diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index a79e5e1bba4..3d5758d176d 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -33,6 +33,10 @@ generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mco { } +void sunplus_gcm394_base_device::default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4) +{ + logerror("callback not hooked\n"); +} // **************************************** SYSTEM DMA device ************************************************* @@ -91,7 +95,7 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c 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 ); + 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 ((source&0x0fffffff) >= 0x20000) LOGMASKED(LOG_GCM394_SYSDMA, " likely transfer from ROM %08x - %08x\n", (source - 0x20000) * 2, (source - 0x20000) * 2 + (length * 2)- 1); @@ -109,14 +113,14 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c for (int i = 0; i < length/2; i++) { - uint16_t val1 = mem.read_word(source); - uint16_t val2 = mem.read_word(source); + uint16_t val1 = read_space(source); + uint16_t val2 = read_space(source); - //printf("val1 %04x val2 %04x\n", val1, val2); + //logerror("val1 %04x val2 %04x\n", val1, val2); uint16_t val = (val2 << 8) | val1; - m_space_write_cb(space, dest, val); + write_space(dest, val); dest += 1; } @@ -126,45 +130,26 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c 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(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 - + //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++) { - uint16_t val = 0x0000; - address_space& mem = this->space(AS_PROGRAM); - - if (source < 0x20000) - { - val = mem.read_word(source); - } - else - { - // maybe the -0x20000 here should be handled in external space handlers instead - val = m_space_read_cb(space, source - 0x20000); - } - - if (dest < 0x20000) - { - mem.write_word(dest, val); - } - else - { - // maybe the -0x20000 here should be handled in external space handlers instead - m_space_write_cb(space, dest - 0x20000, val); - } + uint16_t val = read_space(source); + write_space(dest , val); dest += 1; + if ((mode&0x3fff) == 0x0009) source += 1; } @@ -237,7 +222,8 @@ 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); + if (m_membankswitch_7810 != data) + popmessage("bankswitch %04x -> %04x", m_membankswitch_7810, data); m_membankswitch_7810 = data; } @@ -253,7 +239,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_ if (offset == 0) m_mapping_write_cb(data); - + static const char* const md[] = { @@ -270,6 +256,9 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_ 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); + + m_cs_callback(m_782x[0], m_782x[1], m_782x[2], m_782x[3], m_782x[4]); + } @@ -435,7 +424,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unk_w) } } -void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) +void sunplus_gcm394_base_device::base_internal_map(address_map &map) { map(0x000000, 0x006fff).ram(); map(0x007000, 0x007fff).rw(FUNC(sunplus_gcm394_base_device::unk_r), FUNC(sunplus_gcm394_base_device::unk_w)); // catch unhandled @@ -662,6 +651,77 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map) map(0x007b80, 0x007bbf).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::control_r), FUNC(sunplus_gcm394_audio_device::control_w)); map(0x007c00, 0x007dff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_r), FUNC(sunplus_gcm394_audio_device::audio_w)); map(0x007e00, 0x007fff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_phase_r), FUNC(sunplus_gcm394_audio_device::audio_phase_w)); + +} + +void sunplus_gcm394_base_device::gcm394_internal_map(address_map& map) +{ + sunplus_gcm394_base_device::base_internal_map(map); + + // no internal ROM on this model? + + map(0x08000, 0x0ffff).r(FUNC(sunplus_gcm394_base_device::internalrom_lower32_r)).nopw(); + + map(0x020000, 0x1fffff).rw(FUNC(sunplus_gcm394_base_device::cs_space_r), FUNC(sunplus_gcm394_base_device::cs_space_w)); + map(0x200000, 0x3fffff).rw(FUNC(sunplus_gcm394_base_device::cs_bank_space_r), FUNC(sunplus_gcm394_base_device::cs_bank_space_w)); +} + +READ16_MEMBER(sunplus_gcm394_base_device::cs_space_r) +{ + return m_cs_space->read_word(offset); +} + +WRITE16_MEMBER(sunplus_gcm394_base_device::cs_space_w) +{ + m_cs_space->write_word(offset, data); +} +READ16_MEMBER(sunplus_gcm394_base_device::cs_bank_space_r) +{ + int bank = m_membankswitch_7810 & 0x3f; + int realoffset = offset + (bank * 0x200000) - m_csbase; + + if (realoffset < 0) + { + logerror("read real offset < 0\n"); + 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) +{ + int bank = m_membankswitch_7810 & 0x3f; + int realoffset = offset + (bank * 0x200000) - m_csbase; + + if (realoffset < 0) + { + logerror("write real offset < 0\n"); + return; + } + + m_cs_space->write_word(realoffset, data); +} + + + +READ16_MEMBER(sunplus_gcm394_base_device::internalrom_lower32_r) +{ + if (m_boot_mode == 0) + { + uint16_t* introm = (uint16_t*)m_internalrom->base(); + return introm[offset]; + } + else + { + if (!m_cs_space) + return 0x0000; + + uint16_t val = m_cs_space->read_word(offset+0x8000); + return val; + } } READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r) @@ -691,7 +751,7 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r) 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); + //logerror("reading nand byte %02x\n", data); m_curblockaddr++; @@ -738,31 +798,40 @@ WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w) // so it's likely this is built on top of that just with NAND support void generalplus_gpac800_device::gpac800_internal_map(address_map& map) { - sunplus_gcm394_base_device::gcm394_internal_map(map); + sunplus_gcm394_base_device::base_internal_map(map); - // there is an extra command-based device at 785x, what it returns is important to code flow - // code is littered with NOPs so clearly the device can't accept commands too quickly and doesn't return data immediately - // - // 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 + // 785x = NAND device 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 + + // 128kwords internal ROM + //map(0x08000, 0x0ffff).rom().region("internal", 0); // lower 32kwords of internal ROM is visible / shadowed depending on boot pins and register + map(0x08000, 0x0ffff).r(FUNC(generalplus_gpac800_device::internalrom_lower32_r)).nopw(); + map(0x10000, 0x27fff).rom().region("internal", 0x10000); // upper 96kwords of internal ROM is always visible + map(0x28000, 0x2ffff).noprw(); // reserved + // 0x30000+ is CS access + + map(0x030000, 0x1fffff).rw(FUNC(generalplus_gpac800_device::cs_space_r), FUNC(generalplus_gpac800_device::cs_space_w)); + 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(); + m_cs_callback.resolve(); + m_porta_in.resolve_safe(0); m_portb_in.resolve_safe(0); m_porta_out.resolve(); + m_space_read_cb.resolve_safe(0); m_space_write_cb.resolve(); m_mapping_write_cb.resolve(); @@ -792,7 +861,7 @@ void sunplus_gcm394_base_device::device_reset() m_7807 = 0x0000; - m_membankswitch_7810 = 0x0000; + m_membankswitch_7810 = 0x0001; m_7816 = 0x0000; m_7817 = 0x0000; @@ -850,10 +919,6 @@ void sunplus_gcm394_base_device::device_reset() m_unk_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60)); - - m_gfxregion = memregion(":maincpu")->base(); - m_gfxregionsize = memregion(":maincpu")->bytes(); - } void generalplus_gpac800_device::device_reset() @@ -942,13 +1007,34 @@ WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w) uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset) { -// uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8); -// return b; - address_space& mem = this->space(AS_PROGRAM); - uint16_t retdata = mem.read_word(offset); - return retdata; + address_space& space = this->space(AS_PROGRAM); + uint16_t val; + if (offset < m_csbase) + { + val = space.read_word(offset); + } + else + { + val = m_cs_space->read_word(offset-m_csbase); + } + + return val; } +void sunplus_gcm394_base_device::write_space(uint32_t offset, uint16_t data) +{ + address_space& space = this->space(AS_PROGRAM); + if (offset < m_csbase) + { + space.write_word(offset, data); + } + else + { + m_cs_space->write_word(offset-m_csbase, data); + } +} + + void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config) { diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index df7e849647e..0f05342b9bd 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -17,6 +17,7 @@ #include "sunplus_gcm394_video.h" #include "spg2xx_audio.h" +typedef device_delegate sunplus_gcm394_cs_callback_device; class sunplus_gcm394_base_device : public unsp_20_device, public device_mixer_interface { @@ -32,13 +33,17 @@ public: m_screen(*this, finder_base::DUMMY_TAG), m_spg_video(*this, "spgvideo"), m_spg_audio(*this, "spgaudio"), + m_internalrom(*this, "internal"), m_porta_in(*this), m_portb_in(*this), m_porta_out(*this), m_nand_read_cb(*this), + m_csbase(0x20000), m_space_read_cb(*this), m_space_write_cb(*this), - m_mapping_write_cb(*this) + m_mapping_write_cb(*this), + m_boot_mode(0), + m_cs_callback(*this, DEVICE_SELF, FUNC(sunplus_gcm394_base_device::default_cs_callback)) { } @@ -59,7 +64,13 @@ public: virtual void device_add_mconfig(machine_config& config) override; + void set_bootmode(int mode) { m_boot_mode = mode; } + IRQ_CALLBACK_MEMBER(irq_vector_cb); + template void set_cs_config_callback(T &&... args) { m_cs_callback.set(std::forward(args)...); } + void default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4 ); + + void set_cs_space(address_space* csspace) { m_cs_space = csspace; } protected: @@ -67,10 +78,12 @@ protected: virtual void device_reset() override; void gcm394_internal_map(address_map &map); + void base_internal_map(address_map &map); required_device m_screen; required_device m_spg_video; required_device m_spg_audio; + optional_memory_region m_internalrom; devcb_read16 m_porta_in; devcb_read16 m_portb_in; @@ -142,6 +155,16 @@ protected: uint16_t m_7961; devcb_read16 m_nand_read_cb; + int m_csbase; + + DECLARE_READ16_MEMBER(internalrom_lower32_r); + + address_space* m_cs_space; + + DECLARE_READ16_MEMBER(cs_space_r); + DECLARE_WRITE16_MEMBER(cs_space_w); + DECLARE_READ16_MEMBER(cs_bank_space_r); + DECLARE_WRITE16_MEMBER(cs_bank_space_w); private: devcb_read16 m_space_read_cb; @@ -263,9 +286,12 @@ private: emu_timer *m_unk_timer; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - uint8_t* m_gfxregion; - uint32_t m_gfxregionsize; - uint16_t read_space(uint32_t offset); + inline uint16_t read_space(uint32_t offset); + inline void write_space(uint32_t offset, uint16_t data); + + // config registers (external pins) + int m_boot_mode; // 2 pins determine boot mode, likely only read at power-on + sunplus_gcm394_cs_callback_device m_cs_callback; }; @@ -294,6 +320,7 @@ public: { m_screen.set_tag(std::forward(screen_tag)); m_testval = 0; + m_csbase = 0x30000; } generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index d965d10a8d4..19391111da4 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -207,7 +207,9 @@ void gcm394_base_video_device::device_start() m_maxgfxelement = 0; - decodegfx(":maincpu"); + // debug helper only + if (memregion(":maincpu")) + decodegfx(":maincpu"); save_item(NAME(m_spriteextra)); save_item(NAME(m_spriteram)); diff --git a/src/mame/drivers/nes_vt.cpp b/src/mame/drivers/nes_vt.cpp index 889b7f6bec7..fc1fb32a51d 100644 --- a/src/mame/drivers/nes_vt.cpp +++ b/src/mame/drivers/nes_vt.cpp @@ -2359,6 +2359,8 @@ CONS( 200?, lxcmcysw, 0, 0, nes_vt_cy, nes_vt, nes_vt_cy_state, empty_init, " // Lexibook Compact Cyber Arcade - Paw Patrol // Lexibook Compact Cyber Arcade - Barbie // Lexibook Compact Cyber Arcade - Finding Dory +// Lexibook Compact Cyber Arcade - Marvel Ultimate Spiderman +// Lexibook Compact Cyber Arcade - PJ Masks // more? diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index 56e4de23f4a..7bba62b32e7 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -50,6 +50,89 @@ #include "speaker.h" + + +class full_memory_device : + public device_t, + public device_memory_interface +{ +public: + // construction/destruction + full_memory_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // configuration helpers + template full_memory_device& set_map(T &&... args) { set_addrmap(0, std::forward(args)...); return *this; } + + template full_memory_device& map(T &&... args) { set_addrmap(0, std::forward(args)...); return *this; } + + address_space* get_program() { return m_program; } + +protected: + virtual void device_start() override; + virtual void device_config_complete() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + +private: + // internal state + address_space_config m_program_config; + address_space *m_program; + int m_shift; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(FULL_MEMORY, full_memory_device) + +// device type definition +DEFINE_DEVICE_TYPE(FULL_MEMORY, full_memory_device, "full_memory", "SunPlus Full CS Memory Map") + +full_memory_device::full_memory_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, FULL_MEMORY, tag, owner, clock), + device_memory_interface(mconfig, *this), + m_program(nullptr) +{ +} + +device_memory_interface::space_config_vector full_memory_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config) + }; +} + +/* +':maincpu' (00F87F):possible DMA operation (7abf) (trigger 0001) with params mode:4009 source:00040000 (word offset) dest:00830000 (word offset) length:00007800 (words) +':maincpu' (002384):possible DMA operation (7abf) (trigger 0001) with params mode:0009 source:00180000 (word offset) dest:00840000 (word offset) length:00160000 (words) + +':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:000025bc (word offset) length:000001e0 (words) +':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:000024cc (word offset) length:000000f0 (words) +':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000002 (word offset) length:00000400 (words) +':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000402 (word offset) length:00000400 (words) +':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000802 (word offset) length:00000400 (words) + +gtg +':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030000 (word offset) length:00000200 (words) +':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030100 (word offset) length:00000200 (words) +':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030200 (word offset) length:00000200 (words) +':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030300 (word offset) length:00000200 (words) +':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030400 (word offset) length:00000200 (words) + +*/ + +void full_memory_device::device_config_complete() +{ + m_program_config = address_space_config( "program", ENDIANNESS_BIG, 16, 32, -1 ); +} + +void full_memory_device::device_start() +{ + m_program = &space(AS_PROGRAM); +} + + class gcm394_game_state : public driver_device { public: @@ -57,33 +140,45 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), - m_bank(*this, "cartbank"), m_io_p1(*this, "P1"), m_io_p2(*this, "P2"), - m_romregion(*this, "maincpu") + m_romregion(*this, "maincpu"), + m_memory(*this, "memory") { } void base(machine_config &config); + void cs_map_base(address_map &map); + + virtual DECLARE_READ16_MEMBER(cs0_r); + virtual DECLARE_WRITE16_MEMBER(cs0_w); + virtual DECLARE_READ16_MEMBER(cs1_r); + virtual DECLARE_WRITE16_MEMBER(cs1_w); + virtual DECLARE_READ16_MEMBER(cs2_r); + virtual DECLARE_WRITE16_MEMBER(cs2_w); + virtual DECLARE_READ16_MEMBER(cs3_r); + virtual DECLARE_WRITE16_MEMBER(cs3_w); + virtual DECLARE_READ16_MEMBER(cs4_r); + virtual DECLARE_WRITE16_MEMBER(cs4_w); + + void cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4); protected: virtual void machine_start() override; virtual void machine_reset() override; - void switch_bank(uint32_t bank); required_device m_maincpu; required_device m_screen; - optional_memory_bank m_bank; required_ioport m_io_p1; required_ioport m_io_p2; - virtual void mem_map_4m(address_map &map); - required_region_ptr m_romregion; + optional_region_ptr m_romregion; + required_device m_memory; DECLARE_READ16_MEMBER(porta_r); DECLARE_READ16_MEMBER(portb_r); @@ -95,42 +190,47 @@ protected: virtual DECLARE_WRITE16_MEMBER(write_external_space); private: - - uint32_t m_current_bank; - int m_numbanks; }; -class wrlshunt_game_state : public gcm394_game_state +READ16_MEMBER(gcm394_game_state::cs0_r) { -public: - wrlshunt_game_state(const machine_config& mconfig, device_type type, const char* tag) : - gcm394_game_state(mconfig, type, tag), - m_mapping(0), - m_mainram(*this, "mainram") - { - } + return m_romregion[offset & 0x3fffff]; +} - void wrlshunt(machine_config &config); +WRITE16_MEMBER(gcm394_game_state::cs0_w) +{ + logerror("cs0_w %04x %04x (to ROM!)\n", offset, data); +} -protected: - //virtual void machine_start() override; - //virtual void machine_reset() override; +READ16_MEMBER(gcm394_game_state::cs1_r) { logerror("cs1_r %06n", offset); return 0x0000; } +WRITE16_MEMBER(gcm394_game_state::cs1_w) { logerror("cs1_w %06x %04x\n", offset, data); } +READ16_MEMBER(gcm394_game_state::cs2_r) { logerror("cs2_r %06n", offset); return 0x0000; } +WRITE16_MEMBER(gcm394_game_state::cs2_w) { logerror("cs2_w %06x %04x\n", offset, data); } +READ16_MEMBER(gcm394_game_state::cs3_r) { logerror("cs3_r %06n", offset); return 0x0000; } +WRITE16_MEMBER(gcm394_game_state::cs3_w) { logerror("cs3_w %06x %04x\n", offset, data); } +READ16_MEMBER(gcm394_game_state::cs4_r) { logerror("cs4_r %06n", offset); return 0x0000; } +WRITE16_MEMBER(gcm394_game_state::cs4_w) { logerror("cs4_w %06x %04x\n", offset, data); } - void wrlshunt_map(address_map &map); -private: +/* + map info (NAND type) - DECLARE_READ16_MEMBER(hunt_porta_r); - DECLARE_WRITE16_MEMBER(hunt_porta_w); + 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 - virtual DECLARE_WRITE16_MEMBER(mapping_w) override; - uint16_t m_mapping; + 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) +*/ - required_shared_ptr m_mainram; - virtual DECLARE_READ16_MEMBER(read_external_space) override; - virtual DECLARE_WRITE16_MEMBER(write_external_space) override; -}; + +void gcm394_game_state::cs_map_base(address_map& map) +{ +} class generalplus_gpac800_game_state : public gcm394_game_state @@ -138,7 +238,7 @@ 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_has_nand(false), m_initial_copy_words(0x2000), m_nandreadbase(0) { @@ -155,106 +255,132 @@ public: protected: virtual void machine_reset() override; - void generalplus_gpac800_map(address_map &map); DECLARE_READ8_MEMBER(read_nand); + std::vector m_sdram; + std::vector m_sdram2; + virtual DECLARE_READ16_MEMBER(cs0_r) override; + virtual DECLARE_WRITE16_MEMBER(cs0_w) override; + virtual DECLARE_READ16_MEMBER(cs1_r) override; + virtual DECLARE_WRITE16_MEMBER(cs1_w) override; + + bool m_has_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; }; + + +class wrlshunt_game_state : public gcm394_game_state +{ +public: + wrlshunt_game_state(const machine_config& mconfig, device_type type, const char* tag) : + gcm394_game_state(mconfig, type, tag) + { + } + + void wrlshunt(machine_config &config); + + void init_wrlshunt(); + +protected: + //virtual void machine_start() override; + virtual void machine_reset() override; + + std::vector m_sdram; + +private: + + DECLARE_READ16_MEMBER(hunt_porta_r); + DECLARE_WRITE16_MEMBER(hunt_porta_w); + + //required_shared_ptr m_mainram; + + virtual DECLARE_READ16_MEMBER(cs0_r) override; + virtual DECLARE_WRITE16_MEMBER(cs0_w) override; + virtual DECLARE_READ16_MEMBER(cs1_r) override; + virtual DECLARE_WRITE16_MEMBER(cs1_w) override; +}; + + +READ16_MEMBER(wrlshunt_game_state::cs0_r) +{ + return m_romregion[offset & 0x3ffffff]; +} + +WRITE16_MEMBER(wrlshunt_game_state::cs0_w) +{ + logerror("cs0_w write to ROM?\n"); + //m_romregion[offset & 0x3ffffff] = data; +} + +READ16_MEMBER(wrlshunt_game_state::cs1_r) +{ + return m_sdram[offset & 0x3fffff]; +} + +WRITE16_MEMBER(wrlshunt_game_state::cs1_w) +{ + m_sdram[offset & 0x3fffff] = data; +} + + +void wrlshunt_game_state::machine_reset() +{ + cs_callback(0x00, 0x00, 0x00, 0x00, 0x00); + m_maincpu->set_cs_space(m_memory->get_program()); + m_maincpu->reset(); // reset CPU so vector gets read etc. +} + +void wrlshunt_game_state::init_wrlshunt() +{ + m_sdram.resize(0x400000); // 0x400000 bytes, 0x800000 words +} + +READ16_MEMBER(generalplus_gpac800_game_state::cs0_r) +{ + return m_sdram2[offset & 0xffff]; +} + +WRITE16_MEMBER(generalplus_gpac800_game_state::cs0_w) +{ + m_sdram2[offset & 0xffff] = data; +} + +READ16_MEMBER(generalplus_gpac800_game_state::cs1_r) +{ + return m_sdram[offset & 0x3fffff]; +} + +WRITE16_MEMBER(generalplus_gpac800_game_state::cs1_w) +{ + m_sdram[offset & 0x3fffff] = data; +} + READ8_MEMBER(generalplus_gpac800_game_state::read_nand) { + if (!m_has_nand) + return 0x0000; + 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) { - //logerror("reading offset %04x\n", offset * 2); - return m_romregion[offset]; + return m_memory->get_program()->read_word(offset); } WRITE16_MEMBER(gcm394_game_state::write_external_space) { - logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data); + m_memory->get_program()->write_word(offset, data); } -WRITE16_MEMBER(wrlshunt_game_state::mapping_w) -{ - m_mapping = data; - logerror("change mapping %04x\n", data); -} - -READ16_MEMBER(wrlshunt_game_state::read_external_space) -{ - if (m_mapping == 0x7f8a) - { - //logerror("reading offset %04x\n", offset * 2); - return m_romregion[offset]; - } - else if (m_mapping == 0x008a) - { - address_space& mem = m_maincpu->space(AS_PROGRAM); - uint16_t retdata = mem.read_word(offset + 0x20000); - logerror("reading from RAM instead offset %08x returning %04x\n", offset * 2, retdata); - return retdata; - } - else - { - uint16_t retdata = 0x0000; - logerror("reading from unknown source instead offset %08x returning %04x\n", offset * 2, retdata); - return retdata; - } -} - - - - -WRITE16_MEMBER(wrlshunt_game_state::write_external_space) -{ -// logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data); - - if (offset & 0x0800000) - { - offset &= 0x03fffff; - - if (offset < 0x03d0000) - { - m_mainram[offset] = data; - //logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data); - - } - else - { - logerror("DMA writing to external space (RAM?) (out of bounds) %08x %04x\n", offset, data); - } - } - else - { - logerror("DMA writing to external space (RAM?) (unknown handling) %08x %04x\n", offset, data); - } -} - - - READ16_MEMBER(gcm394_game_state::porta_r) { uint16_t data = m_io_p1->read(); @@ -278,7 +404,6 @@ WRITE16_MEMBER(gcm394_game_state::porta_w) void gcm394_game_state::base(machine_config &config) { GCM394(config, m_maincpu, XTAL(27'000'000), m_screen); - m_maincpu->set_addrmap(AS_PROGRAM, &gcm394_game_state::mem_map_4m); m_maincpu->porta_in().set(FUNC(gcm394_game_state::porta_r)); m_maincpu->portb_in().set(FUNC(gcm394_game_state::portb_r)); m_maincpu->porta_out().set(FUNC(gcm394_game_state::porta_w)); @@ -288,6 +413,10 @@ void gcm394_game_state::base(machine_config &config) m_maincpu->mapping_write_callback().set(FUNC(gcm394_game_state::mapping_w)); m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_maincpu->set_bootmode(1); // boot from external ROM / CS mirror + m_maincpu->set_cs_config_callback(FUNC(gcm394_game_state::cs_callback)); + + FULL_MEMORY(config, m_memory).set_map(&gcm394_game_state::cs_map_base); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); @@ -300,6 +429,19 @@ void gcm394_game_state::base(machine_config &config) SPEAKER(config, "rspeaker").front_right(); } +void wrlshunt_game_state::wrlshunt(machine_config &config) +{ + gcm394_game_state::base(config); + + m_maincpu->porta_in().set(FUNC(wrlshunt_game_state::hunt_porta_r)); + m_maincpu->porta_out().set(FUNC(wrlshunt_game_state::hunt_porta_w)); + m_maincpu->set_bootmode(1); // boot from external ROM / CS mirror + + m_screen->set_size(320*2, 262*2); + m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1); +} + + READ16_MEMBER(wrlshunt_game_state::hunt_porta_r) { uint16_t data = m_io_p1->read(); @@ -311,30 +453,17 @@ WRITE16_MEMBER(wrlshunt_game_state::hunt_porta_w) { logerror("%s: Port A:WRITE %04x\n", machine().describe_context(), data); - // skip check (EEPROM?) - if (m_mainram[0x5b354 - 0x30000] == 0xafd0) - m_mainram[0x5b354 - 0x30000] = 0xB403; + // HACK + address_space& mem = m_maincpu->space(AS_PROGRAM); + if (mem.read_word(0x5b354) == 0xafd0) // wrlshubt - skip check (EEPROM?) + mem.write_word(0x5b354, 0xB403); } -void wrlshunt_game_state::wrlshunt(machine_config &config) -{ - gcm394_game_state::base(config); - m_maincpu->set_addrmap(AS_PROGRAM, &wrlshunt_game_state::wrlshunt_map); - - m_maincpu->porta_in().set(FUNC(wrlshunt_game_state::hunt_porta_r)); - m_maincpu->porta_out().set(FUNC(wrlshunt_game_state::hunt_porta_w)); - - m_screen->set_size(320*2, 262*2); - m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1); -} void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config) { - gcm394_game_state::base(config); - - GPAC800(config.replace(), m_maincpu, XTAL(27'000'000), m_screen); - m_maincpu->set_addrmap(AS_PROGRAM, &generalplus_gpac800_game_state::generalplus_gpac800_map); + GPAC800(config, m_maincpu, XTAL(27'000'000), m_screen); m_maincpu->porta_in().set(FUNC(generalplus_gpac800_game_state::porta_r)); m_maincpu->portb_in().set(FUNC(generalplus_gpac800_game_state::portb_r)); m_maincpu->porta_out().set(FUNC(generalplus_gpac800_game_state::porta_w)); @@ -344,88 +473,80 @@ void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config) m_maincpu->mapping_write_callback().set(FUNC(generalplus_gpac800_game_state::mapping_w)); m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5); m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5); + m_maincpu->set_bootmode(0); // boot from internal ROM (NAND bootstrap) + m_maincpu->set_cs_config_callback(FUNC(gcm394_game_state::cs_callback)); m_maincpu->nand_read_callback().set(FUNC(generalplus_gpac800_game_state::read_nand)); + FULL_MEMORY(config, m_memory).set_map(&generalplus_gpac800_game_state::cs_map_base); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(60); m_screen->set_size(320*2, 262*2); m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1); + m_screen->set_screen_update("maincpu", FUNC(sunplus_gcm394_device::screen_update)); + m_screen->screen_vblank().set(m_maincpu, FUNC(sunplus_gcm394_device::vblank)); + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); } -void gcm394_game_state::switch_bank(uint32_t bank) -{ - if (!m_bank) - return; - - if (bank != m_current_bank) - { - m_current_bank = bank; - m_bank->set_entry(bank); - m_maincpu->invalidate_cache(); - } -} void gcm394_game_state::machine_start() { - if (m_bank) - { - int i; - for (i = 0; i < (m_romregion.bytes() / 0x800000); i++) - { - m_bank->configure_entry(i, &m_romregion[i * 0x800000]); - } - - m_numbanks = i; - - m_bank->set_entry(0); - } - else - { - m_numbanks = 0; - } - - save_item(NAME(m_current_bank)); } void gcm394_game_state::machine_reset() { - m_current_bank = 0; + cs_callback(0x00, 0x00, 0x00, 0x00, 0x00); + m_maincpu->set_cs_space(m_memory->get_program()); + + m_maincpu->reset(); // reset CPU so vector gets read etc. } -/* - map info +void gcm394_game_state::cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4) +{ + // wipe existing mappings; + m_memory->get_program()->unmap_readwrite(0, (0x8000000*5)-1); - 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 + int start_address = 0; + int end_address; - map(0x030000, 0x0.....) view into external spaces (CS0 area starts here. followed by CS1 area, CS2 area etc.) + int size; // cs region sizes in kwords - map(0x200000, 0x3fffff) continued view into external spaces, but this area is banked with m_membankswitch_7810 (valid bank values 0x00-0x3f) -*/ + size = (((cs0 & 0xff00) >> 8) + 1) * 0x10000; + end_address = start_address + (size - 1); + logerror("installing cs0 handler start_address %08x end_address %08x\n", start_address, end_address); + m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs0_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs0_w))); + start_address += size; -void gcm394_game_state::mem_map_4m(address_map &map) -{ - map(0x000000, 0x00ffff).rom().region("maincpu", 0); // non-banked area on this SoC? + size = (((cs1 & 0xff00) >> 8) + 1) * 0x10000; + end_address = start_address + (size - 1); + logerror("installing cs1 handler start_address %08x end_address %08x\n", start_address, end_address); + m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs1_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs1_w))); + start_address += size; - // smartfp really expects the ROM at 0 to map here, so maybe this is how the newer SoC works - map(0x020000, 0x3fffff).bankr("cartbank"); + size = (((cs2 & 0xff00) >> 8) + 1) * 0x10000; + end_address = start_address + (size - 1); + logerror("installing cs2 handler start_address %08x end_address %08x\n", start_address, end_address); + m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs2_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs2_w))); + start_address += size; + + size = (((cs3 & 0xff00) >> 8) + 1) * 0x10000; + end_address = start_address + (size - 1); + logerror("installing cs3 handler start_address %08x end_address %08x\n", start_address, end_address); + m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs3_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs3_w))); + start_address += size; + + size = (((cs4 & 0xff00) >> 8) + 1) * 0x10000; + end_address = start_address + (size - 1); + logerror("installing cs4 handler start_address %08x end_address %08x\n", start_address, end_address); + m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs4_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs4_w))); + //start_address += size; } -void wrlshunt_game_state::wrlshunt_map(address_map &map) -{ - map(0x000000, 0x00ffff).rom().region("maincpu", 0); // non-banked area on this SoC? - map(0x030000, 0x3fffff).ram().share("mainram"); -} - -void generalplus_gpac800_game_state::generalplus_gpac800_map(address_map &map) -{ - map(0x000000, 0x3fffff).ram().share("mainram"); -} static INPUT_PORTS_START( gcm394 ) @@ -686,6 +807,24 @@ static INPUT_PORTS_START( jak_gtg ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END + +ROM_START(smartfp) + //ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different) + //ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) + + ROM_REGION(0x800000, "maincpu", ROMREGION_ERASE00) + ROM_LOAD16_WORD_SWAP("smartfitpark.bin", 0x000000, 0x800000, CRC(ada84507) SHA1(a3a80bf71fae62ebcbf939166a51d29c24504428)) +ROM_END + +ROM_START(wrlshunt) + //ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different) + //ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) + + ROM_REGION(0x8000000, "maincpu", ROMREGION_ERASE00) + ROM_LOAD16_WORD_SWAP("wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796)) +ROM_END + + /* Wireless Hunting Video Game System (info provided with dump) @@ -762,16 +901,6 @@ which is also found in the Wireless Air 60 ROM. */ -ROM_START(wrlshunt) - ROM_REGION(0x8000000, "maincpu", ROMREGION_ERASE00) - ROM_LOAD16_WORD_SWAP("wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796)) -ROM_END - -ROM_START(smartfp) - ROM_REGION(0x800000, "maincpu", ROMREGION_ERASE00) - ROM_LOAD16_WORD_SWAP("smartfitpark.bin", 0x000000, 0x800000, CRC(ada84507) SHA1(a3a80bf71fae62ebcbf939166a51d29c24504428)) -ROM_END - /* Wireless Air 60 @@ -797,88 +926,134 @@ https://web.archive.org/web/20180106005235/http://www.lcis.com.tw/paper_store/pa */ ROM_START( wlsair60 ) - ROM_REGION( 0x8400000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "wlsair60.nand", 0x0000, 0x8400000, CRC(eec23b97) SHA1(1bb88290cf54579a5bb51c08a02d793cd4d79f7a) ) ROM_END ROM_START( jak_gtg ) - ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "goldentee.bin", 0x0000, 0x4200000, CRC(87d5e815) SHA1(5dc46cd753b791449cc41d5eff4928c0dcaf35c0) ) ROM_END ROM_START( jak_car2 ) - ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "cars2.bin", 0x0000, 0x4200000, CRC(4d610e09) SHA1(bc59f5f7f676a8f2a78dfda7fb62c804bbf850b6) ) ROM_END ROM_START( jak_tsm ) - ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "toystorymania.bin", 0x0000, 0x4200000, CRC(183b20a5) SHA1(eb4fa5ee9dfac58f5244d00d4e833b1e461cc52c) ) ROM_END ROM_START( vbaby ) - ROM_REGION( 0x8400000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "vbaby.bin", 0x0000, 0x8400000, CRC(d904441b) SHA1(3742bc4e1e403f061ce2813ecfafc6f30a44d287) ) ROM_END ROM_START( beambox ) - ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 ) + ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only + + ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "beambox.bin", 0x0000, 0x4200000, CRC(a486f04e) SHA1(73c7d99d8922eba58d94e955e254b9c3baa4443e) ) ROM_END // the JAKKS ones of these seem to be known as 'Generalplus GPAC500' hardware? -CONS(2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_game_state, empty_init, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) - CONS(2009, smartfp, 0, 0, base, gcm394, gcm394_game_state, empty_init, "Fisher-Price", "Fun 2 Learn Smart Fit Park (Spain)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND) // Fun 2 Learn 3-in-1 SMART SPORTS ? +CONS(2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_game_state, init_wrlshunt, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) + + void generalplus_gpac800_game_state::machine_reset() { + // configure CS defaults address_space& mem = m_maincpu->space(AS_PROGRAM); + mem.write_word(0x007820, 0x0047); + mem.write_word(0x007821, 0xff47); + mem.write_word(0x007822, 0x00c7); + mem.write_word(0x007823, 0x0047); + mem.write_word(0x007824, 0x0047); - /* Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - 00000000 (50 47 61 6E 64 6E 61 6E 64 6E)-- -- -- -- -- -- PGandnandn------ - 00000010 -- -- -- -- -- bb -- -- -- -- -- -- -- -- -- -- ---------------- - bb = where to copy first block + m_maincpu->set_cs_space(m_memory->get_program()); - The header is GPnandnand (byteswapped) then some params - one of the params appears to be for the initial code copy operation done - by the bootstrap - */ - - // probably more bytes are used - int dest = m_strippedrom[0x15] << 8; - - // copy a block of code from the NAND to RAM - for (int i = 0; i < m_initial_copy_words; i++) + if (m_has_nand) { - uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8); + // up to 256 pages (16384kw) for each space - mem.write_word(dest+i, word); + // (size of cs0 + cs1 + cs2 + cs3 + cs4) <= 81920kwords + + // simulate bootstrap / internal ROM + + address_space& mem = m_maincpu->space(AS_PROGRAM); + + /* Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 00000000 (50 47 61 6E 64 6E 61 6E 64 6E)-- -- -- -- -- -- PGandnandn------ + 00000010 -- -- -- -- -- bb -- -- -- -- -- -- -- -- -- -- ---------------- + + bb = where to copy first block + + The header is GPnandnand (byteswapped) then some params + one of the params appears to be for the initial code copy operation done + by the bootstrap + */ + + // probably more bytes are used + int dest = m_strippedrom[0x15] << 8; + + // copy a block of code from the NAND to RAM + 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); + } + + // these vectors must either directly point to RAM, or at least redirect there after some code + uint16_t* internal = (uint16_t*)memregion("maincpu:internal")->base(); + internal[0x7ff5] = 0x6fea; + internal[0x7ff6] = 0x6fec; + internal[0x7ff7] = dest + 0x20; // point boot vector at code in RAM (probably in reality points to internal code that copies the first block) + internal[0x7ff8] = 0x6ff0; + internal[0x7ff9] = 0x6ff2; + internal[0x7ffa] = 0x6ff4; + internal[0x7ffb] = 0x6ff6; + internal[0x7ffc] = 0x6ff8; + internal[0x7ffd] = 0x6ffa; + internal[0x7ffe] = 0x6ffc; + internal[0x7fff] = 0x6ffe; + + internal[0x8000] = 0xb00b; } - mem.write_word(0xfff5, 0x6fea); - mem.write_word(0xfff6, 0x6fec); - mem.write_word(0xfff7, dest+0x20); // point boot vector at code in RAM - mem.write_word(0xfff8, 0x6ff0); - mem.write_word(0xfff9, 0x6ff2); - mem.write_word(0xfffa, 0x6ff4); - mem.write_word(0xfffb, 0x6ff6); - mem.write_word(0xfffc, 0x6ff8); - mem.write_word(0xfffd, 0x6ffa); - mem.write_word(0xfffe, 0x6ffc); - mem.write_word(0xffff, 0x6ffe); - m_maincpu->reset(); // reset CPU so vector gets read etc. } void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stripped) { - uint8_t* rom = memregion("maincpu")->base(); - int size = memregion("maincpu")->bytes(); + m_sdram.resize(0x400000); // 0x400000 bytes, 0x800000 words + m_sdram2.resize(0x10000); + + uint8_t* rom = memregion("nandrom")->base(); + int size = memregion("nandrom")->bytes(); int numblocks = size / blocksize; m_strippedsize = numblocks * blocksize_stripped; @@ -908,6 +1083,8 @@ void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stri fclose(fp); } } + + m_has_nand = true; } void generalplus_gpac800_game_state::nand_init210() diff --git a/src/mame/drivers/wrlshunt.cpp b/src/mame/drivers/wrlshunt.cpp deleted file mode 100644 index e2c129169c6..00000000000 --- a/src/mame/drivers/wrlshunt.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz -/****************************************************************************** - - Wireless Hunting Video Game System skeleton driver - - System: Wireless Hunting Video Game System - Publisher: Hamy / Kids Station Toys Inc - Year: 2011 - ROM: FDI MSP55LV100G - RAM: Micron Technology 48LC8M16A2 - - Games: - Secret Mission - Predator - Delta Force - Toy Land - Dream Forest - Trophy Season - Freedom Force - Be Careful - Net Power - Open Training - Super Archer - Ultimate Frisbee - UFO Shooting - Happy Darts - Balloon Shoot - Avatair - Angry Pirate - Penguin War - Ghost Shooter - Duck Hunt - - - ROM Board: - Package: SO44 - Spacing: 1.27 mm - Width: 16.14 mm - Length: 27.78 mm - Voltage: 3V - Pinout: - - A25 A24 - | | - +--------------------------+ - A21 --|== # # `.__.' ==|-- A20 - A18 --|== ==|-- A19 - A17 --|== ==|-- A8 - A7 --|== ==|-- A9 - A6 --|== o ==|-- A10 - A5 --|== +----------------+ ==|-- A11 - A4 --|== | | ==|-- A12 - A3 --|== | MSP55LV100G | ==|-- A13 - A2 --|== | 0834 M02H | ==|-- A14 - A1 --|== | JAPAN | ==|-- A15 - A0 --|== | | ==|-- A16 - #CE --|== | | ==|-- A23 - GND --|== | | ==|-- A22 - #OE --|== | | ==|-- Q15 - Q0 --|== | | ==|-- Q7 - Q8 --|== | | ==|-- Q14 - Q1 --|== +----------------+ ==|-- Q6 - Q9 --|== ==|-- Q13 - Q2 --|== M55L100G ==|-- Q5 - Q10 --|== ==|-- Q12 - Q3 --|== ==|-- Q4 - Q11 --|== ==|-- VCC - +--------------------------+ - - The only interesting string in this ROM is SPF2ALP, - which is also found in the Wireless Air 60 ROM. - -*******************************************************************************/ - -#include "emu.h" - -#include "cpu/unsp/unsp.h" -#include "machine/spg2xx.h" - -#include "screen.h" -#include "speaker.h" - -class wrlshunt_state : public driver_device -{ -public: - wrlshunt_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_screen(*this, "screen") - , m_spg(*this, "spg") - { } - - void wrlshunt(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - - void mem_map(address_map &map); - - required_device m_maincpu; - required_device m_screen; - required_device m_spg; -}; - - -/************************************ - * - * Machine Hardware - * - ************************************/ - -void wrlshunt_state::machine_start() -{ -} - -void wrlshunt_state::machine_reset() -{ -} - -void wrlshunt_state::mem_map(address_map &map) -{ - map(0x008000, 0x00ffff).rom().region("maincpu", 0x10000); - map(0x000000, 0x007fff).m(m_spg, FUNC(spg_wh_device::map)); - map(0x040000, 0x07ffff).rom().region("maincpu", 0x106f000); -} - - -/************************************ - * - * Inputs - * - ************************************/ - -static INPUT_PORTS_START( wrlshunt ) -INPUT_PORTS_END - - -/************************************ - * - * Machine Configs - * - ************************************/ - -void wrlshunt_state::wrlshunt(machine_config &config) -{ - UNSP12(config, m_maincpu, XTAL(27'000'000)); - m_maincpu->set_addrmap(AS_PROGRAM, &wrlshunt_state::mem_map); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_size(320, 262); - m_screen->set_visarea(0, 320-1, 0, 240-1); - m_screen->set_screen_update("spg", FUNC(spg_wh_device::screen_update)); - m_screen->screen_vblank().set(m_spg, FUNC(spg_wh_device::vblank)); - - SPG_WH(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen); - - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - m_spg->add_route(ALL_OUTPUTS, "lspeaker", 0.5); - m_spg->add_route(ALL_OUTPUTS, "rspeaker", 0.5); -} - - -/************************************ - * - * ROM Loading - * - ************************************/ - -ROM_START( wrlshunt ) - ROM_REGION( 0x8000000, "maincpu", ROMREGION_ERASE00 ) - ROM_LOAD16_WORD_SWAP( "wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796) ) -ROM_END - -// valid looking code, but extended periperhal area (twice the size?) -CONS( 2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_state, empty_init, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )