From 998e733b5747e08c2a549c2476339ad703553f19 Mon Sep 17 00:00:00 2001 From: 0kmg <9137159+0kmg@users.noreply.github.com> Date: Fri, 16 Jul 2021 10:21:42 -0800 Subject: [PATCH] bus/nes: Added support for Caltron 9 in 1 prototype. - Also corrected Caltron 6 in 1 to more accurately reflect PCB behavior. Fixes the one game that wasn't working (Cosmos Cop). New working software list additions ----------------------------------- 9 in 1 (USA, prototype) --- hash/nes.xml | 17 ++++- src/devices/bus/nes/multigame.cpp | 111 +++++++++++++++++++++++++----- src/devices/bus/nes/multigame.h | 37 ++++++++-- src/devices/bus/nes/nes_carts.cpp | 1 + src/devices/bus/nes/nes_ines.hxx | 2 +- src/devices/bus/nes/nes_pcb.hxx | 1 + src/devices/bus/nes/nes_slot.h | 4 +- 7 files changed, 143 insertions(+), 30 deletions(-) diff --git a/hash/nes.xml b/hash/nes.xml index 72d4b956e58..ef31d14e47c 100644 --- a/hash/nes.xml +++ b/hash/nes.xml @@ -260,7 +260,7 @@ license:CC0 - + 6 in 1 (USA) 1992 Caltron @@ -53892,6 +53892,21 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx + + 9 in 1 (USA, prototype) + 1992 + Caltron + + + + + + + + + + + diff --git a/src/devices/bus/nes/multigame.cpp b/src/devices/bus/nes/multigame.cpp index e17df1eee70..9ec16b43064 100644 --- a/src/devices/bus/nes/multigame.cpp +++ b/src/devices/bus/nes/multigame.cpp @@ -29,7 +29,8 @@ //------------------------------------------------- DEFINE_DEVICE_TYPE(NES_ACTION52, nes_action52_device, "nes_action52", "NES Cart Action 52 PCB") -DEFINE_DEVICE_TYPE(NES_CALTRON6IN1, nes_caltron_device, "nes_caltron", "NES Cart Caltron 6 in 1 PCB") +DEFINE_DEVICE_TYPE(NES_CALTRON6IN1, nes_caltron6in1_device, "nes_caltron6in1", "NES Cart Caltron 6 in 1 PCB") +DEFINE_DEVICE_TYPE(NES_CALTRON9IN1, nes_caltron9in1_device, "nes_caltron9in1", "NES Cart Caltron 9 in 1 PCB") DEFINE_DEVICE_TYPE(NES_RUMBLESTATION, nes_rumblestat_device, "nes_rumblestat", "NES Cart Rumblestation PCB") DEFINE_DEVICE_TYPE(NES_SVISION16, nes_svision16_device, "nes_svision16", "NES Cart Supervision 16 in 1 PCB") DEFINE_DEVICE_TYPE(NES_KN42, nes_kn42_device, "nes_kn42", "NES Cart KN-42 PCB") @@ -89,8 +90,13 @@ nes_action52_device::nes_action52_device(const machine_config &mconfig, const ch { } -nes_caltron_device::nes_caltron_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_nrom_device(mconfig, NES_CALTRON6IN1, tag, owner, clock), m_latch(0) +nes_caltron6in1_device::nes_caltron6in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_CALTRON6IN1, tag, owner, clock), m_latch(0), m_reg(0) +{ +} + +nes_caltron9in1_device::nes_caltron9in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_CALTRON9IN1, tag, owner, clock) { } @@ -369,19 +375,34 @@ void nes_action52_device::pcb_reset() chr8(0, m_chr_source); } -void nes_caltron_device::device_start() +void nes_caltron6in1_device::device_start() +{ + common_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_reg)); +} + +void nes_caltron6in1_device::pcb_reset() +{ + prg32(0); + chr8(0, CHRROM); + + m_latch = 0; + m_reg = 0; +} + +void nes_caltron9in1_device::device_start() { common_start(); save_item(NAME(m_latch)); } -void nes_caltron_device::pcb_reset() +void nes_caltron9in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg32(0); - chr8(0, m_chr_source); + chr8(0, CHRROM); - m_latch = 0; + m_latch[0] = m_latch[1] = m_latch[2] = 0; } void nes_rumblestat_device::device_start() @@ -1118,25 +1139,77 @@ void nes_action52_device::write_h(offs_t offset, uint8_t data) iNES: mapper 41 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ -void nes_caltron_device::write_m(offs_t offset, uint8_t data) +void nes_caltron6in1_device::update_chr() { - LOG_MMC(("caltron write_m, offset: %04x, data: %02x\n", offset, data)); - - m_latch = offset & 0xff; - set_nt_mirroring(BIT(data, 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - prg32(offset & 0x07); + chr8(((m_latch >> 1) & 0x0c) | m_reg, CHRROM); } -void nes_caltron_device::write_h(offs_t offset, uint8_t data) +void nes_caltron6in1_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("caltron write_h, offset: %04x, data: %02x\n", offset, data)); + LOG_MMC(("caltron6in1 write_m, offset: %04x, data: %02x\n", offset, data)); + + switch (offset & 0x1800) + { + case 0x0000: + m_latch = offset & 0x3f; + prg32(offset & 0x07); + update_chr(); + set_nt_mirroring(BIT(offset, 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + break; + } +} + +void nes_caltron6in1_device::write_h(offs_t offset, u8 data) +{ + LOG_MMC(("caltron6in1 write_h, offset: %04x, data: %02x\n", offset, data)); + + // this pcb is subject to bus conflict + data = account_bus_conflict(offset, data); + + if (BIT(m_latch, 2)) + { + m_reg = data & 0x03; + update_chr(); + } +} + +/*------------------------------------------------- + + Caltron 9 in 1 Board + + Games: 9 in 1 by Caltron + + NES 2.0: mapper 389 + + In MAME: Supported. + + -------------------------------------------------*/ + +void nes_caltron9in1_device::write_h(offs_t offset, u8 data) +{ + LOG_MMC(("caltron9in1 write_h, offset: %04x, data: %02x\n", offset, data)); + int nibble = (offset >> 12) & 0x07; + m_latch[std::min(nibble, 2)] = offset & 0x7f; + + if (BIT(m_latch[1], 1)) + { + u8 outer = (m_latch[0] >> 2) & ~0x03; + u8 inner = (m_latch[2] >> 2) & 0x03; + prg16_89ab(outer | inner); + prg16_cdef(outer | 0x03); + } + else + prg32(m_latch[0] >> 3); + + if (nibble) + chr8(((m_latch[1] >> 1) & 0x1c) | (m_latch[2] & 0x03), CHRROM); + else + set_nt_mirroring(BIT(m_latch[0], 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - if (m_latch & 0x04) - chr8(((m_latch & 0x18) >> 1) | (data & 0x03), CHRROM); } /*------------------------------------------------- diff --git a/src/devices/bus/nes/multigame.h b/src/devices/bus/nes/multigame.h index e7d0ccdb64e..bb06032877d 100644 --- a/src/devices/bus/nes/multigame.h +++ b/src/devices/bus/nes/multigame.h @@ -26,16 +26,16 @@ protected: }; -// ======================> nes_caltron_device +// ======================> nes_caltron6in1_device -class nes_caltron_device : public nes_nrom_device +class nes_caltron6in1_device : public nes_nrom_device { public: // construction/destruction - nes_caltron_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_caltron6in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - virtual void write_m(offs_t offset, uint8_t data) override; - virtual void write_h(offs_t offset, uint8_t data) override; + virtual void write_m(offs_t offset, u8 data) override; + virtual void write_h(offs_t offset, u8 data) override; virtual void pcb_reset() override; @@ -44,7 +44,29 @@ protected: virtual void device_start() override; private: - uint8_t m_latch; + void update_chr(); + u8 m_latch, m_reg; +}; + + +// ======================> nes_caltron9in1_device + +class nes_caltron9in1_device : public nes_nrom_device +{ +public: + // construction/destruction + nes_caltron9in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void write_h(offs_t offset, u8 data) override; + + virtual void pcb_reset() override; + +protected: + // device-level overrides + virtual void device_start() override; + +private: + u8 m_latch[3]; }; @@ -1044,7 +1066,8 @@ public: // device type definition DECLARE_DEVICE_TYPE(NES_ACTION52, nes_action52_device) -DECLARE_DEVICE_TYPE(NES_CALTRON6IN1, nes_caltron_device) +DECLARE_DEVICE_TYPE(NES_CALTRON6IN1, nes_caltron6in1_device) +DECLARE_DEVICE_TYPE(NES_CALTRON9IN1, nes_caltron9in1_device) DECLARE_DEVICE_TYPE(NES_RUMBLESTATION, nes_rumblestat_device) DECLARE_DEVICE_TYPE(NES_SVISION16, nes_svision16_device) DECLARE_DEVICE_TYPE(NES_KN42, nes_kn42_device) diff --git a/src/devices/bus/nes/nes_carts.cpp b/src/devices/bus/nes/nes_carts.cpp index 0859084d0fe..50971237e12 100644 --- a/src/devices/bus/nes/nes_carts.cpp +++ b/src/devices/bus/nes/nes_carts.cpp @@ -350,6 +350,7 @@ void nes_cart(device_slot_interface &device) device.option_add_internal("benshieng", NES_BENSHIENG); device.option_add_internal("action52", NES_ACTION52); device.option_add_internal("caltron6in1", NES_CALTRON6IN1); + device.option_add_internal("caltron9in1", NES_CALTRON9IN1); device.option_add_internal("maxi15", NES_MAXI15); // mapper 234 device.option_add_internal("rumblestation", NES_RUMBLESTATION); // mapper 46 device.option_add_internal("svision16", NES_SVISION16); // mapper 53 diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx index 2233ab9ae45..9d0b829d465 100644 --- a/src/devices/bus/nes/nes_ines.hxx +++ b/src/devices/bus/nes/nes_ines.hxx @@ -424,7 +424,7 @@ static const nes_mmc mmc_list[] = // 386 JY-090 multicart // 387 various JY multicarts // 388 various JY multicarts - // { 389, CALTRON_9IN1 }, + { 389, CALTRON_9IN1 }, // 390 variant of mapper 236? // 391 BS-110 MMC3 clone // 392 8-in-1 variant of mc_sv16 diff --git a/src/devices/bus/nes/nes_pcb.hxx b/src/devices/bus/nes/nes_pcb.hxx index 6867b2192c0..37727c91e2f 100644 --- a/src/devices/bus/nes/nes_pcb.hxx +++ b/src/devices/bus/nes/nes_pcb.hxx @@ -236,6 +236,7 @@ static const nes_pcb pcb_list[] = { "benshieng", BMC_BENSHIENG }, { "action52", ACTENT_ACT52 }, { "caltron6in1", CALTRON_6IN1 }, + { "caltron9in1", CALTRON_9IN1 }, { "rumblestation", RUMBLESTATION_BOARD }, // mapper 46 { "svision16", SVISION16_BOARD }, { "kn42", UNL_KN42 }, diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index 2ac512a675c..f828fe842db 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -43,8 +43,8 @@ enum BANDAI_FJUMP2, BANDAI_PT554, BANDAI_DATACH, BANDAI_KARAOKE, BANDAI_OEKAKIDS, BANDAI_FCG, BANDAI_LZ93, BANDAI_LZ93EX1, BANDAI_LZ93EX2, - /* Caltron */ - CALTRON_6IN1, + // Caltron + CALTRON_6IN1, CALTRON_9IN1, /* Camerica */ CAMERICA_BF9093, CAMERICA_BF9096, CAMERICA_ALADDIN, CAMERICA_GOLDENFIVE, GG_NROM,