diff options
-rw-r--r-- | hash/pce.xml | 1 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_rom.cpp | 98 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_rom.h | 31 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_slot.cpp | 3 | ||||
-rw-r--r-- | src/devices/bus/pce/pce_slot.h | 3 | ||||
-rw-r--r-- | src/mame/drivers/pce.cpp | 1 |
6 files changed, 135 insertions, 2 deletions
diff --git a/hash/pce.xml b/hash/pce.xml index 55c7846356a..e59d80ac62f 100644 --- a/hash/pce.xml +++ b/hash/pce.xml @@ -3882,6 +3882,7 @@ <publisher>Hudson</publisher> <info name="release" value="19910906"/> <part name="cart" interface="pce_cart"> + <feature name="slot" value="tennokoe" /> <dataarea name="rom" size="131072"> <rom name="tennokoe bank (japan).pce" size="131072" crc="3b3808bd" sha1="8ade1c698e0cb96ce3ed01986c7e5268aa5a1451" offset="000000" /> </dataarea> diff --git a/src/devices/bus/pce/pce_rom.cpp b/src/devices/bus/pce/pce_rom.cpp index ac837917a34..0af70e60388 100644 --- a/src/devices/bus/pce/pce_rom.cpp +++ b/src/devices/bus/pce/pce_rom.cpp @@ -20,7 +20,8 @@ DEFINE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device, "pce_rom", "PCE/TG16 Carts") DEFINE_DEVICE_TYPE(PCE_ROM_CDSYS3, pce_cdsys3_device, "pce_cdsys3", "PCE/TG16 CD-System Cart v3.00") DEFINE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device, "pce_populous", "PCE Populous Cart") -DEFINE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device, "pce_sf2", "PCE Street Fighters 2 Cart") +DEFINE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device, "pce_sf2", "PCE Street Fighter 2 CE Cart") +DEFINE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device, "pce_tennokoe", "PCE Tennokoe Bank Cart") pce_rom_device::pce_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) @@ -49,6 +50,12 @@ pce_sf2_device::pce_sf2_device(const machine_config &mconfig, const char *tag, d { } +pce_tennokoe_device::pce_tennokoe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : pce_rom_device(mconfig, PCE_ROM_TENNOKOE, tag, owner, clock), + device_nvram_interface(mconfig, *this) +{ +} + //------------------------------------------------- // mapper specific start/reset @@ -65,7 +72,54 @@ void pce_sf2_device::device_reset() m_bank_base = 0; } +void pce_tennokoe_device::device_start() +{ + save_item(NAME(m_bram)); + save_item(NAME(m_bram_locked)); +} + +void pce_tennokoe_device::device_reset() +{ + m_bram_locked = 1; +} + +// Tennokoe Bank is a special HuCard containing x4 Backup RAM banks, +// the software can transfer +void pce_tennokoe_device::nvram_default() +{ + memset(m_bram, 0xff, m_bram_size); + // easter egg: load copy of a BRAM (debug leftover?) inside bank 4. + // Contains 14 save blocks, mostly at the end of the various games. + // Not entirely correct but not incorrect as well to just unlock these saves for public use, + // for testing reasons and for a slim chance of actually be supposed as default data in the bank(s) + // File list: + // 001 NEUTOPIA1 + // 002 MOTURBO-1 + // 003 MOMODE2-1 + // 004 MOMOKATSU. + // 005 BOMBERMAN1 + // 006 POPULOUS. + // 007 ADVENTURE1 (Starts in HuMan form at the village with 983040 gold, basically before the last dungeon); + // 008 TENGAI1 + // 009 COBRA1 + // 010 YS.DATA.01 (right before the switch between Ys 1 and 2, read book to move on); + // 011 YS.DATA.02 + // 012 YS3.DAT.01 (right before the end, go to the right bridge for the ending); + // 013 URUSEI1 + // 014 MITUBATI1 + // TODO: document the other saves. + memcpy(m_bram + 0x1800, m_rom + 0x8800, 0x800); +} + +void pce_tennokoe_device::nvram_read(emu_file &file) +{ + file.read(m_bram, m_bram_size); +} +void pce_tennokoe_device::nvram_write(emu_file &file) +{ + file.write(m_bram, m_bram_size); +} /*------------------------------------------------- mapper specific handlers @@ -123,3 +177,45 @@ WRITE8_MEMBER(pce_sf2_device::write_cart) if (offset >= 0x1ff0 && offset < 0x1ff4) m_bank_base = offset & 3; } + +READ8_MEMBER(pce_tennokoe_device::read_cart) +{ + switch((offset & 0xf0000) >> 16) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return m_rom[offset]; + case 8: + if (m_bram_locked) + return 0xff; + else + return m_bram[offset & (m_bram_size-1)]; + } + + logerror("tennokoe: ROM reading at %06x\n",offset); + return 0xff; +} + +WRITE8_MEMBER(pce_tennokoe_device::write_cart) +{ + switch((offset & 0xf0000) >> 16) + { + case 8: + if(!m_bram_locked) + m_bram[offset & (m_bram_size-1)] = data; + break; + case 0xf: + // TODO: lock/unlock mechanism is a complete guess, needs real HW study + // (writes to ports $c0000, $d0000, $f0000) + m_bram_locked = (data == 0); + default: + logerror("tennokoe: ROM writing at %06x %02x\n",offset,data); + break; + } +} diff --git a/src/devices/bus/pce/pce_rom.h b/src/devices/bus/pce/pce_rom.h index addbfc1fa3e..82122462d03 100644 --- a/src/devices/bus/pce/pce_rom.h +++ b/src/devices/bus/pce/pce_rom.h @@ -6,6 +6,7 @@ #pragma once #include "pce_slot.h" +#include "machine/nvram.h" // ======================> pce_rom_device @@ -77,11 +78,41 @@ private: uint8_t m_bank_base; }; +// ======================> pce_tennokoe_device + +class pce_tennokoe_device : public pce_rom_device, + public device_nvram_interface +{ +public: + // construction/destruction + pce_tennokoe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_cart) override; + virtual DECLARE_WRITE8_MEMBER(write_cart) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void nvram_default() override; + virtual void nvram_read(emu_file &file) override; + virtual void nvram_write(emu_file &file) override; + +private: + const uint32_t m_bram_size = 0x800*4; + uint8_t m_bram[0x800*4]; + + uint8_t m_bram_locked; +}; + // device type definition DECLARE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device) DECLARE_DEVICE_TYPE(PCE_ROM_CDSYS3, pce_cdsys3_device) DECLARE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device) DECLARE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device) +DECLARE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device) + #endif // MAME_BUS_PCE_PCE_ROM_H diff --git a/src/devices/bus/pce/pce_slot.cpp b/src/devices/bus/pce/pce_slot.cpp index 912a8cf8c59..2a238d0eb15 100644 --- a/src/devices/bus/pce/pce_slot.cpp +++ b/src/devices/bus/pce/pce_slot.cpp @@ -181,6 +181,7 @@ static const pce_slot slot_list[] = { PCE_CDSYS3J, "cdsys3j" }, { PCE_POPULOUS, "populous" }, { PCE_SF2, "sf2" }, + { PCE_TENNOKOE, "tennokoe" }, }; static int pce_get_pcb_id(const char *slot) @@ -306,6 +307,8 @@ int pce_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len) if (!memcmp(ROM + 0x29d1, "VER. 3.", 7)) { type = PCE_CDSYS3J; } // JP version else if (!memcmp(ROM + 0x29c4, "VER. 3.", 7 )) { type = PCE_CDSYS3U; } // US version } + + // TODO: type for TENNOKOE, "Kei's" string at bottom? return type; } diff --git a/src/devices/bus/pce/pce_slot.h b/src/devices/bus/pce/pce_slot.h index add982a534b..53d690cc4ce 100644 --- a/src/devices/bus/pce/pce_slot.h +++ b/src/devices/bus/pce/pce_slot.h @@ -20,7 +20,8 @@ enum PCE_CDSYS3J, PCE_CDSYS3U, PCE_POPULOUS, - PCE_SF2 + PCE_SF2, + PCE_TENNOKOE }; diff --git a/src/mame/drivers/pce.cpp b/src/mame/drivers/pce.cpp index 29b365e6443..974deae34ac 100644 --- a/src/mame/drivers/pce.cpp +++ b/src/mame/drivers/pce.cpp @@ -303,6 +303,7 @@ static void pce_cart(device_slot_interface &device) device.option_add_internal("cdsys3j", PCE_ROM_CDSYS3); device.option_add_internal("populous", PCE_ROM_POPULOUS); device.option_add_internal("sf2", PCE_ROM_SF2); + device.option_add_internal("tennokoe", PCE_ROM_TENNOKOE); } void pce_state::pce_common(machine_config &config) |