summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/sunplus_gcm394.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/sunplus_gcm394.cpp')
-rw-r--r--src/devices/machine/sunplus_gcm394.cpp206
1 files changed, 171 insertions, 35 deletions
diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp
index ed0522de90d..34fa38066f8 100644
--- a/src/devices/machine/sunplus_gcm394.cpp
+++ b/src/devices/machine/sunplus_gcm394.cpp
@@ -729,25 +729,12 @@ READ16_MEMBER(sunplus_gcm394_base_device::internalrom_lower32_r)
}
}
-READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r)
-{
- return machine().rand();
-}
-
-//[:maincpu] ':maincpu' (001490):sunplus_gcm394_base_device::unk_r @ 0x785f
-READ16_MEMBER(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)
-{
- return 0x0000;
-}
-
-
-
// GPR27P512A = C2 76
// HY27UF081G2A = AD F1 80 1D
// H27U518S2C = AD 76
-READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r)
+READ16_MEMBER(generalplus_gpac800_device::nand_7854_r)
{
// TODO: use actual NAND / Smart Media devices once this is better understood.
// The games have extensive checks on startup to determine the flash types, but then it appears that
@@ -762,11 +749,11 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r)
// real TSM code starts at 4c000
- //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context());
+ //logerror("%s:sunplus_gcm394_base_device::nand_7854_r\n", machine().describe_context());
if (m_nandcommand == 0x90) // read ident
{
- logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr);
+ logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ IDENT byte %d\n", machine().describe_context(), m_curblockaddr);
uint8_t data = 0x00;
@@ -802,9 +789,9 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r)
}
else if (m_nandcommand == 0x00)
{
- //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr);
+ //logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr);
- uint32_t nandaddress = (m_flash_addr_high << 16) | m_flash_addr_low;
+ uint32_t nandaddress = (m_nand_addr_high << 16) | m_nand_addr_low;
uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr);
m_curblockaddr++;
@@ -813,13 +800,13 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r)
}
else if (m_nandcommand == 0x70) // read status
{
- logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr);
+ logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ STATUS byte %d\n", machine().describe_context(), m_curblockaddr);
return 0xffff;
}
else
{
- logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr);
+ logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ UNKNOWN byte %d\n", machine().describe_context(), m_curblockaddr);
return 0xffff;
}
@@ -834,25 +821,159 @@ WRITE16_MEMBER(generalplus_gpac800_device::nand_command_w)
m_nandcommand = data;
}
-WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_low_w)
+WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_low_w)
{
- //logerror("%s:sunplus_gcm394_base_device::flash_addr_low_w %04x\n", machine().describe_context(), data);
- m_flash_addr_low = data;
+ //logerror("%s:sunplus_gcm394_base_device::nand_addr_low_w %04x\n", machine().describe_context(), data);
+ m_nand_addr_low = data;
m_curblockaddr = 0;
}
-WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w)
+WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_high_w)
{
- //logerror("%s:sunplus_gcm394_base_device::flash_addr_high_w %04x\n", machine().describe_context(), data);
- m_flash_addr_high = data;
+ //logerror("%s:sunplus_gcm394_base_device::nand_addr_high_w %04x\n", machine().describe_context(), data);
+ m_nand_addr_high = data;
- uint32_t address = (m_flash_addr_high << 16) | m_flash_addr_low;
+ uint32_t address = (m_nand_addr_high << 16) | m_nand_addr_low;
logerror("%s: flash address is now %08x\n", machine().describe_context(), address);
m_curblockaddr = 0;
}
+WRITE16_MEMBER(generalplus_gpac800_device::nand_dma_ctrl_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_dma_ctrl_w(?) %04x\n", machine().describe_context(), data);
+ m_nand_dma_ctrl = data;
+}
+
+READ16_MEMBER(generalplus_gpac800_device::nand_7850_r)
+{
+ // 0x8000 = ready
+ return m_nand_7850 | 0x8000;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_7850_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_7850_w %04x\n", machine().describe_context(), data);
+ m_nand_7850 = data;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_7856_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_7856_w %04x\n", machine().describe_context(), data);
+ m_nand_7856 = data;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_7857_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_7857_w %04x\n", machine().describe_context(), data);
+ m_nand_7857 = data;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_785b_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_785b_w %04x\n", machine().describe_context(), data);
+ m_nand_785b = data;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_785c_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_785c_w %04x\n", machine().describe_context(), data);
+ m_nand_785c = data;
+}
+
+WRITE16_MEMBER(generalplus_gpac800_device::nand_785d_w)
+{
+ logerror("%s:sunplus_gcm394_base_device::nand_785d_w %04x\n", machine().describe_context(), data);
+ m_nand_785d = data;
+}
+
+// [:maincpu] ':maincpu' (00146D) jak_tsm
+READ16_MEMBER(generalplus_gpac800_device::nand_785e_r)
+{
+ return 0x0000;
+}
+
+//[:maincpu] ':maincpu' (001490) jak_tsm
+READ16_MEMBER(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)
+{
+ return 0x0000;
+}
+
+/*
+UNMAPPED reads writes
+
+jak_tsm uses these (all iniitalized near start)
+unclear if these are specific to the GPAC800 type, or present in the older types
+
+[:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
+[:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000)
+[:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
+[:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
+[:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57)
+[:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
+[:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
+[:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011)
+[:maincpu] ':maincpu' (00045B):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x0000)
+[:maincpu] ':maincpu' (00045D):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x0000)
+[:maincpu] ':maincpu' (00045F):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x0000)
+[:maincpu] ':maincpu' (000461):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x0000)
+
+jak_car2 uses these
+
+[:maincpu] ':maincpu' (004056):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
+[:maincpu] ':maincpu' (004059):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
+[:maincpu] ':maincpu' (00405C):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0a57)
+[:maincpu] ':maincpu' (00405F):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
+[:maincpu] ':maincpu' (004062):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
+[:maincpu] ':maincpu' (004065):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x3011)
+[:maincpu] ':maincpu' (004069):sunplus_gcm394_base_device::unk_r @ 0x7880
+[:maincpu] ':maincpu' (00406F):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x1249)
+[:maincpu] ':maincpu' (004071):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x1249)
+[:maincpu] ':maincpu' (004073):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x1249)
+[:maincpu] ':maincpu' (004075):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x1249)
+[:maincpu] ':maincpu' (004088):sunplus_gcm394_base_device::unk_w @ 0x7841 (data 0x000f)
+[:maincpu] ':maincpu' (00408F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
+[:maincpu] ':maincpu' (004092):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0002)
+
+[:maincpu] ':maincpu' (03000A):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x36db)
+[:maincpu] ':maincpu' (03000C):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x36db)
+[:maincpu] ':maincpu' (03000E):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x36db)
+[:maincpu] ':maincpu' (030010):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x36db)
+[:maincpu] ':maincpu' (030013):sunplus_gcm394_base_device::unk_w @ 0x787f (data 0x0010)
+[:maincpu] ':maincpu' (03001D):sunplus_gcm394_base_device::unk_w @ 0x7804 (data 0x1c7f)
+[:maincpu] ':maincpu' (030023):sunplus_gcm394_base_device::unk_w @ 0x7805 (data 0xcdf0)
+[:maincpu] ':maincpu' (03E645):sunplus_gcm394_base_device::unk_w @ 0x7861 (data 0x1f66)
+[:maincpu] ':maincpu' (03E64C):sunplus_gcm394_base_device::unk_w @ 0x786b (data 0x0000)
+[:maincpu] ':maincpu' (03E64F):sunplus_gcm394_base_device::unk_w @ 0x7869 (data 0x0000)
+[:maincpu] ':maincpu' (03E652):sunplus_gcm394_base_device::unk_w @ 0x786a (data 0x0000)
+[:maincpu] ':maincpu' (03E65B):sunplus_gcm394_base_device::unk_w @ 0x7966 (data 0x0001)
+[:maincpu] ':maincpu' (03CBD0):sunplus_gcm394_base_device::unk_w @ 0x7871 (data 0x0000)
+
+-- this one seems like a common alt type of DMA, used in both hw types as it polls 707c status before doing it
+[:maincpu] ':maincpu' (03B4C7):sunplus_gcm394_base_device::unk_w @ 0x707c (data 0x0001)
+-- also video / alt dma?
+[:maincpu] ':maincpu' (068C15):sunplus_gcm394_base_device::unk_r @ 0x707e
+
+beambox sets things up with different values (ultimately stalls on some check, maybe seeprom?)
+
+[:maincpu] ':maincpu' (00043F):sunplus_gcm394_base_device::unk_w @ 0x780a (data 0x0000)
+[:maincpu] ':maincpu' (000442):sunplus_gcm394_base_device::unk_w @ 0x7808 (data 0x0000)
+[:maincpu] ':maincpu' (000445):sunplus_gcm394_base_device::unk_w @ 0x782f (data 0x0002)
+[:maincpu] ':maincpu' (000449):sunplus_gcm394_base_device::unk_w @ 0x783d (data 0x05d9)
+[:maincpu] ':maincpu' (00044D):sunplus_gcm394_base_device::unk_w @ 0x783c (data 0x0f58)
+[:maincpu] ':maincpu' (000451):sunplus_gcm394_base_device::unk_w @ 0x783b (data 0x2400)
+[:maincpu] ':maincpu' (000454):sunplus_gcm394_base_device::unk_w @ 0x783e (data 0x0002)
+[:maincpu] ':maincpu' (000458):sunplus_gcm394_base_device::unk_w @ 0x783a (data 0x4011)
+[:maincpu] ':maincpu' (00045C):sunplus_gcm394_base_device::unk_w @ 0x7874 (data 0x2492) -- note pair of 4, but different values to above games
+[:maincpu] ':maincpu' (00045E):sunplus_gcm394_base_device::unk_w @ 0x787c (data 0x2492)
+[:maincpu] ':maincpu' (000460):sunplus_gcm394_base_device::unk_w @ 0x7888 (data 0x2492)
+[:maincpu] ':maincpu' (000462):sunplus_gcm394_base_device::unk_w @ 0x787e (data 0x2492)
+
+vbaby code is very differet, attempts to load NAND block manually, not with DMA
+
+*/
+
// all tilemap registers etc. appear to be in the same place as the above system, including the 'extra' ones not on the earlier models
// so it's likely this is built on top of that just with NAND support
@@ -861,13 +982,20 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map)
sunplus_gcm394_base_device::base_internal_map(map);
// 785x = NAND device
- map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // NAND Control Reg
+ map(0x007850, 0x007850).rw(FUNC(generalplus_gpac800_device::nand_7850_r), FUNC(generalplus_gpac800_device::nand_7850_w)); // NAND Control Reg
map(0x007851, 0x007851).w(FUNC(generalplus_gpac800_device::nand_command_w)); // NAND Command Reg
- map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::flash_addr_low_w)); // NAND Low Address Reg
- map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::flash_addr_high_w)); // NAND High Address Reg
- map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // NAND Data Reg
-// map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control
-
+ map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::nand_addr_low_w)); // NAND Low Address Reg
+ map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::nand_addr_high_w)); // NAND High Address Reg
+ map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::nand_7854_r)); // NAND Data Reg
+ map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control
+ map(0x007856, 0x007856).w(FUNC(generalplus_gpac800_device::nand_7856_w)); // usually 0x0021?
+ map(0x007857, 0x007857).w(FUNC(generalplus_gpac800_device::nand_7857_w));
+
+ // most of these are likely ECC stuff for testing the ROM?
+ map(0x00785b, 0x00785b).w(FUNC(generalplus_gpac800_device::nand_785b_w));
+ map(0x00785c, 0x00785c).w(FUNC(generalplus_gpac800_device::nand_785c_w));
+ map(0x00785d, 0x00785d).w(FUNC(generalplus_gpac800_device::nand_785d_w));
+ map(0x00785e, 0x00785e).r(FUNC(generalplus_gpac800_device::nand_785e_r)); // also ECC status related?
map(0x00785f, 0x00785f).r(FUNC(generalplus_gpac800_device::nand_ecc_low_byte_error_flag_1_r)); // ECC Low Byte Error Flag 1 (maybe)
// 128kwords internal ROM
@@ -881,6 +1009,7 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map)
map(0x200000, 0x3fffff).rw(FUNC(generalplus_gpac800_device::cs_bank_space_r), FUNC(generalplus_gpac800_device::cs_bank_space_w));
}
+
void sunplus_gcm394_base_device::device_start()
{
unsp_20_device::device_start();
@@ -987,8 +1116,15 @@ void generalplus_gpac800_device::device_reset()
{
sunplus_gcm394_base_device::device_reset();
- m_flash_addr_low = 0x0000;
- m_flash_addr_high = 0x0000;
+ m_nand_addr_low = 0x0000;
+ m_nand_addr_high = 0x0000;
+ m_nand_dma_ctrl = 0x0000;
+ m_nand_7850 = 0x0000;
+ m_nand_785d = 0x0000;
+ m_nand_785c = 0x0000;
+ m_nand_785b = 0x0000;
+ m_nand_7856 = 0x0000;
+ m_nand_7857 = 0x0000;
}
IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb)