diff --git a/src/devices/cpu/unsp/unsp_exxx.cpp b/src/devices/cpu/unsp/unsp_exxx.cpp index d631e096588..202151ed2be 100644 --- a/src/devices/cpu/unsp/unsp_exxx.cpp +++ b/src/devices/cpu/unsp/unsp_exxx.cpp @@ -60,7 +60,7 @@ void unsp_12_device::execute_exxx_group(uint16_t op) return; case 0x03: - fatalerror("UNSP: unknown opcode invb Rd,offset (%04x) at %04x\n", op, UNSP_LPC); + m_core->m_r[rd] ^= (1 << offset); return; } return; diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index ed5ec37ff07..a79e5e1bba4 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -37,28 +37,63 @@ generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mco // **************************************** SYSTEM DMA device ************************************************* +uint16_t sunplus_gcm394_base_device::read_dma_params(int channel, int offset) +{ + uint16_t retdata = m_dma_params[offset][channel]; + LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::read_dma_params (channel %01x) %01x returning %04x\n", machine().describe_context(), channel, offset, retdata); + return retdata; +} + +void sunplus_gcm394_base_device::write_dma_params(int channel, int offset, uint16_t data) +{ + 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); +} + + +READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel0_r) +{ + return read_dma_params(0, offset); +} + + +WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel0_w) +{ + write_dma_params(0, offset, data); +} + +READ16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel1_r) +{ + return read_dma_params(1, offset); +} + +WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_channel1_w) +{ + write_dma_params(1, offset, data); +} + + + READ16_MEMBER(sunplus_gcm394_base_device::system_dma_status_r) { LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::system_dma_status_r (7abf)\n", machine().describe_context()); - return 0x0001; + + // bit 0 = channel 0 ready + // bit 1 = channel 1 ready + + return 0x0003; } -WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_w) +void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int channel, uint16_t data) { - m_dma_params[offset] = data; - LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::sys_dma_params_w %01x %04x\n", machine().describe_context(), offset, data); -} - -WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) -{ - uint16_t mode = m_dma_params[0]; - uint32_t source = m_dma_params[1] | (m_dma_params[4] << 16); - uint32_t dest = m_dma_params[2] | (m_dma_params[5] << 16) ; - uint32_t length = m_dma_params[3] | (m_dma_params[6] << 16); + 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); 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)\n", machine().describe_context(), data, mode, source, dest, length ); - if (source >= 0x20000) + if ((source&0x0fffffff) >= 0x20000) LOGMASKED(LOG_GCM394_SYSDMA, " likely transfer from ROM %08x - %08x\n", (source - 0x20000) * 2, (source - 0x20000) * 2 + (length * 2)- 1); // wrlshunt transfers ROM to RAM, all RAM write addresses have 0x800000 in the destination set @@ -67,7 +102,41 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) // 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?) - if ((mode == 0x0089) || (mode == 0x0009) || (mode == 0x4009)) + 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) + { + address_space& mem = this->space(AS_PROGRAM); + source &= 0x0fffffff; + + for (int i = 0; i < length/2; i++) + { + uint16_t val1 = mem.read_word(source); + uint16_t val2 = mem.read_word(source); + + //printf("val1 %04x val2 %04x\n", val1, val2); + + uint16_t val = (val2 << 8) | val1; + + m_space_write_cb(space, dest, val); + dest += 1; + } + + // HACKS to get into service mode for debugging + + // 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 + + if (mem.read_word(0x4368c) == 0x4846) + mem.write_word(0x4368c, 0x4840); // cars 2 force service mode + + if (mem.read_word(0x4d8d4) == 0x4840) + mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack + + 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++) { @@ -105,10 +174,16 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) LOGMASKED(LOG_GCM394_SYSDMA, "unhandled!\n"); } - m_dma_params[0] = m_dma_params[1] = m_dma_params[2] = m_dma_params[3] = m_dma_params[4] = m_dma_params[5] = m_dma_params[6] = 0x0000; + 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) +{ + if (data & 0x01) trigger_systemm_dma(space, 0, data); + if (data & 0x02) trigger_systemm_dma(space, 1, data); +} + // **************************************** 78xx region with some handling ************************************************* @@ -142,39 +217,60 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7803_w) { LOGMASKED(LOG_GCM39 WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7807_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7807_w %04x\n", machine().describe_context(), data); m_7807 = data; } - -// this gets stored / modified / restored before certain memory accesses (in practical terms it just seems to flip from 0/1) maybe it changes the memory mapping (as 7820 seems to) -READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_r) +WRITE16_MEMBER(sunplus_gcm394_base_device::waitmode_enter_780c_w) { - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_r\n", machine().describe_context()); - return m_7810; + // LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::waitmode_enter_780c_w %04x\n", machine().describe_context(), data); + // must be followed by 6 nops to ensure wait mode is entered } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_w) +// this gets stored / modified / restored before certain memory accesses ( +// used extensively during SDRAM checks in jak_gtg and jak_car2 + +READ16_MEMBER(sunplus_gcm394_base_device::membankswitch_7810_r) { - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_w %04x\n", machine().describe_context(), data); - m_7810 = data; +// LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::membankswitch_7810_r\n", machine().describe_context()); + return m_membankswitch_7810; +} + +WRITE16_MEMBER(sunplus_gcm394_base_device::membankswitch_7810_w) +{ +// if (m_membankswitch_7810 != data) +// LOGMASKED(LOG_GCM394,"%s:sunplus_gcm394_base_device::membankswitch_7810_w %04x\n", machine().describe_context(), data); + + popmessage("bankswitch %04x -> %04x", m_membankswitch_7810, data); + + m_membankswitch_7810 = 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::unkarea_7820_w) +WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w) { - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7820_w (Rom Mapping control?) %04x\n", machine().describe_context(), data); - m_7820 = data; - m_mapping_write_cb(data); -} + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w %04x (782x registers offset %d)\n", machine().describe_context(), data, offset); + m_782x[offset] = data; + + if (offset == 0) + m_mapping_write_cb(data); + + + static const char* const md[] = + { + "(00) ROM / SRAM", + "(01) ROM / SRAM", + "(10) NOR FLASH", + "(11) NAND FLASH", + }; + + uint8_t cs_wait = data & 0x000f; + uint8_t cs_warat = (data & 0x0030)>>4; + uint8_t cs_md = (data & 0x00c0)>>6; + int cs_size = (data & 0xff00)>>8; + + logerror("CS%d set to size: %02x (%08x words) md: %01x %s warat: %01x wait: %01x\n", offset, cs_size, (cs_size+1)*0x10000, cs_md, md[cs_md], cs_warat, cs_wait); -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7821_w) -{ - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7821_w %04x\n", machine().describe_context(), data); m_7821 = data; } -// these seem to be related to the above but don't change after startup. maybe it's how different devices see memory? -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7822_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7822_w %04x\n", machine().describe_context(), data); m_7822 = data; } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7823_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7823_w %04x\n", machine().describe_context(), data); m_7823 = data; } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7824_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7824_w %04x\n", machine().describe_context(), data); m_7824 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7835_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7835_w %04x\n", machine().describe_context(), data); m_7835 = data; } @@ -357,18 +453,18 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) map(0x007016, 0x00701b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_regs_r), FUNC(gcm394_base_video_device::tmap1_regs_w)); // tilebase LSBs - map(0x007020, 0x007020).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_w)); // tilebase, written with other tmap0 regs - map(0x007021, 0x007021).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_w)); // tilebase, written with other tmap1 regs - map(0x007022, 0x007022).w(m_spg_video, FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w)); // sprite tilebase written as 7022, 702d and 7042 group + map(0x007020, 0x007020).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_w)); // tilebase, written with other tmap0 regs + map(0x007021, 0x007021).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_r), FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_w)); // tilebase, written with other tmap1 regs + map(0x007022, 0x007022).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_r), FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w)); // sprite tilebase written as 7022, 702d and 7042 group map(0x007023, 0x007023).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_lsb_w)); // written with other unknown_video_device1 regs (roz layer or line layer?) map(0x007024, 0x007024).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_lsb_w)); // written with other unknown_video_device2 regs (roz layer or line layer?) map(0x00702a, 0x00702a).w(m_spg_video, FUNC(gcm394_base_video_device::video_702a_w)); // blend level control // tilebase MSBs - map(0x00702b, 0x00702b).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_msb_w)); // written with other tmap0 regs - map(0x00702c, 0x00702c).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_msb_w)); // written with other tmap1 regs - map(0x00702d, 0x00702d).w(m_spg_video, FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_w)); // sprites, written as 7022, 702d and 7042 group + map(0x00702b, 0x00702b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap0_tilebase_msb_w)); // written with other tmap0 regs + map(0x00702c, 0x00702c).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_msb_r), FUNC(gcm394_base_video_device::tmap1_tilebase_msb_w)); // written with other tmap1 regs + map(0x00702d, 0x00702d).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_r), FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_w)); // sprites, written as 7022, 702d and 7042 group map(0x00702e, 0x00702e).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_msb_w)); // written with other unknown_video_device1 regs (roz layer or line layer?) map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_msb_w)); // written with other unknown_video_device2 regs (roz layer or line layer?) @@ -418,80 +514,131 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) map(0x007400, 0x0077ff).rw(m_spg_video, FUNC(gcm394_base_video_device::spriteram_r), FUNC(gcm394_base_video_device::spriteram_w)); // ###################################################################################################################################################################################### - // 78xx region = io + other? + // 78xx region = system regs? // ###################################################################################################################################################################################### map(0x007803, 0x007803).rw(FUNC(sunplus_gcm394_base_device::unkarea_7803_r), FUNC(sunplus_gcm394_base_device::unkarea_7803_w)); map(0x007807, 0x007807).w(FUNC(sunplus_gcm394_base_device::unkarea_7807_w)); + // 7808 + + // 780a + + map(0x00780c, 0x00780c).w(FUNC(sunplus_gcm394_base_device::waitmode_enter_780c_w)); map(0x00780f, 0x00780f).r(FUNC(sunplus_gcm394_base_device::unkarea_780f_status_r)); - map(0x007810, 0x007810).rw(FUNC(sunplus_gcm394_base_device::unkarea_7810_r), FUNC(sunplus_gcm394_base_device::unkarea_7810_w)); + map(0x007810, 0x007810).rw(FUNC(sunplus_gcm394_base_device::membankswitch_7810_r), FUNC(sunplus_gcm394_base_device::membankswitch_7810_w)); // 7810 Bank Switch Control Register (P_BankSwitch_Ctrl) (maybe) map(0x007819, 0x007819).rw(FUNC(sunplus_gcm394_base_device::unkarea_7819_r), FUNC(sunplus_gcm394_base_device::unkarea_7819_w)); map(0x007816, 0x007816).w(FUNC(sunplus_gcm394_base_device::unkarea_7816_w)); map(0x007817, 0x007817).w(FUNC(sunplus_gcm394_base_device::unkarea_7817_w)); - // wrlshunt | smartfp - map(0x007820, 0x007820).w(FUNC(sunplus_gcm394_base_device::unkarea_7820_w)); // 7f8a (7f8a before DMA from ROM to RAM, 008a after DMA from ROM to RAM) | 3f04 - map(0x007821, 0x007821).w(FUNC(sunplus_gcm394_base_device::unkarea_7821_w)); // 7f47 | 0044 - map(0x007822, 0x007822).w(FUNC(sunplus_gcm394_base_device::unkarea_7822_w)); // 0047 | 1f44 - map(0x007823, 0x007823).w(FUNC(sunplus_gcm394_base_device::unkarea_7823_w)); // 0047 | 0044 - map(0x007824, 0x007824).w(FUNC(sunplus_gcm394_base_device::unkarea_7824_w)); // 0047 | 0044 + // ###################################################################################################################################################################################### + // 782x region = memory config / control + // ###################################################################################################################################################################################### + // wrlshunt | smartfp + map(0x007820, 0x007824).w(FUNC(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_w)); // 7f8a (7f8a before DMA from ROM to RAM, 008a after DMA from ROM to RAM) | 3f04 7820 Chip Select (CS0) Memory Device Control (P_MC50_Ctrl) + // 7f47 | 0044 7821 Chip Select (CS1) Memory Device Control (P_MC51_Ctrl) + // 0047 | 1f44 7822 Chip Select (CS2) Memory Device Control (P_MC52_Ctrl) + // 0047 | 0044 7823 Chip Select (CS3) Memory Device Control (P_MC53_Ctrl) + // 0047 | 0044 7824 Chip Select (CS4) Memory Device Control (P_MC54_Ctrl) map(0x00782d, 0x00782d).rw(FUNC(sunplus_gcm394_base_device::unkarea_782d_r), FUNC(sunplus_gcm394_base_device::unkarea_782d_w)); // on startup + // 782f map(0x007835, 0x007835).w(FUNC(sunplus_gcm394_base_device::unkarea_7835_w)); - map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_r), FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_w)); + // 783a + // 783b + // 783c + // 783d + // 783e - map(0x007861, 0x007861).r(FUNC(sunplus_gcm394_base_device::unkarea_7861_r)); - map(0x007862, 0x007862).rw(FUNC(sunplus_gcm394_base_device::unkarea_7862_r), FUNC(sunplus_gcm394_base_device::unkarea_7862_w)); - map(0x007863, 0x007863).rw(FUNC(sunplus_gcm394_base_device::unkarea_7863_r), FUNC(sunplus_gcm394_base_device::unkarea_7863_w)); + // 7841 - map(0x007868, 0x007868).r(FUNC(sunplus_gcm394_base_device::unkarea_7868_r)); // on startup + // ###################################################################################################################################################################################### + // 786x - 787x - IO related? + // ###################################################################################################################################################################################### - map(0x007870, 0x007870).rw(FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_r) ,FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_w)); + map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_r), FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_w)); // 7860 I/O PortA Data Register + map(0x007861, 0x007861).r(FUNC(sunplus_gcm394_base_device::unkarea_7861_r)); // 7861 I/O PortA Buffer Register + map(0x007862, 0x007862).rw(FUNC(sunplus_gcm394_base_device::unkarea_7862_r), FUNC(sunplus_gcm394_base_device::unkarea_7862_w)); // 7862 I/O PortA Direction Register + map(0x007863, 0x007863).rw(FUNC(sunplus_gcm394_base_device::unkarea_7863_r), FUNC(sunplus_gcm394_base_device::unkarea_7863_w)); // 7863 I/O PortA Attribute Register - map(0x007871, 0x007871).r(FUNC(sunplus_gcm394_base_device::unkarea_7871_r)); - map(0x007872, 0x007872).rw(FUNC(sunplus_gcm394_base_device::unkarea_7872_r), FUNC(sunplus_gcm394_base_device::unkarea_7872_w)); - map(0x007873, 0x007873).rw(FUNC(sunplus_gcm394_base_device::unkarea_7873_r), FUNC(sunplus_gcm394_base_device::unkarea_7873_w)); + map(0x007868, 0x007868).r(FUNC(sunplus_gcm394_base_device::unkarea_7868_r)); // on startup // 7868 I/O PortB Data Register + // 7869 I/O PortB Buffer Register + // 786a I/O PortB Direction Register + // 786b I/O PortB Attribute Register + // 786a I/O PortB Direction Register + // 786c I/O PortB Latch / Wakeup + + map(0x007870, 0x007870).rw(FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_r) ,FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_w)); // 7870 I/O PortC Data Register + map(0x007871, 0x007871).r(FUNC(sunplus_gcm394_base_device::unkarea_7871_r)); // 7871 I/O PortC Buffer Register + map(0x007872, 0x007872).rw(FUNC(sunplus_gcm394_base_device::unkarea_7872_r), FUNC(sunplus_gcm394_base_device::unkarea_7872_w)); // 7872 I/O PortC Direction Register + map(0x007873, 0x007873).rw(FUNC(sunplus_gcm394_base_device::unkarea_7873_r), FUNC(sunplus_gcm394_base_device::unkarea_7873_w)); // 7873 I/O PortC Attribute Register + // 7874 (data 0x1249) + // 787c (data 0x1249) + // 787e (data 0x1249) + + // 7878 I/O PortD Data Register + // 7879 I/O PortD Buffer Register + // 787a I/O PortD Direction Register + // 787b I/O PortD Attribute Register + + // ###################################################################################################################################################################################### + // 788x - more IO? + // ###################################################################################################################################################################################### + + // 7880 map(0x007882, 0x007882).rw(FUNC(sunplus_gcm394_base_device::unkarea_7882_r), FUNC(sunplus_gcm394_base_device::unkarea_7882_w)); map(0x007883, 0x007883).rw(FUNC(sunplus_gcm394_base_device::unkarea_7883_r), FUNC(sunplus_gcm394_base_device::unkarea_7883_w)); - map(0x0078a0, 0x0078a0).rw(FUNC(sunplus_gcm394_base_device::unkarea_78a0_r), FUNC(sunplus_gcm394_base_device::unkarea_78a0_w)); + // 0x7888 (data 0x1249) + // ###################################################################################################################################################################################### + // 78ax - interrupt controller? + // ###################################################################################################################################################################################### + + map(0x0078a0, 0x0078a0).rw(FUNC(sunplus_gcm394_base_device::unkarea_78a0_r), FUNC(sunplus_gcm394_base_device::unkarea_78a0_w)); map(0x0078a1, 0x0078a1).r(FUNC(sunplus_gcm394_base_device::unkarea_78a1_r)); map(0x0078a4, 0x0078a4).w(FUNC(sunplus_gcm394_base_device::unkarea_78a4_w)); map(0x0078a5, 0x0078a5).w(FUNC(sunplus_gcm394_base_device::unkarea_78a5_w)); map(0x0078a6, 0x0078a6).w(FUNC(sunplus_gcm394_base_device::unkarea_78a6_w)); - map(0x0078a8, 0x0078a8).w(FUNC(sunplus_gcm394_base_device::unkarea_78a8_w)); + map(0x0078a8, 0x0078a8).w(FUNC(sunplus_gcm394_base_device::unkarea_78a8_w)); - map(0x0078b0, 0x0078b0).w(FUNC(sunplus_gcm394_base_device::unkarea_78b0_w)); - map(0x0078b1, 0x0078b1).w(FUNC(sunplus_gcm394_base_device::unkarea_78b1_w)); + // ###################################################################################################################################################################################### + // 78bx - timer control? + // ###################################################################################################################################################################################### - map(0x0078b2, 0x0078b2).r(FUNC(sunplus_gcm394_base_device::unkarea_78b2_r)); - map(0x0078b2, 0x0078b2).w(FUNC(sunplus_gcm394_base_device::unkarea_78b2_w)); + map(0x0078b0, 0x0078b0).w(FUNC(sunplus_gcm394_base_device::unkarea_78b0_w)); // 78b0 TimeBase A Control Register (P_TimeBaseA_Ctrl) + map(0x0078b1, 0x0078b1).w(FUNC(sunplus_gcm394_base_device::unkarea_78b1_w)); // 78b1 TimeBase B Control Register (P_TimeBaseB_Ctrl) + map(0x0078b2, 0x0078b2).rw(FUNC(sunplus_gcm394_base_device::unkarea_78b2_r), FUNC(sunplus_gcm394_base_device::unkarea_78b2_w)); // 78b2 TimeBase C Control Register (P_TimeBaseC_Ctrl) - map(0x0078b8, 0x0078b8).w(FUNC(sunplus_gcm394_base_device::unkarea_78b8_w)); + map(0x0078b8, 0x0078b8).w(FUNC(sunplus_gcm394_base_device::unkarea_78b8_w)); // 78b8 TimeBase Counter Reset Register (P_TimeBase_Reset) + + // ###################################################################################################################################################################################### + // 78fx - unknown + // ###################################################################################################################################################################################### map(0x0078f0, 0x0078f0).w(FUNC(sunplus_gcm394_base_device::unkarea_78f0_w)); map(0x0078fb, 0x0078fb).r(FUNC(sunplus_gcm394_base_device::unkarea_78fb_status_r)); // ###################################################################################################################################################################################### - // 79xx region = timers? + // 79xx - misc? // ###################################################################################################################################################################################### + // possible rtc? map(0x007934, 0x007934).rw(FUNC(sunplus_gcm394_base_device::unkarea_7934_r), FUNC(sunplus_gcm394_base_device::unkarea_7934_w)); map(0x007935, 0x007935).rw(FUNC(sunplus_gcm394_base_device::unkarea_7935_r), FUNC(sunplus_gcm394_base_device::unkarea_7935_w)); map(0x007936, 0x007936).rw(FUNC(sunplus_gcm394_base_device::unkarea_7936_r), FUNC(sunplus_gcm394_base_device::unkarea_7936_w)); + // possible adc? map(0x007960, 0x007960).w(FUNC(sunplus_gcm394_base_device::unkarea_7960_w)); map(0x007961, 0x007961).rw(FUNC(sunplus_gcm394_base_device::unkarea_7961_r), FUNC(sunplus_gcm394_base_device::unkarea_7961_w)); @@ -499,7 +646,13 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) // 7axx region = system (including dma) // ###################################################################################################################################################################################### - map(0x007a80, 0x007a86).w(FUNC(sunplus_gcm394_base_device::system_dma_params_w)); + 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 + + // 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)); // ###################################################################################################################################################################################### @@ -518,25 +671,53 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r) READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) { - m_testval ^= 1; - logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context()); + //logerror("%s:sunplus_gcm394_base_device::unkarea_7854_r\n", machine().describe_context()); // jak_tsm code looks for various 'magic values' - if (m_testval == 1) - return 0x98; - else - return 0x79; + if (m_nandcommand == 0x90) // read ident + { + m_testval ^= 1; + if (m_testval == 0) + return 0x73; + else + return 0x98; + } + else if (m_nandcommand == 0x00) // read data + { + //uint8_t d + uint32_t nandaddress = (m_flash_addr_high << 16) | m_flash_addr_low; + uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr); + + //printf("reading nand byte %02x\n", data); + + m_curblockaddr++; + + return data; + } + else if (m_nandcommand == 0x70) // read status + { + return 0xffff; + } + + return 0x00; } // 7998 +WRITE16_MEMBER(generalplus_gpac800_device::nand_command_w) +{ + logerror("%s:sunplus_gcm394_base_device::nand_command_w %04x\n", machine().describe_context(), data); + m_nandcommand = data; +} + WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_low_w) { //logerror("%s:sunplus_gcm394_base_device::flash_addr_low_w %04x\n", machine().describe_context(), data); m_flash_addr_low = data; + m_curblockaddr = 0; } WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) @@ -546,7 +727,10 @@ WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) uint32_t address = (m_flash_addr_high << 16) | m_flash_addr_low; + logerror("%s: flash address is now %08x\n", machine().describe_context(), address); + + m_curblockaddr = 0; } @@ -561,13 +745,12 @@ void generalplus_gpac800_device::gpac800_internal_map(address_map& map) // // this should be the NAND device, as the games attempt to do a DMA operation with '7854' as the source, and the target // as the RAM location where code needs to end up before jumping to it - map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // 'device ready' status flag? - - map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::flash_addr_low_w)); - map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::flash_addr_high_w)); - - - map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // data read port (timing appears to be important) + map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // 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 } void sunplus_gcm394_base_device::device_start() @@ -584,6 +767,7 @@ void sunplus_gcm394_base_device::device_start() m_space_write_cb.resolve(); m_mapping_write_cb.resolve(); + m_nand_read_cb.resolve_safe(0); m_unk_timer = timer_alloc(0); m_unk_timer->adjust(attotime::never); @@ -593,9 +777,12 @@ void sunplus_gcm394_base_device::device_reset() { unsp_20_device::device_reset(); - for (int i = 0; i < 7; i++) + for (int j = 0; j < 2; j++) { - m_dma_params[i] = 0x0000; + for (int i = 0; i < 7; i++) + { + m_dma_params[i][j] = 0x0000; + } } // 78xx unknown @@ -605,18 +792,18 @@ void sunplus_gcm394_base_device::device_reset() m_7807 = 0x0000; - m_7810 = 0x0000; + m_membankswitch_7810 = 0x0000; m_7816 = 0x0000; m_7817 = 0x0000; m_7819 = 0x0000; - m_7820 = 0x0000; - m_7821 = 0x0000; - m_7822 = 0x0000; - m_7823 = 0x0000; - m_7824 = 0x0000; + m_782x[0] = 0x0000; + m_782x[1] = 0x0000; + m_782x[2] = 0x0000; + m_782x[3] = 0x0000; + m_782x[4] = 0x0000; m_7835 = 0x0000; diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index 5ce0ff9a433..df7e849647e 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -35,6 +35,7 @@ public: m_porta_in(*this), m_portb_in(*this), m_porta_out(*this), + m_nand_read_cb(*this), m_space_read_cb(*this), m_space_write_cb(*this), m_mapping_write_cb(*this) @@ -52,6 +53,7 @@ public: auto space_write_callback() { return m_space_write_cb.bind(); } auto mapping_write_callback() { return m_mapping_write_cb.bind(); } + auto nand_read_callback() { return m_nand_read_cb.bind(); } DECLARE_WRITE_LINE_MEMBER(vblank) { m_spg_video->vblank(state); } @@ -75,14 +77,14 @@ protected: devcb_write16 m_porta_out; - uint16_t m_dma_params[7]; + uint16_t m_dma_params[7][2]; // unk 78xx uint16_t m_7803; uint16_t m_7807; - uint16_t m_7810; + uint16_t m_membankswitch_7810; uint16_t m_7816; uint16_t m_7817; @@ -90,11 +92,7 @@ protected: uint16_t m_7819; - uint16_t m_7820; - uint16_t m_7821; - uint16_t m_7822; - uint16_t m_7823; - uint16_t m_7824; + uint16_t m_782x[5]; uint16_t m_782d; @@ -143,6 +141,8 @@ protected: uint16_t m_7960; uint16_t m_7961; + devcb_read16 m_nand_read_cb; + private: devcb_read16 m_space_read_cb; devcb_write16 m_space_write_cb; @@ -150,11 +150,17 @@ private: DECLARE_READ16_MEMBER(unk_r); DECLARE_WRITE16_MEMBER(unk_w); + + void write_dma_params(int channel, int offset, uint16_t data); + uint16_t read_dma_params(int channel, int offset); + void trigger_systemm_dma(address_space &space, int channel, uint16_t data); - - DECLARE_WRITE16_MEMBER(system_dma_params_w); - DECLARE_WRITE16_MEMBER(system_dma_trigger_w); + DECLARE_READ16_MEMBER(system_dma_params_channel0_r); + DECLARE_WRITE16_MEMBER(system_dma_params_channel0_w); + DECLARE_READ16_MEMBER(system_dma_params_channel1_r); + DECLARE_WRITE16_MEMBER(system_dma_params_channel1_w); DECLARE_READ16_MEMBER(system_dma_status_r); + DECLARE_WRITE16_MEMBER(system_dma_trigger_w); DECLARE_READ16_MEMBER(unkarea_780f_status_r); DECLARE_READ16_MEMBER(unkarea_78fb_status_r); @@ -164,8 +170,10 @@ private: DECLARE_WRITE16_MEMBER(unkarea_7807_w); - DECLARE_READ16_MEMBER(unkarea_7810_r); - DECLARE_WRITE16_MEMBER(unkarea_7810_w); + DECLARE_WRITE16_MEMBER(waitmode_enter_780c_w); + + DECLARE_READ16_MEMBER(membankswitch_7810_r); + DECLARE_WRITE16_MEMBER(membankswitch_7810_w); DECLARE_WRITE16_MEMBER(unkarea_7816_w); DECLARE_WRITE16_MEMBER(unkarea_7817_w); @@ -173,11 +181,7 @@ private: DECLARE_READ16_MEMBER(unkarea_7819_r); DECLARE_WRITE16_MEMBER(unkarea_7819_w); - DECLARE_WRITE16_MEMBER(unkarea_7820_w); - DECLARE_WRITE16_MEMBER(unkarea_7821_w); - DECLARE_WRITE16_MEMBER(unkarea_7822_w); - DECLARE_WRITE16_MEMBER(unkarea_7823_w); - DECLARE_WRITE16_MEMBER(unkarea_7824_w); + DECLARE_WRITE16_MEMBER(chipselect_csx_memory_device_control_w); DECLARE_WRITE16_MEMBER(unkarea_7835_w); @@ -249,6 +253,11 @@ private: DECLARE_WRITE_LINE_MEMBER(videoirq_w); DECLARE_WRITE_LINE_MEMBER(audioirq_w); + DECLARE_READ16_MEMBER(system_7a3a_r) + { + return machine().rand(); + } + void checkirq6(); emu_timer *m_unk_timer; @@ -299,14 +308,20 @@ private: DECLARE_READ16_MEMBER(unkarea_7850_r); DECLARE_READ16_MEMBER(unkarea_7854_r); + DECLARE_WRITE16_MEMBER(nand_command_w); + DECLARE_WRITE16_MEMBER(flash_addr_low_w); DECLARE_WRITE16_MEMBER(flash_addr_high_w); int m_testval; + uint16_t m_nandcommand; + uint16_t m_flash_addr_low; uint16_t m_flash_addr_high; + int m_curblockaddr; + }; diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index b74441fe5b2..d965d10a8d4 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -31,6 +31,7 @@ gcm394_base_video_device::gcm394_base_video_device(const machine_config &mconfig , m_palette(*this, "palette") , m_gfxdecode(*this, "gfxdecode") , m_space_read_cb(*this) + , m_global_y_mask(0x1ff) { } @@ -301,9 +302,9 @@ void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, ui uint32_t nbits = 0; uint32_t y = line; - int yy = (yoff + y) & 0x1ff; - if (yy >= 0x01c0) - yy -= 0x0200; + int yy = (yoff + y);// &0x1ff; + //if (yy >= 0x01c0) + // yy -= 0x0200; if (yy > cliprect.max_y || yy < 0) return; @@ -355,9 +356,9 @@ void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, ui if (RowScroll) xx -= 0;// (int16_t)m_scrollram[yy & 0x1ff]; - xx &= 0x01ff; - if (xx >= 0x01c0) - xx -= 0x0200; + //xx &= 0x01ff; + //if (xx >= 0x01c0) + // xx -= 0x0200; if (xx >= 0 && xx <= cliprect.max_x) { @@ -408,17 +409,22 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca uint32_t tile_h = 8 << ((attr_reg & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT); uint32_t tile_w = 8 << ((attr_reg & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT); - uint32_t tile_count_x = 512 / tile_w; + int total_width = 512; - uint32_t bitmap_y = (scanline + yscroll) & 0xff; + if ((attr_reg >> 14) & 0x2) + total_width = 1024; + + uint32_t tile_count_x = total_width / tile_w; + + uint32_t bitmap_y = (scanline + yscroll);// &0xff; uint32_t y0 = bitmap_y / tile_h; uint32_t tile_scanline = bitmap_y % tile_h; uint32_t tile_address = tile_count_x * y0; for (uint32_t x0 = 0; x0 < tile_count_x; x0++, tile_address++) { - uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & 0xff) - 0x10; - uint32_t xx = (tile_w * x0 - xscroll) & 0x1ff; + uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & m_global_y_mask) - 0x10; + uint32_t xx = (tile_w * x0 - xscroll);// &0x1ff; uint32_t tile = (ctrl_reg & PAGE_WALLPAPER_MASK) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address); uint16_t palette = (ctrl_reg & PAGE_WALLPAPER_MASK) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2); @@ -694,6 +700,11 @@ WRITE16_MEMBER(gcm394_base_video_device::tmap0_regs_w) write_tmap_regs(0, m_tmap0_regs, offset, data); } +READ16_MEMBER(gcm394_base_video_device::tmap0_tilebase_lsb_r) +{ + return m_page0_addr_lsb; +} + WRITE16_MEMBER(gcm394_base_video_device::tmap0_tilebase_lsb_w) { LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap0_tilebase_lsb_w %04x\n", machine().describe_context(), data); @@ -701,6 +712,11 @@ WRITE16_MEMBER(gcm394_base_video_device::tmap0_tilebase_lsb_w) LOGMASKED(LOG_GCM394_TMAP, "\t(tmap0 tilegfxbase is now %04x%04x)\n", m_page0_addr_msb, m_page0_addr_lsb); } +READ16_MEMBER(gcm394_base_video_device::tmap0_tilebase_msb_r) +{ + return m_page0_addr_msb; +} + WRITE16_MEMBER(gcm394_base_video_device::tmap0_tilebase_msb_w) { LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap0_tilebase_msb_w %04x\n", machine().describe_context(), data); @@ -718,6 +734,12 @@ WRITE16_MEMBER(gcm394_base_video_device::tmap1_regs_w) write_tmap_regs(1, m_tmap1_regs, offset, data); } +READ16_MEMBER(gcm394_base_video_device::tmap1_tilebase_lsb_r) +{ + return m_page1_addr_lsb; +} + + WRITE16_MEMBER(gcm394_base_video_device::tmap1_tilebase_lsb_w) { LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap1_tilebase_lsb_w %04x\n", machine().describe_context(), data); @@ -725,6 +747,11 @@ WRITE16_MEMBER(gcm394_base_video_device::tmap1_tilebase_lsb_w) LOGMASKED(LOG_GCM394_TMAP, "\t(tmap1 tilegfxbase is now %04x%04x)\n", m_page1_addr_msb, m_page1_addr_lsb); } +READ16_MEMBER(gcm394_base_video_device::tmap1_tilebase_msb_r) +{ + return m_page1_addr_msb; +} + WRITE16_MEMBER(gcm394_base_video_device::tmap1_tilebase_msb_w) { LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap1_tilebase_msb_w %04x\n", machine().describe_context(), data); @@ -811,6 +838,11 @@ WRITE16_MEMBER(gcm394_base_video_device::unk_vid2_gfxbase_msb_w) // set to 001264c0 in wrlshunt, which point at the menu selectors (game names, arrows etc.) +READ16_MEMBER(gcm394_base_video_device::sprite_7022_gfxbase_lsb_r) +{ + return m_sprite_7022_gfxbase_lsb; +} + WRITE16_MEMBER(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::sprite_7022_gfxbase_lsb_w %04x\n", machine().describe_context(), data); @@ -818,6 +850,11 @@ WRITE16_MEMBER(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w) LOGMASKED(LOG_GCM394_TMAP, "\t(sprite tilebase is now %04x%04x)\n", m_sprite_702d_gfxbase_msb, m_sprite_7022_gfxbase_lsb); } +READ16_MEMBER(gcm394_base_video_device::sprite_702d_gfxbase_msb_r) +{ + return m_sprite_702d_gfxbase_msb; +} + WRITE16_MEMBER(gcm394_base_video_device::sprite_702d_gfxbase_msb_w) { LOGMASKED(LOG_GCM394_VIDEO, "%s:gcm394_base_video_device::sprite_702d_gfxbase_msb_w %04x\n", machine().describe_context(), data); diff --git a/src/devices/machine/sunplus_gcm394_video.h b/src/devices/machine/sunplus_gcm394_video.h index 73d9da3e5c7..a2a54a1b388 100644 --- a/src/devices/machine/sunplus_gcm394_video.h +++ b/src/devices/machine/sunplus_gcm394_video.h @@ -29,11 +29,15 @@ public: DECLARE_READ16_MEMBER(tmap0_regs_r); DECLARE_WRITE16_MEMBER(tmap0_regs_w); + DECLARE_READ16_MEMBER(tmap0_tilebase_lsb_r); + DECLARE_READ16_MEMBER(tmap0_tilebase_msb_r); DECLARE_WRITE16_MEMBER(tmap0_tilebase_lsb_w); DECLARE_WRITE16_MEMBER(tmap0_tilebase_msb_w); DECLARE_READ16_MEMBER(tmap1_regs_r); DECLARE_WRITE16_MEMBER(tmap1_regs_w); + DECLARE_READ16_MEMBER(tmap1_tilebase_lsb_r); + DECLARE_READ16_MEMBER(tmap1_tilebase_msb_r); DECLARE_WRITE16_MEMBER(tmap1_tilebase_lsb_w); DECLARE_WRITE16_MEMBER(tmap1_tilebase_msb_w); @@ -44,6 +48,9 @@ public: DECLARE_WRITE16_MEMBER(unk_vid2_regs_w); DECLARE_WRITE16_MEMBER(unk_vid2_gfxbase_lsb_w); DECLARE_WRITE16_MEMBER(unk_vid2_gfxbase_msb_w); + + DECLARE_READ16_MEMBER(sprite_7022_gfxbase_lsb_r); + DECLARE_READ16_MEMBER(sprite_702d_gfxbase_msb_r); DECLARE_WRITE16_MEMBER(sprite_7022_gfxbase_lsb_w); DECLARE_WRITE16_MEMBER(sprite_702d_gfxbase_msb_w); @@ -220,6 +227,7 @@ protected: int m_maxgfxelement; void decodegfx(const char* tag); + int m_global_y_mask; }; class gcm394_video_device : public gcm394_base_video_device diff --git a/src/mame/drivers/generalplus_gpl32612.cpp b/src/mame/drivers/generalplus_gpl32612.cpp index 673b112b017..89db04dd7cf 100644 --- a/src/mame/drivers/generalplus_gpl32612.cpp +++ b/src/mame/drivers/generalplus_gpl32612.cpp @@ -7,6 +7,12 @@ unlike earlier SunPlus / GeneralPlus based SoCs this one seems to be ARM based + + NAND types + + Star Wars Blaster MX30LF1G08AA (2048+64) x 64 x 512 + TMNT Hero Portal MX30LF1G08AA (2048+64) x 64 x 512 + *****************************************************************************/ diff --git a/src/mame/drivers/storio.cpp b/src/mame/drivers/storio.cpp index 4907ff02968..286cd03b467 100644 --- a/src/mame/drivers/storio.cpp +++ b/src/mame/drivers/storio.cpp @@ -15,6 +15,10 @@ TODO: everything! + NAND types + + Storio Spanish old BIOS TC58NVG0S3ETA00 (2048+64) x 64 x 1024 + *******************************************************************************/ #include "emu.h" diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index 46e1df81787..56e4de23f4a 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -5,6 +5,7 @@ Compared to vii.cpp this is clearly newer, has extra opcodes, different internal map etc. also scaling and higher resolutions based on Spongebob + note, these SoC types always have a 128Kwords internal ROM, which the JAKKS games appear to use for basic bootstrap purposes. GPL600 Smart Fit Park @@ -28,6 +29,17 @@ smartfp: hold button Circle, Star and Home on startup for Test Menu these are both unsp 2.0 type, as they use the extended ocpodes + + + NAND types: + + Toy Story Mania H27U518S2C dumped as HY27US08121A (512+16) x 32 x 4096 + Beam Box GPR27P512A dumped as HY27US08121A (512+16) x 32 x 4096 + Golden Tee GPR27P512A dumped as HY27US08121A (512+16) x 32 x 4096 + Cars 2 GPR27P512A dumped as HY27US08121A (512+16) x 32 x 4096 + + V.Baby HY27UF081G2A (2048+64) x 64 x 1024 + */ #include "emu.h" @@ -86,7 +98,6 @@ private: uint32_t m_current_bank; int m_numbanks; - }; class wrlshunt_game_state : public gcm394_game_state @@ -127,7 +138,9 @@ class generalplus_gpac800_game_state : public gcm394_game_state public: generalplus_gpac800_game_state(const machine_config& mconfig, device_type type, const char* tag) : gcm394_game_state(mconfig, type, tag), - m_mainram(*this, "mainram") + m_mainram(*this, "mainram"), + m_initial_copy_words(0x2000), + m_nandreadbase(0) { } @@ -135,20 +148,42 @@ public: void nand_init210(); void nand_init840(); + void nand_wlsair60(); + void nand_vbaby(); + void nand_tsm(); protected: virtual void machine_reset() override; void generalplus_gpac800_map(address_map &map); + DECLARE_READ8_MEMBER(read_nand); private: void nand_init(int blocksize, int blocksize_stripped); required_shared_ptr m_mainram; std::vector m_strippedrom; + int m_strippedsize; + + int m_initial_copy_words; + int m_nandreadbase; + + virtual DECLARE_WRITE16_MEMBER(write_external_space) override; }; +READ8_MEMBER(generalplus_gpac800_game_state::read_nand) +{ + return m_strippedrom[(offset + m_nandreadbase) & (m_strippedsize - 1)]; +} +WRITE16_MEMBER(generalplus_gpac800_game_state::write_external_space) +{ + if (offset < 0x0400000) + { + m_mainram[offset] = data; + // logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data); + } +} READ16_MEMBER(gcm394_game_state::read_external_space) @@ -310,6 +345,11 @@ void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config) m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_maincpu->nand_read_callback().set(FUNC(generalplus_gpac800_game_state::read_nand)); + + m_screen->set_size(320*2, 262*2); + m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1); + } @@ -353,6 +393,21 @@ void gcm394_game_state::machine_reset() m_current_bank = 0; } + +/* + map info + + map(0x000000, 0x006fff) internal RAM + map(0x007000, 0x007fff) internal peripherals + map(0x008000, 0x00ffff) internal ROM (lower 32kwords) - can also be configured to mirror CS0 308000 area with external pin for boot from external ROM + map(0x010000, 0x027fff) internal ROM (upper 96kwords) - can't be switched + map(0x028000, 0x02ffff) reserved + + map(0x030000, 0x0.....) view into external spaces (CS0 area starts here. followed by CS1 area, CS2 area etc.) + + map(0x200000, 0x3fffff) continued view into external spaces, but this area is banked with m_membankswitch_7810 (valid bank values 0x00-0x3f) +*/ + void gcm394_game_state::mem_map_4m(address_map &map) { map(0x000000, 0x00ffff).rom().region("maincpu", 0); // non-banked area on this SoC? @@ -797,22 +852,13 @@ void generalplus_gpac800_game_state::machine_reset() int dest = m_strippedrom[0x15] << 8; // copy a block of code from the NAND to RAM - for (int i = 0; i < 0x7000-dest; i++) + for (int i = 0; i < m_initial_copy_words; i++) { uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8); mem.write_word(dest+i, word); } - int rambase = 0x30000; - for (int i = 0x4000/2; i < 0x37c000/2; i++) - { - uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8); - - m_mainram[rambase] = word; - rambase++; - } - mem.write_word(0xfff5, 0x6fea); mem.write_word(0xfff6, 0x6fec); mem.write_word(0xfff7, dest+0x20); // point boot vector at code in RAM @@ -825,20 +871,6 @@ void generalplus_gpac800_game_state::machine_reset() mem.write_word(0xfffe, 0x6ffc); mem.write_word(0xffff, 0x6ffe); - // 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 - - if (mem.read_word(0x4368c) == 0x4846) - mem.write_word(0x4368c, 0x4840); // cars 2 force service mode - - if (mem.read_word(0x4d8d4) == 0x4840) - mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack - - if (mem.read_word(0x34410) == 0x4846) - mem.write_word(0x34410, 0x4840); // golden tee force service mode - - m_maincpu->reset(); // reset CPU so vector gets read etc. } @@ -849,8 +881,8 @@ void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stri int size = memregion("maincpu")->bytes(); int numblocks = size / blocksize; - - m_strippedrom.resize(numblocks * blocksize_stripped); + m_strippedsize = numblocks * blocksize_stripped; + m_strippedrom.resize(m_strippedsize); for (int i = 0; i < numblocks; i++) { @@ -888,11 +920,39 @@ void generalplus_gpac800_game_state::nand_init840() nand_init(0x840, 0x800); } +void generalplus_gpac800_game_state::nand_wlsair60() +{ + nand_init840(); + m_initial_copy_words = 0x2800; +} + +void generalplus_gpac800_game_state::nand_vbaby() +{ + nand_init840(); + m_initial_copy_words = 0x1000; +} + +void generalplus_gpac800_game_state::nand_tsm() +{ + nand_init210(); + + // something odd must be going on with the bootloader? + // structure has the first 0x4000 block repeated 3 times (must appear in RAM on startup?) + // then it has a 0x10000 block repeated 4 times (must get copied to 0x30000 by code) + // then it has the larger, main payload, just the once. + + // the addresses written to the NAND device don't compensate for these data repeats, however dump seems ok as no other data is being repeated? + // reads after startup still need checking + m_nandreadbase = (0x2000 + 0x2000 + 0x8000 + 0x8000 + 0x8000) * 2; +} + + + // NAND dumps w/ internal bootstrap (and u'nSP 2.0 extended opcodes) (have gpnandnand strings) // the JAKKS ones seem to be known as 'Generalplus GPAC800' hardware -CONS(2010, wlsair60, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init840, "Jungle Soft / Kids Station Toys Inc", "Wireless Air 60", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_gtg, 0, 0, generalplus_gpac800, jak_gtg, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Golden Tee Golf (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_car2, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Cars 2 (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, jak_tsm , 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Toy Story Mania (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, vbaby, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init840, "VTech", "V.Baby", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) -CONS(200?, beambox, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "Hasbro", "Playskool Heroes Transformers Rescue Bots Beam Box (Spain)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(2010, wlsair60, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_wlsair60, "Jungle Soft / Kids Station Toys Inc", "Wireless Air 60", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_gtg, 0, 0, generalplus_gpac800, jak_gtg, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Golden Tee Golf (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_car2, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "JAKKS Pacific Inc", "Cars 2 (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, jak_tsm , 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_tsm, "JAKKS Pacific Inc", "Toy Story Mania (JAKKS Pacific TV Game)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, vbaby, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_vbaby, "VTech", "V.Baby", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) +CONS(200?, beambox, 0, 0, generalplus_gpac800, jak_car2, generalplus_gpac800_game_state, nand_init210, "Hasbro", "Playskool Heroes Transformers Rescue Bots Beam Box (Spain)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)