summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2019-08-13 03:43:39 +0200
committer angelosa <lordkale4@gmail.com>2019-08-13 03:43:39 +0200
commit920d964b16da6f387ebc5edd4de8e121e0c9068c (patch)
tree80613dee9d6b739c4ae7da3fd8d36e708cb52b06
parent902c4589e9d4bd458c8a500133e2b7ba112dd511 (diff)
pce.cpp: add support for Tennokoe Bank extended Backup RAM [Angelo Salese]
-rw-r--r--hash/pce.xml1
-rw-r--r--src/devices/bus/pce/pce_rom.cpp98
-rw-r--r--src/devices/bus/pce/pce_rom.h31
-rw-r--r--src/devices/bus/pce/pce_slot.cpp3
-rw-r--r--src/devices/bus/pce/pce_slot.h3
-rw-r--r--src/mame/drivers/pce.cpp1
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)