pce.cpp: add support for Tennokoe Bank extended Backup RAM [Angelo Salese]

This commit is contained in:
angelosa 2019-08-13 03:43:39 +02:00
parent 902c4589e9
commit 920d964b16
6 changed files with 135 additions and 2 deletions

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -20,7 +20,8 @@ enum
PCE_CDSYS3J,
PCE_CDSYS3U,
PCE_POPULOUS,
PCE_SF2
PCE_SF2,
PCE_TENNOKOE
};

View File

@ -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)