diff options
author | David Haywood <28625134+DavidHaywood@users.noreply.github.com> | 2020-02-04 17:57:04 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-04 12:57:04 -0500 |
commit | c689e4230206e3e8e0951b62cc30d7233da68804 (patch) | |
tree | 0add03f6254e7a29ae346b810584a98026ca6482 /src/devices/machine | |
parent | 21004f0213246e75f092c5da0b5e4d6f4721180c (diff) |
Plug and Play work (#6254)
* new WORKING machines
----
Sports Trivia Professional Edition (Senario, Plug and Play) [Sean Riddle, David Haywood]
My Sports Challenge Plus / Wireless Sports Plus [Sean Riddle, David Haywood]
new NOT WORKING
---
Megapad 31-in-1 [Sean Riddle, GameHistory.org]
the 31-in-1 is playable, except for one game, need to look into that.
* (nw)
* new NOT WORKING Software List entry
-----
buzztime_cart.xml : Series 1 - Sports Trivia [Sean Riddle, David Haywood]
* new WORKING software list entry
jakks_gamekey_nm.xml : Pac-Man & Bosconian (01 APR 2005 A SKU G) [Sean Riddle, Ryan Holtz, David Haywood]
(that's all the known gamekeys covered now)
* sunplus_gcm394 changes from Tahg
(I'll tidy these up shortly to fit MAME standard better)
* refactor (nw)
* refactor (nw)
* (nw)
* (nw)
* some decryption refactor (nw)
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/sunplus_gcm394.cpp | 216 | ||||
-rw-r--r-- | src/devices/machine/sunplus_gcm394.h | 17 |
2 files changed, 143 insertions, 90 deletions
diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index b67a20550a4..29f83441d36 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -57,10 +57,17 @@ uint16_t sunplus_gcm394_base_device::read_dma_params(int channel, int offset) return retdata; } -void sunplus_gcm394_base_device::write_dma_params(int channel, int offset, uint16_t data) +void sunplus_gcm394_base_device::write_dma_params(int channel, int offset, uint16_t data, address_space& space) { - m_dma_params[offset][channel] = data; LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::write_dma_params (channel %01x) %01x %04x\n", machine().describe_context(), channel, offset, data); + + m_dma_params[offset][channel] = data; + + if (offset == 0 && (data & 1)) + { + trigger_systemm_dma(space, channel); + } + } @@ -72,7 +79,7 @@ READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel0_r) WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel0_w) { - write_dma_params(0, offset, data); + write_dma_params(0, offset, data, space); } READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel1_r) @@ -82,7 +89,7 @@ READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel1_r) WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel1_w) { - write_dma_params(1, offset, data); + write_dma_params(1, offset, data, space); } READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel2_r) @@ -92,7 +99,17 @@ READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel2_r) WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel2_w) { - write_dma_params(2, offset, data); + write_dma_params(2, offset, data, space); +} + +READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel3_r) +{ + return read_dma_params(3, offset); +} + +WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel3_w) +{ + write_dma_params(3, offset, data, space); } @@ -105,95 +122,91 @@ READ16_MEMBER(sunplus_gcm394_base_device::system_dma_status_r) // bit 0 = channel 0 ready // bit 1 = channel 1 ready - return 0x0003; + return 0x00FF; } -void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int channel, uint16_t data) +void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int channel) { uint16_t mode = m_dma_params[0][channel]; uint32_t source = m_dma_params[1][channel] | (m_dma_params[4][channel] << 16); uint32_t dest = m_dma_params[2][channel] | (m_dma_params[5][channel] << 16) ; uint32_t length = m_dma_params[3][channel] | (m_dma_params[6][channel] << 16); + int sourcedelta = 0; + int destdelta = 0; + + if ((mode & 0xa0) == 0x00) + sourcedelta = 1; + else if ((mode & 0xa0) == 0x20) + sourcedelta = -1; - LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) (trigger %04x) with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words) while csbank is %02x\n", machine().describe_context().c_str(), data, mode, source, dest, length, m_membankswitch_7810 ); + if ((mode & 0x50) == 0x00) + destdelta = 1; + else if ((mode & 0x50) == 0x10) + destdelta = -1; - if ((source&0x0fffffff) >= 0x20000) - LOGMASKED(LOG_GCM394_SYSDMA, " likely transfer from ROM %08x - %08x\n", (source - 0x20000) * 2, (source - 0x20000) * 2 + (length * 2)- 1); + LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words) while csbank is %02x\n", machine().describe_context().c_str(), mode, source, dest, length, m_membankswitch_7810 ); // wrlshunt transfers ROM to RAM, all RAM write addresses have 0x800000 in the destination set - // mode 0x0089 == no source inc, used for memory clear operations? (source usually points at stack value) - // mode 0x0009 == regular copy? (smartfp does 2 copies like this after the initial clears, source definitely points at a correctly sized data structure) - // what does having bit 0x4000 on mode set mean? (first transfer on wrlshunt - maybe an IRQ disable?) + address_space& mem = this->space(AS_PROGRAM); + source &= 0x0fffffff; - if (mode == 0x1089) // 8-bit no increment mode, counter is in bytes? used for DMA from NAND (first writes 0x1088 then does an OR with 0x0001) + for (int i = 0; i < length; i++) { - address_space& mem = this->space(AS_PROGRAM); - source &= 0x0fffffff; - - for (int i = 0; i < length/2; i++) + uint16_t val; + if (mode & 0x1000) { - uint16_t val1 = read_space(source); - uint16_t val2 = read_space(source); - - //logerror("val1 %04x val2 %04x\n", val1, val2); - - uint16_t val = (val2 << 8) | val1; + val = (read_space(source) & 0xFF) | (read_space(source) << 8); + i++; + } + else + { + val = read_space(source); + } + source += sourcedelta; + + if (mode & 0x2000) + { + write_space(dest, val & 0xFF); + write_space(dest, val >> 8); + } + else + { write_space(dest, val); - dest += 1; } - // HACKS to get into service mode for debugging + dest += destdelta; + } - // note, these patch the code copied to SRAM so the 'PROGRAM ROM' check fails (it passes otherwise) - if (mem.read_word(0x3f368) == 0x4840) - mem.write_word(0x3f368, 0x4841); // cars 2 IRQ? wait hack + // HACKS to get into service mode for debugging - //if (mem.read_word(0x4368c) == 0x4846) - // mem.write_word(0x4368c, 0x4840); // cars 2 force service mode + // note, these patch the code copied to SRAM so the 'PROGRAM ROM' check fails (it passes otherwise) - if (mem.read_word(0x4d8d4) == 0x4840) - mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack + //if (mem.read_word(0x4368c) == 0x4846) + // mem.write_word(0x4368c, 0x4840); // cars 2 force service mode - //if (mem.read_word(0x34410) == 0x4846) - // mem.write_word(0x34410, 0x4840); // golden tee force service mode + //if (mem.read_word(0x34410) == 0x4846) + // mem.write_word(0x34410, 0x4840); // golden tee force service mode - } - else if ((mode == 0x0089) || (mode == 0x0009) || (mode == 0x4009)) - { - for (int i = 0; i < length; i++) - { + // what is it waiting for when we need these? (needed on some service mode screens) + if (mem.read_word(0x3f368) == 0x4840) + mem.write_word(0x3f368, 0x4841); // cars 2 IRQ? wait hack - uint16_t val = read_space(source); + if (mem.read_word(0x4d8d4) == 0x4840) + mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack - write_space(dest , val); - dest += 1; - - if ((mode&0x3fff) == 0x0009) - source += 1; - } - } - else - { - LOGMASKED(LOG_GCM394_SYSDMA, "unhandled!\n"); - } + // clear params after operation m_dma_params[0][channel] = m_dma_params[1][channel] = m_dma_params[2][channel] = m_dma_params[3][channel] = m_dma_params[4][channel] = m_dma_params[5][channel] = m_dma_params[6][channel] = 0x0000; //machine().debug_break(); } -WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) +WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_7abf_unk_w) { - // trigger is value based, not bit based, how many channels are there? + // if this isn't trigger, is it enable? (which could maybe used as similar if DMA only starts to happen if unmasked?) - if (data == 1) trigger_systemm_dma(space, 0, data); - else if (data == 2) trigger_systemm_dma(space, 1, data); - else if (data == 3) trigger_systemm_dma(space, 2, data); - else - { - fatalerror("unknown DMA trigger type\n"); - } + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_dma_7abf_unk_w %04x\n", machine().describe_context(), data); } READ16_MEMBER(sunplus_gcm394_base_device::system_dma_memtype_r) @@ -295,8 +308,17 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::membankswitch_7810_w) } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7816_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7816_w %04x\n", machine().describe_context(), data); m_7816 = data; } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7817_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7817_w %04x\n", machine().describe_context(), data); m_7817 = data; } +WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7816_w) +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7816_w %04x\n", machine().describe_context(), data); + m_7816 = data; +} + +WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7817_w) +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7817_w %04x\n", machine().describe_context(), data); + m_7817 = data; +} WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w) { @@ -799,13 +821,13 @@ void sunplus_gcm394_base_device::base_internal_map(address_map &map) map(0x007a3a, 0x007a3a).r(FUNC(sunplus_gcm394_base_device::system_7a3a_r)); // ? - map(0x007a80, 0x007a86).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_w)); - map(0x007a88, 0x007a8e).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_w)); // jak_tsm writes here - map(0x007a90, 0x007a96).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_w)); // bkrankp writes here (is this on all types or just SPI?) - //map(0x007a98, 0x007a9e).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_w)); // not seen, but probably + map(0x007a80, 0x007a87).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel0_w)); + map(0x007a88, 0x007a8f).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel1_w)); // jak_tsm writes here + map(0x007a90, 0x007a97).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel2_w)); // bkrankp writes here (is this on all types or just SPI?) + map(0x007a98, 0x007a9f).rw(FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_r), FUNC(sunplus_gcm394_base_device::system_dma_params_channel3_w)); // not seen, but probably map(0x007abe, 0x007abe).rw(FUNC(sunplus_gcm394_base_device::system_dma_memtype_r), FUNC(sunplus_gcm394_base_device::system_dma_memtype_w)); // 7abe - written with DMA stuff (source type for each channel so that device handles timings properly?) - map(0x007abf, 0x007abf).rw(FUNC(sunplus_gcm394_base_device::system_dma_status_r), FUNC(sunplus_gcm394_base_device::system_dma_trigger_w)); + map(0x007abf, 0x007abf).rw(FUNC(sunplus_gcm394_base_device::system_dma_status_r), FUNC(sunplus_gcm394_base_device::system_dma_7abf_unk_w)); // ###################################################################################################################################################################################### // 7bxx-7fxx = audio @@ -851,9 +873,7 @@ READ16_MEMBER(sunplus_gcm394_base_device::cs_bank_space_r) return 0; } - //return m_cs_space->read_word(offset + (0x200000 - m_csbase)); return m_cs_space->read_word(realoffset); - } WRITE16_MEMBER(sunplus_gcm394_base_device::cs_bank_space_w) @@ -933,7 +953,7 @@ READ16_MEMBER(generalplus_gpac800_device::nand_7854_r) } else { - if (m_curblockaddr == 2) + if (m_curblockaddr == 0) data = 0xad; else if (m_curblockaddr == 1) data = 0xf1; @@ -947,12 +967,11 @@ READ16_MEMBER(generalplus_gpac800_device::nand_7854_r) return data; } - else if (m_nandcommand == 0x00) + else if (m_nandcommand == 0x00 || m_nandcommand == 0x01 || m_nandcommand == 0x50) { //logerror("%s:sunplus_gcm394_base_device::nand_7854_r READ DATA byte %d\n", machine().describe_context(), m_curblockaddr); - uint32_t nandaddress = (m_nand_addr_high << 16) | m_nand_addr_low; - uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr); + uint8_t data = m_nand_read_cb(m_effectiveaddress + m_curblockaddr); m_curblockaddr++; @@ -983,19 +1002,44 @@ WRITE16_MEMBER(generalplus_gpac800_device::nand_command_w) WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_low_w) { - //logerror("%s:sunplus_gcm394_base_device::nand_addr_low_w %04x\n", machine().describe_context(), 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; } +void generalplus_gpac800_device::recalculate_calculate_effective_nand_address() +{ + uint8_t type = m_nand_7856 & 0xf; + uint8_t shift = 0; + uint32_t page_offset = 0; + + if (type == 7) + shift = 4; + else if (type == 11) + shift = 5; + + if (m_nandcommand == 0x01) + page_offset = 256; + else if (m_nandcommand == 0x50) + page_offset = 512; + + uint32_t nandaddress = (m_nand_addr_high << 16) | m_nand_addr_low; + + if (m_nand_7850 & 0x4000) + nandaddress *= 2; + + uint32_t page = type ? nandaddress : /*(m_nand_7850 & 0x4000) ?*/ nandaddress >> 8 /*: nandaddress >> 9*/; + m_effectiveaddress = (page * 528 + page_offset) << shift; + + logerror("%s: Requested address is %08x, translating to %08x\n", machine().describe_context(), nandaddress, m_effectiveaddress); +} + WRITE16_MEMBER(generalplus_gpac800_device::nand_addr_high_w) { - //logerror("%s:sunplus_gcm394_base_device::nand_addr_high_w %04x\n", machine().describe_context(), 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_nand_addr_high << 16) | m_nand_addr_low; - - logerror("%s: flash address is now %08x\n", machine().describe_context(), address); + recalculate_calculate_effective_nand_address(); m_curblockaddr = 0; } @@ -1006,7 +1050,7 @@ WRITE16_MEMBER(generalplus_gpac800_device::nand_dma_ctrl_w) m_nand_dma_ctrl = data; } -READ16_MEMBER(generalplus_gpac800_device::nand_7850_r) +READ16_MEMBER(generalplus_gpac800_device::nand_7850_status_r) { // 0x8000 = ready return m_nand_7850 | 0x8000; @@ -1018,10 +1062,14 @@ WRITE16_MEMBER(generalplus_gpac800_device::nand_7850_w) m_nand_7850 = data; } -WRITE16_MEMBER(generalplus_gpac800_device::nand_7856_w) +WRITE16_MEMBER(generalplus_gpac800_device::nand_7856_type_w) { - logerror("%s:sunplus_gcm394_base_device::nand_7856_w %04x\n", machine().describe_context(), data); + logerror("%s:sunplus_gcm394_base_device::nand_7856_type_w %04x\n", machine().describe_context(), data); m_nand_7856 = data; + + recalculate_calculate_effective_nand_address(); + + m_curblockaddr = 0; } WRITE16_MEMBER(generalplus_gpac800_device::nand_7857_w) @@ -1142,13 +1190,13 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) sunplus_gcm394_base_device::base_internal_map(map); // 785x = NAND device - map(0x007850, 0x007850).rw(FUNC(generalplus_gpac800_device::nand_7850_r), FUNC(generalplus_gpac800_device::nand_7850_w)); // NAND Control Reg + map(0x007850, 0x007850).rw(FUNC(generalplus_gpac800_device::nand_7850_status_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::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(0x007856, 0x007856).w(FUNC(generalplus_gpac800_device::nand_7856_type_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? diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index ad29b7b1208..79a5a0aa067 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -98,7 +98,7 @@ protected: devcb_write16 m_porta_out; - uint16_t m_dma_params[7][3]; + uint16_t m_dma_params[8][4]; // unk 78xx uint16_t m_7803; @@ -187,9 +187,9 @@ private: DECLARE_READ16_MEMBER(unk_r); DECLARE_WRITE16_MEMBER(unk_w); - void write_dma_params(int channel, int offset, uint16_t data); + void write_dma_params(int channel, int offset, uint16_t data, address_space& space); uint16_t read_dma_params(int channel, int offset); - void trigger_systemm_dma(address_space &space, int channel, uint16_t data); + void trigger_systemm_dma(address_space &space, int channel); DECLARE_READ16_MEMBER(system_dma_params_channel0_r); DECLARE_WRITE16_MEMBER(system_dma_params_channel0_w); @@ -197,8 +197,10 @@ private: DECLARE_WRITE16_MEMBER(system_dma_params_channel1_w); DECLARE_READ16_MEMBER(system_dma_params_channel2_r); DECLARE_WRITE16_MEMBER(system_dma_params_channel2_w); + DECLARE_READ16_MEMBER(system_dma_params_channel3_r); + DECLARE_WRITE16_MEMBER(system_dma_params_channel3_w); DECLARE_READ16_MEMBER(system_dma_status_r); - DECLARE_WRITE16_MEMBER(system_dma_trigger_w); + DECLARE_WRITE16_MEMBER(system_dma_7abf_unk_w); DECLARE_READ16_MEMBER(system_dma_memtype_r); DECLARE_WRITE16_MEMBER(system_dma_memtype_w); @@ -357,7 +359,9 @@ protected: virtual void device_reset() override; private: - DECLARE_READ16_MEMBER(nand_7850_r); + void recalculate_calculate_effective_nand_address(); + + DECLARE_READ16_MEMBER(nand_7850_status_r); DECLARE_READ16_MEMBER(nand_7854_r); DECLARE_WRITE16_MEMBER(nand_dma_ctrl_w); DECLARE_WRITE16_MEMBER(nand_7850_w); @@ -365,7 +369,7 @@ private: DECLARE_WRITE16_MEMBER(nand_addr_low_w); DECLARE_WRITE16_MEMBER(nand_addr_high_w); DECLARE_READ16_MEMBER(nand_ecc_low_byte_error_flag_1_r); - DECLARE_WRITE16_MEMBER(nand_7856_w); + DECLARE_WRITE16_MEMBER(nand_7856_type_w); DECLARE_WRITE16_MEMBER(nand_7857_w); DECLARE_WRITE16_MEMBER(nand_785b_w); DECLARE_WRITE16_MEMBER(nand_785c_w); @@ -386,6 +390,7 @@ private: uint16_t m_nand_7857; int m_curblockaddr; + uint32_t m_effectiveaddress; }; |