From e1676a4818c8aa2d24976fc994280d1ba2990fe2 Mon Sep 17 00:00:00 2001 From: 0kmg <9137159+0kmg@users.noreply.github.com> Date: Mon, 4 Oct 2021 09:44:40 -0800 Subject: [PATCH] bus/nes: Added MMC1 variant board SZROM. (#8658) This fixes corrupt (NVRAM) save games for A Ressha de Ikou, the only known game to use this board. --- hash/nes.xml | 2 +- src/devices/bus/nes/mmc1.cpp | 35 +++++++++++++++++++++++++++++++ src/devices/bus/nes/mmc1.h | 17 +++++++++++++++ src/devices/bus/nes/nes_carts.cpp | 1 + src/devices/bus/nes/nes_ines.hxx | 8 +++++++ src/devices/bus/nes/nes_pcb.hxx | 1 + src/devices/bus/nes/nes_slot.h | 2 +- 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/hash/nes.xml b/hash/nes.xml index b50a928d050..ba617a15d11 100644 --- a/hash/nes.xml +++ b/hash/nes.xml @@ -44502,7 +44502,7 @@ Also notice that VRAM, WRAM & mirror are probably incorrect for some of these se - + diff --git a/src/devices/bus/nes/mmc1.cpp b/src/devices/bus/nes/mmc1.cpp index 8c8e7bc31bd..bfd2992d0a8 100644 --- a/src/devices/bus/nes/mmc1.cpp +++ b/src/devices/bus/nes/mmc1.cpp @@ -41,6 +41,7 @@ DEFINE_DEVICE_TYPE(NES_SXROM, nes_sxrom_device, "nes_sxrom", "NES Cart SxROM (MMC-1) PCB") DEFINE_DEVICE_TYPE(NES_SOROM, nes_sorom_device, "nes_sorom", "NES Cart SOROM (MMC-1) PCB") +DEFINE_DEVICE_TYPE(NES_SZROM, nes_szrom_device, "nes_szrom", "NES Cart SZROM (MMC-1) PCB") @@ -59,6 +60,11 @@ nes_sorom_device::nes_sorom_device(const machine_config &mconfig, const char *ta { } +nes_szrom_device::nes_szrom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_sxrom_device(mconfig, NES_SZROM, tag, owner, clock) +{ +} + void nes_sxrom_device::device_start() @@ -313,3 +319,32 @@ uint8_t nes_sorom_device::read_m(offs_t offset) return get_open_bus(); } + +// SZROM has two RAM banks, the first is not battery backed up, the second is. +void nes_szrom_device::write_m(offs_t offset, u8 data) +{ + LOG_MMC(("szrom write_m, offset: %04x, data: %02x\n", offset, data)); + + if (!BIT(m_reg[3], 4) || m_mmc1_type == mmc1_type::MMC1A) // WRAM enabled + { + if (BIT(m_reg[BIT(m_reg[0], 4) + 1], 4)) + m_battery[offset & (m_battery.size() - 1)] = data; + else + m_prgram[offset & (m_prgram.size() - 1)] = data; + } +} + +u8 nes_szrom_device::read_m(offs_t offset) +{ + LOG_MMC(("szrom read_m, offset: %04x\n", offset)); + + if (!BIT(m_reg[3], 4) || m_mmc1_type == mmc1_type::MMC1A) // WRAM enabled + { + if (BIT(m_reg[BIT(m_reg[0], 4) + 1], 4)) + return m_battery[offset & (m_battery.size() - 1)]; + else + return m_prgram[offset & (m_prgram.size() - 1)]; + } + + return get_open_bus(); +} diff --git a/src/devices/bus/nes/mmc1.h b/src/devices/bus/nes/mmc1.h index dbf234f734f..c55a42cf87c 100644 --- a/src/devices/bus/nes/mmc1.h +++ b/src/devices/bus/nes/mmc1.h @@ -43,6 +43,9 @@ protected: int m_count; }; + +// ======================> nes_sorom_device + class nes_sorom_device : public nes_sxrom_device { public: @@ -54,8 +57,22 @@ public: }; +// ======================> nes_szrom_device + +class nes_szrom_device : public nes_sxrom_device +{ +public: + // construction/destruction + nes_szrom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual u8 read_m(offs_t offset) override; + virtual void write_m(offs_t offset, u8 data) override; +}; + + // device type definition DECLARE_DEVICE_TYPE(NES_SXROM, nes_sxrom_device) DECLARE_DEVICE_TYPE(NES_SOROM, nes_sorom_device) +DECLARE_DEVICE_TYPE(NES_SZROM, nes_szrom_device) #endif // MAME_BUS_NES_MMC1_H diff --git a/src/devices/bus/nes/nes_carts.cpp b/src/devices/bus/nes/nes_carts.cpp index 380e87aceb0..d42ecd514c4 100644 --- a/src/devices/bus/nes/nes_carts.cpp +++ b/src/devices/bus/nes/nes_carts.cpp @@ -101,6 +101,7 @@ void nes_cart(device_slot_interface &device) // SxROM device.option_add_internal("sxrom", NES_SXROM); device.option_add_internal("sorom", NES_SOROM); + device.option_add_internal("szrom", NES_SZROM); // TxROM device.option_add_internal("txrom", NES_TXROM); // HKROM diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx index 0c8ce115178..5f8868085c7 100644 --- a/src/devices/bus/nes/nes_ines.hxx +++ b/src/devices/bus/nes/nes_ines.hxx @@ -798,6 +798,8 @@ void nes_cart_slot_device::call_load_ines() break; case STD_SXROM: + if (mapper == 1 && ines20 && prgram_size == 0x2000 && battery_size == 0x2000 && vrom_size == 0x4000) + m_pcb_id = STD_SZROM; if (mapper == 155) m_cart->set_mmc1_type(device_nes_cart_interface::mmc1_type::MMC1A); break; @@ -1219,6 +1221,12 @@ const char * nes_cart_slot_device::get_default_card_ines(get_default_card_softwa pcb_id = STD_NROM368; break; + case STD_SXROM: + // only A Ressha de Ikou uses SZROM and it can be detected by its profile: 8K WRAM, 8K BWRAM, 16K CHR ROM + if (mapper == 1 && ines20 && ROM[10] == 0x77 && ROM[5] == 2) + pcb_id = STD_SZROM; + break; + case KONAMI_VRC2: if (mapper == 23 && crc_hack && !submapper) pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset diff --git a/src/devices/bus/nes/nes_pcb.hxx b/src/devices/bus/nes/nes_pcb.hxx index cbf56bce160..e1186988144 100644 --- a/src/devices/bus/nes/nes_pcb.hxx +++ b/src/devices/bus/nes/nes_pcb.hxx @@ -32,6 +32,7 @@ static const nes_pcb pcb_list[] = { "un1rom", STD_UN1ROM }, { "sxrom", STD_SXROM }, { "sorom", STD_SOROM }, + { "szrom", STD_SZROM }, { "txrom", STD_TXROM }, { "hkrom", STD_HKROM }, { "tqrom", STD_TQROM }, diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index e33e545ec08..5c6013e8f8a 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -23,7 +23,7 @@ enum STD_CNROM, STD_CPROM, STD_EXROM, STD_FXROM, STD_GXROM, STD_HKROM, STD_PXROM, - STD_SXROM, STD_SOROM, + STD_SXROM, STD_SOROM, STD_SZROM, STD_TXROM, STD_TXSROM, STD_TKROM, STD_TQROM, STD_UXROM, STD_UN1ROM, UXROM_CC, HVC_FAMBASIC, NES_QJ, PAL_ZZ, STD_EVENT,