summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes/mmc3_clones.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nes/mmc3_clones.cpp')
-rw-r--r--src/devices/bus/nes/mmc3_clones.cpp3241
1 files changed, 2157 insertions, 1084 deletions
diff --git a/src/devices/bus/nes/mmc3_clones.cpp b/src/devices/bus/nes/mmc3_clones.cpp
index 9be591c7d9f..0fc9b3c1c93 100644
--- a/src/devices/bus/nes/mmc3_clones.cpp
+++ b/src/devices/bus/nes/mmc3_clones.cpp
@@ -14,14 +14,14 @@
#include "emu.h"
#include "mmc3_clones.h"
+#define LOG_HIFREQ (1U << 1)
#ifdef NES_PCB_DEBUG
-#define VERBOSE 1
+#define VERBOSE (LOG_GENERAL)
#else
-#define VERBOSE 0
+#define VERBOSE (0)
#endif
-
-#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
+#include "logmacro.h"
//-------------------------------------------------
@@ -29,12 +29,15 @@
//-------------------------------------------------
DEFINE_DEVICE_TYPE(NES_NITRA, nes_nitra_device, "nes_nitra", "NES Cart Nitra PCB")
-DEFINE_DEVICE_TYPE(NES_KS7057, nes_ks7057_device, "nes_ks7057", "NES Cart KS-7057 PCB")
+DEFINE_DEVICE_TYPE(NES_BMW8544, nes_bmw8544_device, "nes_bmw8544", "NES Cart BMW8544 PCB")
+DEFINE_DEVICE_TYPE(NES_FS6, nes_fs6_device, "nes_fs6", "NES Cart Fight Street VI PCB")
DEFINE_DEVICE_TYPE(NES_SBROS11, nes_sbros11_device, "nes_smb11", "NES Cart SMB 11 PCB")
-DEFINE_DEVICE_TYPE(NES_MALISB, nes_malisb_device, "nes_malisb", "NES Cart Mali Spash Bomb PCB")
-DEFINE_DEVICE_TYPE(NES_FAMILY4646, nes_family4646_device, "nes_family4646", "NES Cart BMC-FAMILY04646 PCB")
+DEFINE_DEVICE_TYPE(NES_MALISB, nes_malisb_device, "nes_malisb", "NES Cart Mali Splash Bomb PCB")
+DEFINE_DEVICE_TYPE(NES_FAMILY4646, nes_family4646_device, "nes_family4646", "NES Cart BMC-FAMILY4646 PCB")
DEFINE_DEVICE_TYPE(NES_PIKAY2K, nes_pikay2k_device, "nes_pikay2k", "NES Cart PIKACHU Y2K PCB")
DEFINE_DEVICE_TYPE(NES_8237, nes_8237_device, "nes_8237", "NES Cart UNL-8237 PCB")
+DEFINE_DEVICE_TYPE(NES_8237A, nes_8237a_device, "nes_8237a", "NES Cart UNL-8237A PCB")
+DEFINE_DEVICE_TYPE(NES_158B, nes_158b_device, "nes_158b", "NES Cart UNL-158B PCB")
DEFINE_DEVICE_TYPE(NES_SG_LIONK, nes_sglionk_device, "nes_sglionk", "NES Cart SuperGame Lion King PCB")
DEFINE_DEVICE_TYPE(NES_SG_BOOG, nes_sgboog_device, "nes_sgbooger", "NES Cart SuperGame BoogerMan PCB")
DEFINE_DEVICE_TYPE(NES_KASING, nes_kasing_device, "nes_kasing", "NES Cart Kasing PCB")
@@ -45,48 +48,141 @@ DEFINE_DEVICE_TYPE(NES_TXC_TW, nes_txc_tw_device, "nes_txc_tw",
DEFINE_DEVICE_TYPE(NES_KOF97, nes_kof97_device, "nes_kof97", "NES Cart KoF 97 PCB")
DEFINE_DEVICE_TYPE(NES_KOF96, nes_kof96_device, "nes_kof96", "NES Cart KoF 96 PCB")
DEFINE_DEVICE_TYPE(NES_SF3, nes_sf3_device, "nes_sf3", "NES Cart Super Fighter III PCB")
+DEFINE_DEVICE_TYPE(NES_COCOMA, nes_cocoma_device, "nes_cocoma", "NES Cart Cocoma Core Pro PCB")
DEFINE_DEVICE_TYPE(NES_GOUDER, nes_gouder_device, "nes_gouder", "NES Cart Gouder PCB")
DEFINE_DEVICE_TYPE(NES_SA9602B, nes_sa9602b_device, "nes_sa9602b", "NES Cart SA-9602B PCB")
DEFINE_DEVICE_TYPE(NES_SACHEN_SHERO, nes_sachen_shero_device, "nes_shero", "NES Cart Street Hero PCB")
-//DEFINE_DEVICE_TYPE(NES_A9746, nes_a9746_device, "nes_bmc_a9746", "NES Cart A-9746 PCB")
-
-DEFINE_DEVICE_TYPE(NES_FK23C, nes_fk23c_device, "nes_kf23c", "NES Cart KF23C PCB")
-DEFINE_DEVICE_TYPE(NES_FK23CA, nes_fk23ca_device, "nes_kf23ca", "NES Cart KF23CA PCB")
+DEFINE_DEVICE_TYPE(NES_SACHEN_ZGDH, nes_sachen_zgdh_device, "nes_zgdh", "NES Cart Zhongguo Daheng PCB")
+DEFINE_DEVICE_TYPE(NES_A9746, nes_a9746_device, "nes_bmc_a9746", "NES Cart A-9746 PCB")
+
+DEFINE_DEVICE_TYPE(NES_A88S1, nes_a88s1_device, "nes_a88s1", "NES Cart BMC A88S-1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_EL86XC, nes_bmc_el86xc_device, "nes_bmc_el86xc", "NES Cart BMC EL860947C/EL861121C PCB")
+DEFINE_DEVICE_TYPE(NES_FK23C, nes_fk23c_device, "nes_fk23c", "NES Cart FK23C PCB")
+DEFINE_DEVICE_TYPE(NES_FK23CA, nes_fk23ca_device, "nes_fk23ca", "NES Cart FK23CA PCB")
+DEFINE_DEVICE_TYPE(NES_NT639, nes_nt639_device, "nes_nt639", "NES Cart NT-639 PCB")
+DEFINE_DEVICE_TYPE(NES_RESETTXROM, nes_resettxrom_device, "nes_resettxrom", "NES Cart BMC RESET-TXROM PCB")
DEFINE_DEVICE_TYPE(NES_S24IN1SC03, nes_s24in1sc03_device, "nes_s24in1c03", "NES Cart Super 24 in 1 SC-03 PCB")
+DEFINE_DEVICE_TYPE(NES_TECHLINE9IN1, nes_tech9in1_device, "nes_tech9in1", "NES Cart Techline 9 in 1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_5IN1, nes_bmc_5in1_device, "nes_bmc_5in1", "NES Cart BMC 5 in 1 1993 Copyright PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_8IN1, nes_bmc_8in1_device, "nes_bmc_8in1", "NES Cart BMC GRM070 8 in 1 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_15IN1, nes_bmc_15in1_device, "nes_bmc_15in1", "NES Cart BMC 15 in 1 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_SBIG7, nes_bmc_sbig7_device, "nes_bmc_sbig7", "NES Cart BMC Super BIG 7 in 1 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_HIK8, nes_bmc_hik8_device, "nes_bmc_hik8", "NES Cart BMC HIK 8 in 1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_JY208, nes_bmc_jy208_device, "nes_bmc_jy208", "NES Cart BMC JY-208 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_JY302, nes_bmc_jy302_device, "nes_bmc_jy302", "NES Cart BMC JY-302 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_KC885, nes_bmc_kc885_device, "nes_bmc_kc885", "NES Cart BMC KC885 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_SFC12, nes_bmc_sfc12_device, "nes_bmc_sfc12", "NES Cart BMC SFC-12 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_HIK4, nes_bmc_hik4_device, "nes_bmc_hik4", "NES Cart BMC HIK 4 in 1 PCB")
-DEFINE_DEVICE_TYPE(NES_BMC_MARIO7IN1, nes_bmc_mario7in1_device, "nes_bmc_mario7in1", "NES Cart BMC Mario 7 in 1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_F15, nes_bmc_f15_device, "nes_bmc_f15", "NES Cart BMC F-15 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_F600, nes_bmc_f600_device, "nes_bmc_f600", "NES Cart BMC F600 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_GN45, nes_bmc_gn45_device, "nes_bmc_gn45", "NES Cart BMC GN-45 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_GOLD7IN1, nes_bmc_gold7in1_device, "nes_bmc_gold7in1", "NES Cart BMC Golden 7 in 1 PCB")
-DEFINE_DEVICE_TYPE(NES_BMC_GC6IN1, nes_bmc_gc6in1_device, "nes_bmc_gc6in1", "NES Cart BMC Golden Card 6 in 1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_K3006, nes_bmc_k3006_device, "nes_bmc_k3006", "NES Cart BMC K-3006 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_K3033, nes_bmc_k3033_device, "nes_bmc_k3033", "NES Cart BMC K-3033 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_L6IN1, nes_bmc_l6in1_device, "nes_bmc_l6in1", "NES Cart BMC L6IN1 PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_00202650, nes_bmc_00202650_device, "nes_bmc_00202650", "NES Cart BMC 00202650 PCB")
DEFINE_DEVICE_TYPE(NES_BMC_411120C, nes_bmc_411120c_device, "nes_bmc_411120c", "NES Cart BMC 411120C PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_810305C, nes_bmc_810305c_device, "nes_bmc_810305c", "NES Cart BMC 81-03-05-C PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_820720C, nes_bmc_820720c_device, "nes_bmc_820720c", "NES Cart BMC 820720C PCB")
DEFINE_DEVICE_TYPE(NES_BMC_830118C, nes_bmc_830118c_device, "nes_bmc_830118c", "NES Cart BMC 830118C PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_830832C, nes_bmc_830832c_device, "nes_bmc_830832c", "NES Cart BMC 830832C PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_YY841101C, nes_bmc_yy841101c_device, "nes_bmc_yy841101c", "NES Cart BMC YY841101C PCB")
+DEFINE_DEVICE_TYPE(NES_BMC_YY841155C, nes_bmc_yy841155c_device, "nes_bmc_yy841155c", "NES Cart BMC YY841155C PCB")
DEFINE_DEVICE_TYPE(NES_PJOY84, nes_pjoy84_device, "nes_pjoy84", "NES Cart Powerjoy 84 PCB")
-DEFINE_DEVICE_TYPE(NES_COOLBOY, nes_coolboy_device, "nes_coolboy", "NES Cart CoolBoy PCB")
+DEFINE_DEVICE_TYPE(NES_SMD133, nes_smd133_device, "nes_smd133", "NES Cart SMD133 PCB")
+
+
+INPUT_PORTS_START( sachen_shero )
+ PORT_START("JUMPER")
+ PORT_CONFNAME( 0x80, 0x00, "Title Screen" )
+ PORT_CONFSETTING( 0x00, "Street Heroes" )
+ PORT_CONFSETTING( 0x80, u8"\u4f8d\u9b42 (Shìhún)" ) // 侍魂
+INPUT_PORTS_END
+
+INPUT_PORTS_START( bmc_5in1 )
+ PORT_START("JUMPER")
+ PORT_CONFNAME( 0x01, 0x01, "Menu Type" )
+ PORT_CONFSETTING( 0x00, "20 in 1" )
+ PORT_CONFSETTING( 0x01, "5 in 1" )
+INPUT_PORTS_END
+
+INPUT_PORTS_START( bmc_f600 )
+ PORT_START("JUMPER")
+ PORT_CONFNAME( 0x80, 0x80, "Menu Type" )
+ PORT_CONFSETTING( 0x00, "Mario 67 in 1" )
+ PORT_CONFSETTING( 0x80, "Mario Party II (6 in 1)" )
+INPUT_PORTS_END
+
+INPUT_PORTS_START( bmc_kc885 )
+ PORT_START("JUMPER")
+ PORT_CONFNAME( 0x07, 0x07, "Menu Type" )
+ PORT_CONFSETTING( 0x00, "6000 in 1" )
+ PORT_CONFSETTING( 0x01, "400 in 1" )
+ PORT_CONFSETTING( 0x02, "800 in 1" )
+ PORT_CONFSETTING( 0x03, "5000 in 1" )
+ PORT_CONFSETTING( 0x04, "190 in 1" )
+ PORT_CONFSETTING( 0x05, "1000 in 1" )
+ PORT_CONFSETTING( 0x06, "2000 in 1" )
+ PORT_CONFSETTING( 0x07, "19 in 1" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+ioport_constructor nes_sachen_shero_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( sachen_shero );
+}
+
+ioport_constructor nes_bmc_5in1_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( bmc_5in1 );
+}
-nes_nitra_device::nes_nitra_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ioport_constructor nes_bmc_f600_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( bmc_f600 );
+}
+
+ioport_constructor nes_bmc_kc885_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( bmc_kc885 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+nes_nitra_device::nes_nitra_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_NITRA, tag, owner, clock)
{
}
-nes_ks7057_device::nes_ks7057_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_KS7057, tag, owner, clock)
+nes_bmw8544_device::nes_bmw8544_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMW8544, tag, owner, clock), m_reg(0)
+{
+}
+
+nes_fs6_device::nes_fs6_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_FS6, tag, owner, clock)
{
}
-nes_sbros11_device::nes_sbros11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_sbros11_device::nes_sbros11_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_SBROS11, tag, owner, clock)
{
}
-nes_malisb_device::nes_malisb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_malisb_device::nes_malisb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_MALISB, tag, owner, clock)
{
}
-nes_family4646_device::nes_family4646_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_family4646_device::nes_family4646_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_FAMILY4646, tag, owner, clock)
{
}
@@ -96,33 +192,58 @@ nes_pikay2k_device::nes_pikay2k_device(const machine_config &mconfig, const char
{
}
-nes_8237_device::nes_8237_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_8237, tag, owner, clock), m_cd_enable(0)
+nes_8237_device::nes_8237_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 board)
+ : nes_txrom_device(mconfig, type, tag, owner, clock), m_board(board)
{
}
-nes_sglionk_device::nes_sglionk_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_SG_LIONK, tag, owner, clock), m_reg(0), m_reg_enabled(0)
+nes_8237_device::nes_8237_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_8237_device(mconfig, NES_8237, tag, owner, clock, 0)
{
}
-nes_sgboog_device::nes_sgboog_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_SG_BOOG, tag, owner, clock), m_mode(0)
+nes_8237a_device::nes_8237a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_8237_device(mconfig, NES_8237A, tag, owner, clock, 1)
{
}
-nes_kasing_device::nes_kasing_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_KASING, tag, owner, clock), m_reg(0)
+nes_158b_device::nes_158b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_8237_device(mconfig, NES_158B, tag, owner, clock, 0)
{
}
-nes_kay_device::nes_kay_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_kasing_device::nes_kasing_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, type, tag, owner, clock), m_mmc3_mode(true)
+{
+}
+
+nes_kasing_device::nes_kasing_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_kasing_device(mconfig, NES_KASING, tag, owner, clock)
+{
+}
+
+nes_sglionk_device::nes_sglionk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 board)
+ : nes_kasing_device(mconfig, type, tag, owner, clock), m_board(board)
+{
+}
+
+nes_sglionk_device::nes_sglionk_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_sglionk_device(mconfig, NES_SG_LIONK, tag, owner, clock, 0)
+{
+}
+
+nes_sgboog_device::nes_sgboog_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_sglionk_device(mconfig, NES_SG_BOOG, tag, owner, clock, 1)
+{
+}
+
+nes_kay_device::nes_kay_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_KAY, tag, owner, clock), m_low_reg(0)
{
}
-nes_h2288_device::nes_h2288_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_H2288, tag, owner, clock)
+nes_h2288_device::nes_h2288_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_H2288, tag, owner, clock), m_mmc3_mode(true)
{
}
@@ -141,8 +262,8 @@ nes_kof97_device::nes_kof97_device(const machine_config &mconfig, const char *ta
{
}
-nes_kof96_device::nes_kof96_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_KOF96, tag, owner, clock)
+nes_kof96_device::nes_kof96_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_KOF96, tag, owner, clock), m_mmc3_mode(true)
{
}
@@ -151,6 +272,11 @@ nes_sf3_device::nes_sf3_device(const machine_config &mconfig, const char *tag, d
{
}
+nes_cocoma_device::nes_cocoma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_COCOMA, tag, owner, clock)
+{
+}
+
nes_gouder_device::nes_gouder_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: nes_txrom_device(mconfig, NES_GOUDER, tag, owner, clock)
{
@@ -161,15 +287,32 @@ nes_sa9602b_device::nes_sa9602b_device(const machine_config &mconfig, const char
{
}
-nes_sachen_shero_device::nes_sachen_shero_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_SACHEN_SHERO, tag, owner, clock), m_reg(0)
+nes_sachen_shero_device::nes_sachen_shero_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_SACHEN_SHERO, tag, owner, clock)
+ , m_jumper(*this, "JUMPER")
+ , m_reg(0)
+{
+}
+
+nes_sachen_zgdh_device::nes_sachen_zgdh_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_SACHEN_ZGDH, tag, owner, clock), m_reg(0)
+{
+}
+
+nes_a9746_device::nes_a9746_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : nes_txrom_device(mconfig, NES_A9746, tag, owner, clock)
+{
+}
+
+nes_a88s1_device::nes_a88s1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_A88S1, tag, owner, clock)
{
}
-//nes_a9746_device::nes_a9746_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
-// : nes_txrom_device(mconfig, NES_A9746, tag, owner, clock)
-//{
-//}
+nes_bmc_el86xc_device::nes_bmc_el86xc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_EL86XC, tag, owner, clock)
+{
+}
nes_fk23c_device::nes_fk23c_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: nes_txrom_device(mconfig, type, tag, owner, clock), m_mmc_cmd1(0)
@@ -186,13 +329,39 @@ nes_fk23ca_device::nes_fk23ca_device(const machine_config &mconfig, const char *
{
}
+nes_nt639_device::nes_nt639_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_NT639, tag, owner, clock)
+{
+}
+
+nes_resettxrom_device::nes_resettxrom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_RESETTXROM, tag, owner, clock), m_count(-1)
+{
+}
+
nes_s24in1sc03_device::nes_s24in1sc03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: nes_txrom_device(mconfig, NES_S24IN1SC03, tag, owner, clock)
{
}
-nes_bmc_15in1_device::nes_bmc_15in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_15IN1, tag, owner, clock)
+nes_tech9in1_device::nes_tech9in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_TECHLINE9IN1, tag, owner, clock)
+{
+}
+
+nes_bmc_5in1_device::nes_bmc_5in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_5IN1, tag, owner, clock)
+ , m_jumper(*this, "JUMPER")
+{
+}
+
+nes_bmc_8in1_device::nes_bmc_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_8IN1, tag, owner, clock)
+{
+}
+
+nes_bmc_15in1_device::nes_bmc_15in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_15IN1, tag, owner, clock), m_jumper(0)
{
}
@@ -201,38 +370,116 @@ nes_bmc_sbig7_device::nes_bmc_sbig7_device(const machine_config &mconfig, const
{
}
-nes_bmc_hik8_device::nes_bmc_hik8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_HIK8, tag, owner, clock), m_count(0)
+nes_bmc_hik8_device::nes_bmc_hik8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, type, tag, owner, clock), m_count(0)
+{
+}
+
+nes_bmc_hik8_device::nes_bmc_hik8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_bmc_hik8_device(mconfig, NES_BMC_HIK8, tag, owner, clock)
+{
+}
+
+nes_bmc_jy208_device::nes_bmc_jy208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_bmc_hik8_device(mconfig, NES_BMC_JY208, tag, owner, clock)
+{
+}
+
+nes_bmc_jy302_device::nes_bmc_jy302_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_bmc_hik8_device(mconfig, NES_BMC_JY302, tag, owner, clock)
+{
+}
+
+nes_bmc_kc885_device::nes_bmc_kc885_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_bmc_hik8_device(mconfig, NES_BMC_KC885, tag, owner, clock)
+ , m_jumper(*this, "JUMPER")
+{
+}
+
+nes_bmc_sfc12_device::nes_bmc_sfc12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_bmc_hik8_device(mconfig, NES_BMC_SFC12, tag, owner, clock)
+{
+}
+
+nes_bmc_hik4_device::nes_bmc_hik4_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_HIK4, tag, owner, clock), m_mmc3_mode(true)
+{
+}
+
+nes_bmc_f15_device::nes_bmc_f15_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_F15, tag, owner, clock)
+{
+}
+
+nes_bmc_f600_device::nes_bmc_f600_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txsrom_device(mconfig, NES_BMC_F600, tag, owner, clock)
+ , m_jumper(*this, "JUMPER")
+ , m_reg(0)
+{
+}
+
+nes_bmc_gn45_device::nes_bmc_gn45_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_GN45, tag, owner, clock), m_lock(false)
+{
+}
+
+nes_bmc_gold7in1_device::nes_bmc_gold7in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_GOLD7IN1, tag, owner, clock), m_lock(false)
{
}
-nes_bmc_hik4_device::nes_bmc_hik4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_HIK4, tag, owner, clock)
+nes_bmc_k3006_device::nes_bmc_k3006_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_K3006, tag, owner, clock)
{
}
-nes_bmc_mario7in1_device::nes_bmc_mario7in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_MARIO7IN1, tag, owner, clock), m_reg_written(0)
+nes_bmc_k3033_device::nes_bmc_k3033_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_K3033, tag, owner, clock), m_mmc3_mode(false)
{
}
-nes_bmc_gold7in1_device::nes_bmc_gold7in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_GOLD7IN1, tag, owner, clock), m_reg_written(0)
+nes_bmc_l6in1_device::nes_bmc_l6in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_L6IN1, tag, owner, clock), m_reg(0)
{
}
-nes_bmc_gc6in1_device::nes_bmc_gc6in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_GC6IN1, tag, owner, clock)
+nes_bmc_00202650_device::nes_bmc_00202650_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_00202650, tag, owner, clock), m_mmc3_mode(false)
{
}
-nes_bmc_411120c_device::nes_bmc_411120c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_bmc_411120c_device::nes_bmc_411120c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_txrom_device(mconfig, NES_BMC_411120C, tag, owner, clock), m_reg(0)
{
}
-nes_bmc_830118c_device::nes_bmc_830118c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_BMC_830118C, tag, owner, clock), m_reg(0)
+nes_bmc_810305c_device::nes_bmc_810305c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txsrom_device(mconfig, NES_BMC_810305C, tag, owner, clock), m_outer(0)
+{
+}
+
+nes_bmc_820720c_device::nes_bmc_820720c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_820720C, tag, owner, clock), m_reg(0)
+{
+}
+
+nes_bmc_830118c_device::nes_bmc_830118c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_830118C, tag, owner, clock)
+{
+}
+
+nes_bmc_830832c_device::nes_bmc_830832c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_830832C, tag, owner, clock)
+{
+}
+
+nes_bmc_yy841101c_device::nes_bmc_yy841101c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_YY841101C, tag, owner, clock)
+{
+}
+
+nes_bmc_yy841155c_device::nes_bmc_yy841155c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_BMC_YY841155C, tag, owner, clock)
{
}
@@ -241,17 +488,37 @@ nes_pjoy84_device::nes_pjoy84_device(const machine_config &mconfig, const char *
{
}
-nes_coolboy_device::nes_coolboy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_txrom_device(mconfig, NES_COOLBOY, tag, owner, clock)
+nes_smd133_device::nes_smd133_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_txrom_device(mconfig, NES_SMD133, tag, owner, clock)
{
}
+
+void nes_bmw8544_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
+void nes_bmw8544_device::pcb_reset()
+{
+ m_reg = 0;
+ mmc3_common_initialize(0x0f, 0xff, 0);
+}
+
+void nes_family4646_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
void nes_family4646_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
mmc3_common_initialize(0x1f, 0xff, 0);
+ set_nt_mirroring(PPU_MIRROR_HORZ); // Space Shuttle on CB-4035 doesn't set mirroring bit. Whether this cart is hard-wired to reset correctly to horizontal mirroring is not clear.
}
void nes_pikay2k_device::device_start()
@@ -262,8 +529,6 @@ void nes_pikay2k_device::device_start()
void nes_pikay2k_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_reg[0] = 0xff;
m_reg[1] = 0;
mmc3_common_initialize(0xff, 0xff, 0);
@@ -273,70 +538,42 @@ void nes_8237_device::device_start()
{
mmc3_start();
save_item(NAME(m_reg));
- save_item(NAME(m_cd_enable));
}
void nes_8237_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ mmc3_common_initialize(0x1f, 0xff, 0);
m_reg[0] = 0;
- m_reg[1] = 0;
+ m_reg[1] = 0x0f;
m_reg[2] = 0;
- m_cd_enable = 0;
- mmc3_common_initialize(0xff, 0xff, 0);
-}
-
-void nes_sglionk_device::device_start()
-{
- mmc3_start();
- save_item(NAME(m_reg));
- save_item(NAME(m_reg_enabled));
+ update_banks();
}
-void nes_sglionk_device::pcb_reset()
+void nes_158b_device::device_start()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- m_reg = m_reg_enabled = 0;
- mmc3_common_initialize(0xff, 0xff, 0);
+ nes_8237_device::device_start();
+ save_item(NAME(m_prot));
}
-void nes_sgboog_device::device_start()
+void nes_158b_device::pcb_reset()
{
- mmc3_start();
- save_item(NAME(m_reg));
- save_item(NAME(m_mode));
-}
-
-void nes_sgboog_device::pcb_reset()
-{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- m_mode = 0x04;
- m_reg[0] = 0x00;
- m_reg[1] = 0xff;
- m_reg[2] = 0;
- mmc3_common_initialize(0x1f, 0xff, 0);
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ nes_8237_device::pcb_reset();
+ m_prot = 7; // Blood of Jurassic needs this row of prot_table
}
void nes_kasing_device::device_start()
{
mmc3_start();
- save_item(NAME(m_reg));
+ save_item(NAME(m_mmc3_mode));
}
void nes_kasing_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- m_reg = 0;
+ m_mmc3_mode = true;
mmc3_common_initialize(0xff, 0xff, 0);
}
-
void nes_kay_device::device_start()
{
mmc3_start();
@@ -346,27 +583,22 @@ void nes_kay_device::device_start()
void nes_kay_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- memset(m_reg, 0, sizeof(m_reg));
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
m_low_reg = 0;
- mmc3_common_initialize(0xff, 0xff, 0);
+ mmc3_common_initialize(0x1f, 0xff, 0);
}
void nes_h2288_device::device_start()
{
mmc3_start();
- save_item(NAME(m_reg));
+ save_item(NAME(m_mmc3_mode));
}
void nes_h2288_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- m_reg[0] = 0;
- m_reg[1] = 0;
- mmc3_common_initialize(0xff, 0xff, 0);
+ m_mmc3_mode = true;
+ mmc3_common_initialize(0x3f, 0xff, 0);
}
void nes_6035052_device::device_start()
@@ -377,25 +609,27 @@ void nes_6035052_device::device_start()
void nes_6035052_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
mmc3_common_initialize(0xff, 0xff, 0);
-
m_prot = 0;
}
void nes_kof96_device::device_start()
{
mmc3_start();
- save_item(NAME(m_reg));
+ save_item(NAME(m_mmc3_mode));
}
void nes_kof96_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- memset(m_reg, 0, sizeof(m_reg));
+ m_mmc3_mode = true;
mmc3_common_initialize(0xff, 0xff, 0);
}
+void nes_cocoma_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+}
+
void nes_gouder_device::device_start()
{
mmc3_start();
@@ -404,8 +638,7 @@ void nes_gouder_device::device_start()
void nes_gouder_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- memset(m_reg, 0, sizeof(m_reg));
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
mmc3_common_initialize(0xff, 0xff, 0);
}
@@ -418,8 +651,6 @@ void nes_sa9602b_device::device_start()
void nes_sa9602b_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_reg = 0;
m_prg_chip = 0;
mmc3_common_initialize(0x1ff, 0xff, 0); // 1.5MB of PRG-ROM, no CHR-ROM but 32K CHR-RAM
@@ -433,10 +664,57 @@ void nes_sachen_shero_device::device_start()
void nes_sachen_shero_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ m_reg = 0;
+ mmc3_common_initialize(0xff, 0xff, 0);
+}
+
+void nes_sachen_zgdh_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
+void nes_sachen_zgdh_device::pcb_reset()
+{
+ assert(m_vram.size() >= 0x2000);
m_reg = 0;
- mmc3_common_initialize(0xff, 0x1ff, 0);
+ mmc3_common_initialize(0x1f, 0x7f, 0);
+}
+
+void nes_a9746_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
+void nes_a9746_device::pcb_reset()
+{
+ m_reg[0] = 0;
+ m_reg[1] = 0;
+ m_reg[2] = 0;
+ mmc3_common_initialize(0x7f, 0xff, 0);
+}
+
+void nes_a88s1_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+
+ // power-on values for registers; they don't seem to change with soft reset
+ m_reg[0] = 0x80;
+ m_reg[1] = 0x82;
+}
+
+void nes_a88s1_device::pcb_reset()
+{
+ mmc3_common_initialize(0x1f, 0xff, 0);
+ update_banks();
+}
+
+void nes_bmc_el86xc_device::pcb_reset()
+{
+ mmc3_common_initialize((m_outer_prg_size >> 3) - 1, 0x7f, 0);
}
void nes_fk23c_device::device_start()
@@ -448,8 +726,6 @@ void nes_fk23c_device::device_start()
void nes_fk23c_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_mmc_cmd1 = 0;
m_reg[0] = 4;
m_reg[1] = 0xff;
@@ -458,13 +734,10 @@ void nes_fk23c_device::pcb_reset()
mmc3_common_initialize(0xff, 0xff, 0);
fk23c_set_prg();
fk23c_set_chr();
-
}
void nes_fk23ca_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_mmc_cmd1 = 0;
m_reg[0] = m_reg[1] = m_reg[2] = m_reg[3] = 0;
m_reg[4] = m_reg[5] = m_reg[6] = m_reg[7] = 0xff;
@@ -473,6 +746,29 @@ void nes_fk23ca_device::pcb_reset()
fk23c_set_chr();
}
+void nes_nt639_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0xff, 0);
+}
+
+// These reset-based PCBs are emulated here with no additional handlers
+void nes_resettxrom_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_count));
+}
+
+void nes_resettxrom_device::pcb_reset()
+{
+ mmc3_common_initialize((m_outer_prg_size >> 3) - 1, m_outer_chr_size - 1, 0);
+
+ m_count = (m_count + 1) & 3;
+ m_prg_base = m_count << (31 - count_leading_zeros_32(m_outer_prg_size) - 3); // << std::countr_zero(m_outer_prg_size) - 3; in C++20
+ m_chr_base = m_count << (31 - count_leading_zeros_32(m_outer_chr_size)); // << std::countr_zero(m_outer_chr_size); in C++20
+ set_prg(m_prg_base, m_prg_mask);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+}
+
void nes_s24in1sc03_device::device_start()
{
mmc3_start();
@@ -481,26 +777,43 @@ void nes_s24in1sc03_device::device_start()
void nes_s24in1sc03_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_reg[0] = 0x24;
m_reg[1] = 0x9f;
m_reg[2] = 0;
mmc3_common_initialize(0xff, 0xff, 0);
}
-void nes_bmc_15in1_device::pcb_reset()
+void nes_tech9in1_device::device_start()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+void nes_tech9in1_device::pcb_reset()
+{
+ m_reg[0] = m_reg[1] = m_reg[2] = 0;
+ mmc3_common_initialize(0x1f, 0xff, 0);
+}
+
+void nes_bmc_5in1_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+ prg32(0);
+}
+
+void nes_bmc_8in1_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+ prg32(0);
+}
+
+void nes_bmc_15in1_device::pcb_reset()
+{
mmc3_common_initialize(0x1f, 0xff, 0);
- m_prg_base = 0x10; // this board has a diff prg_base
- set_prg(m_prg_base, m_prg_mask);
}
void nes_bmc_sbig7_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
mmc3_common_initialize(0x0f, 0x7f, 0);
}
@@ -513,64 +826,122 @@ void nes_bmc_hik8_device::device_start()
void nes_bmc_hik8_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ set_nt_mirroring(PPU_MIRROR_VERT); // necessary since some boards/games don't reliably set mirroring (Rockman 1 on mc_s13 at least)
m_count = 0;
- memset(m_reg, 0, sizeof(m_reg));
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
mmc3_common_initialize(0x3f, 0xff, 0);
}
+void nes_bmc_kc885_device::pcb_reset()
+{
+ nes_bmc_hik8_device::pcb_reset();
+ m_prg_mask = 0x1f;
+ set_prg(m_prg_base, m_prg_mask);
+}
+
+void nes_bmc_hik4_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_mmc3_mode));
+}
+
void nes_bmc_hik4_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ m_mmc3_mode = true;
mmc3_common_initialize(0x0f, 0x7f, 0);
}
-void nes_bmc_mario7in1_device::device_start()
+void nes_bmc_f15_device::pcb_reset()
+{
+ mmc3_common_initialize(0x1f, 0xff, 0);
+ prg16_89ab(0);
+ prg16_cdef(0);
+}
+
+void nes_bmc_f600_device::device_start()
{
mmc3_start();
- save_item(NAME(m_reg_written));
+ save_item(NAME(m_reg));
+}
+
+void nes_bmc_f600_device::pcb_reset()
+{
+ m_reg = 0;
+ mmc3_common_initialize(0x1f, 0x7f, 0);
}
-void nes_bmc_mario7in1_device::pcb_reset()
+void nes_bmc_gn45_device::device_start()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ mmc3_start();
+ save_item(NAME(m_lock));
+}
- m_reg_written = 0;
- mmc3_common_initialize(0x1f, 0xff, 0);
+void nes_bmc_gn45_device::pcb_reset()
+{
+ m_lock = false;
+ mmc3_common_initialize(0x0f, 0x7f, 0);
}
void nes_bmc_gold7in1_device::device_start()
{
mmc3_start();
- save_item(NAME(m_reg_written));
+ save_item(NAME(m_lock));
}
void nes_bmc_gold7in1_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- m_reg_written = 0;
+ m_lock = false;
mmc3_common_initialize(0x1f, 0xff, 0);
}
-void nes_bmc_gc6in1_device::device_start()
+void nes_bmc_k3006_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+ prg16_89ab(0);
+ prg16_cdef(0);
+}
+
+void nes_bmc_k3033_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_mmc3_mode));
+}
+
+void nes_bmc_k3033_device::pcb_reset()
+{
+ m_mmc3_mode = false;
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+ prg16_89ab(0);
+ prg16_cdef(0);
+}
+
+void nes_bmc_l6in1_device::device_start()
{
mmc3_start();
save_item(NAME(m_reg));
}
-void nes_bmc_gc6in1_device::pcb_reset()
+void nes_bmc_l6in1_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ m_reg = 0;
+ mmc3_common_initialize(0x0f, 0x07, 0);
+}
- m_reg[0] = 0x00;
- m_reg[1] = 0xff;
- m_reg[2] = 0x03;
- m_reg[3] = 0;
- mmc3_common_initialize(0xff, 0xff, 0);
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
+void nes_bmc_00202650_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_mmc3_mode));
+}
+
+void nes_bmc_00202650_device::pcb_reset()
+{
+ m_mmc3_mode = false;
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+
+ // PCB has an extra 32KB boot menu chip, only the menu uses the CHRRAM
+ prg32((m_prg_chunks >> 1) - 1);
+ chr8(0, CHRRAM);
}
void nes_bmc_411120c_device::device_start()
@@ -581,24 +952,59 @@ void nes_bmc_411120c_device::device_start()
void nes_bmc_411120c_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
m_reg = 0;
- mmc3_common_initialize(0x7f, 0x7f, 0);
+ mmc3_common_initialize(0x0f, 0x7f, 0);
}
-void nes_bmc_830118c_device::device_start()
+void nes_bmc_810305c_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_outer));
+}
+
+void nes_bmc_810305c_device::pcb_reset()
+{
+ m_outer = 0;
+ mmc3_common_initialize(0x1f, 0x7f, 0);
+}
+
+void nes_bmc_820720c_device::device_start()
{
mmc3_start();
save_item(NAME(m_reg));
}
+void nes_bmc_820720c_device::pcb_reset()
+{
+ m_reg = 0;
+ mmc3_common_initialize(0x0f, 0xff, 0);
+}
+
void nes_bmc_830118c_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+}
- m_reg = 0;
- mmc3_common_initialize(0x7f, 0x7f, 0);
+void nes_bmc_830832c_device::pcb_reset()
+{
+ mmc3_common_initialize(0x1f, 0xff, 0);
+}
+
+void nes_bmc_yy841101c_device::pcb_reset()
+{
+ mmc3_common_initialize(0x0f, 0x7f, 0);
+}
+
+void nes_bmc_yy841155c_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
+void nes_bmc_yy841155c_device::pcb_reset()
+{
+ m_reg[0] = m_reg[1];
+ mmc3_common_initialize(0x0f, 0x7f, 0);
}
void nes_pjoy84_device::device_start()
@@ -609,13 +1015,23 @@ void nes_pjoy84_device::device_start()
void nes_pjoy84_device::pcb_reset()
{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
-
- memset(m_reg, 0, sizeof(m_reg));
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
set_base_mask();
mmc3_common_initialize(m_prg_mask, m_chr_mask, 0);
}
+void nes_smd133_device::device_start()
+{
+ mmc3_start();
+ save_item(NAME(m_reg));
+}
+
+void nes_smd133_device::pcb_reset()
+{
+ std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
+ mmc3_common_initialize(0x3f, 0xff, 0);
+}
+
/*-------------------------------------------------
@@ -626,42 +1042,79 @@ void nes_pjoy84_device::pcb_reset()
Bootleg Board by Nitra
- Games: Time Diver Avenger
+ Games: Queen Bee, Time Diver Avenger
- This acts basically like a MMC3 with different use of write
- address.
+ MMC3 clone with A10 tied to what is normally A0 and
+ data instead coming from the lower address lines.
iNES: mapper 250
- In MESS: Supported.
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_nitra_device::write_h(offs_t offset, u8 data)
+{
+ LOG("nitra write_h, offset: %04x, data: %02x\n", offset, data);
+
+ txrom_write((offset & 0x6000) | BIT(offset, 10), offset);
+}
+
+/*-------------------------------------------------
+
+ Board BMW8544
+
+ Games: Dragon Fighter (Flying Star)
+
+ MMC3 clone with poorly understood PRG/CHR banking.
+
+ NES 2.0: mapper 292
+
+ In MAME: Not supported.
-------------------------------------------------*/
-void nes_nitra_device::write_h(offs_t offset, uint8_t data)
+void nes_bmw8544_device::set_prg(int prg_base, int prg_mask)
{
- LOG_MMC(("nitra write_h, offset: %04x, data: %02x\n", offset, data));
+ nes_txrom_device::set_prg(prg_base, prg_mask);
+ prg8_89(m_reg);
+}
+
+u8 nes_bmw8544_device::read_m(offs_t offset)
+{
+ LOGMASKED(LOG_HIFREQ, "bmw8544 read_m, offset: %04x\n", offset);
- txrom_write((offset & 0x6000) | ((offset & 0x400) >> 10), offset & 0xff);
+ // CHR banking may be done by reads in this address range
+
+ return nes_txrom_device::read_m(offset);
+}
+
+void nes_bmw8544_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmw8544 write_m, offset: %04x, data: %02x\n", offset, data);
+ m_reg = data;
+ prg8_89(data);
}
/*-------------------------------------------------
- Board UNL-KS7057
+ Board UNL-FS6
Games: Street Fighter VI / Fight Street VI
MMC3 clone (identical, but for switched address lines)
- In MESS: Supported
+ iNES: mapper 196 alt?
+
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_ks7057_device::write_h(offs_t offset, uint8_t data)
+void nes_fs6_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("ks7057 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("fs6 write_h, offset: %04x, data: %02x\n", offset, data);
- offset = (BIT(offset, 0) << 1) | BIT(offset, 1) | (offset & ~0x03);
- txrom_write(offset, data);
+ txrom_write(bitswap<2>(offset, 0, 1) | (offset & ~0x03), data);
}
/*-------------------------------------------------
@@ -675,15 +1128,15 @@ void nes_ks7057_device::write_h(offs_t offset, uint8_t data)
iNES: mapper 196
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_sbros11_device::write_h(offs_t offset, uint8_t data)
+void nes_sbros11_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("smb11 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("smb11 write_h, offset: %04x, data: %02x\n", offset, data);
- txrom_write((offset & 0x6000) | ((offset & 0x04) >> 2), data);
+ txrom_write((offset & 0x6000) | BIT(offset, 2), data);
}
/*-------------------------------------------------
@@ -695,30 +1148,30 @@ void nes_sbros11_device::write_h(offs_t offset, uint8_t data)
This is very similar to mapper 196, but with additional
data bit swap.
- In MESS: Supported.
+ NES 2.0: mapper 325
+
+ In MAME: Supported.
-------------------------------------------------*/
void nes_malisb_device::prg_cb(int start, int bank)
{
- bank = (bank & 3) | ((bank & 8) >> 1) | ((bank & 4) << 1);
+ bank = bitswap<4>(bank, 2, 3, 1, 0);
prg8_x(start, bank);
}
void nes_malisb_device::chr_cb(int start, int bank, int source)
{
- bank = (bank & 0xdd) | ((bank & 0x20) >> 4) | ((bank & 2) << 4);
+ bank = bitswap<8>(bank, 7, 6, 1, 4, 3, 2, 5, 0);
chr1_x(start, bank, source);
}
-void nes_malisb_device::write_h(offs_t offset, uint8_t data)
+void nes_malisb_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("malisb write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("malisb write_h, offset: %04x, data: %02x\n", offset, data);
- if (offset > 0x4000)
- txrom_write((offset & 0xfffe) | ((offset & 0x04) >> 2) | ((offset & 0x08) >> 3), data);
- else
- txrom_write((offset & 0xfffe) | ((offset & 0x08) >> 3), data);
+ offset = (offset & 0x6000) | BIT(offset, 3) | (BIT(offset, 14) & BIT(offset, 2));
+ txrom_write(offset, data);
}
/*-------------------------------------------------
@@ -726,31 +1179,62 @@ void nes_malisb_device::write_h(offs_t offset, uint8_t data)
BMC-FAMILY-4646B
Known Boards: Unknown Multigame Bootleg Board (4646B)
- Games: 2 in 1 - Family Kid & Aladdin 4
+ Games: 2 in 1 - Family Kid & Aladdin 4, various multicarts.
- MMC3 clone
+ MMC3 clone with banking for multigame menu.
iNES: mapper 134
- In MESS: Supported.
+ In MAME: Preliminary supported.
+
+ TODO: There are unknown writes to the unused reg 3,
+ though it seems only 0x00 is written. Next, some
+ carts have solder pad setting readable at 0x8000.
+ Lastly, YH-4103 doesn't soft reset cleanly like
+ the other carts, but does this happen on hardware?
-------------------------------------------------*/
-void nes_family4646_device::write_m(offs_t offset, uint8_t data)
+void nes_family4646_device::prg_cb(int start, int bank)
{
- LOG_MMC(("family4646 write_m, offset: %04x, data: %02x\n", offset, data));
-
- if (offset == 0x01)
+ if (!BIT(m_reg[1], 7)) // MMC3 mode
+ nes_txrom_device::prg_cb(start, bank);
+ else if (start == 0) // NROM mode, only uses MMC3's $8000 bank
{
- m_prg_base = (data & 0x02) << 4;
- m_prg_mask = 0x1f;
- m_chr_base = (data & 0x20) << 3;
- m_chr_mask = 0xff;
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ if (BIT(m_reg[1], 3))
+ {
+ prg16_89ab(bank & ~0x01);
+ prg16_cdef(bank & ~0x01);
+ }
+ else
+ prg32(bank & ~0x03);
}
}
+void nes_family4646_device::write_m(offs_t offset, u8 data)
+{
+ LOG("family4646 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ int reg = offset & 0x03;
+ if (!BIT(m_reg[0], 7)) // lock bit
+ m_reg[reg] = data;
+ else if (reg == 2) // final two bits of reg 2 respond regardless
+ m_reg[reg] = (m_reg[reg] & ~0x03) | (data & 0x03);
+ else
+ return;
+
+ m_prg_base = (m_reg[1] & 0x03) << 4;
+ m_prg_mask = 0x1f >> BIT(m_reg[1], 2);
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = (m_reg[1] & 0x30) << 3;
+ m_chr_mask = 0xff >> BIT(m_reg[1], 6);
+ if (BIT(m_reg[0], 3)) // CNROM-like mode
+ chr8(m_chr_base >> 3 | (m_reg[2] & (m_chr_mask >> 3)), m_chr_source);
+ else // MMC3 mode
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+}
+
/*-------------------------------------------------
BTL-PIKACHUY2K
@@ -759,13 +1243,13 @@ void nes_family4646_device::write_m(offs_t offset, uint8_t data)
iNES: mapper 254
- In MESS:
+ In MAME:
-------------------------------------------------*/
void nes_pikay2k_device::write_h(offs_t offset, uint8_t data)
{
- LOG_MMC(("pikay2k write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("pikay2k write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x6001)
{
@@ -775,6 +1259,7 @@ void nes_pikay2k_device::write_h(offs_t offset, uint8_t data)
case 0x2000:
m_reg[0] = 0;
+ [[fallthrough]];
default:
txrom_write(offset, data);
break;
@@ -784,382 +1269,265 @@ void nes_pikay2k_device::write_h(offs_t offset, uint8_t data)
// strange WRAM usage: it is protected at start, and gets unprotected after the first write to 0xa000
void nes_pikay2k_device::write_m(offs_t offset, uint8_t data)
{
- LOG_MMC(("pikay2k write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("pikay2k write_m, offset: %04x, data: %02x\n", offset, data);
m_prgram[offset & 0x1fff] = data;
}
uint8_t nes_pikay2k_device::read_m(offs_t offset)
{
- LOG_MMC(("pikay2k read_m, offset: %04x\n", offset));
+ LOG("pikay2k read_m, offset: %04x\n", offset);
return m_prgram[offset & 0x1fff] ^ (m_reg[0] & m_reg[1]);
}
/*-------------------------------------------------
- Board UNL-8237
+ Board UNL-8237, UNL-8237A
- Games: Pocahontas 2
+ Games: Pocahontas 2, MK3, various multicarts
- MMC3 clone
+ MMC3 clone with register and address scrambling and
+ a few extra banking modes by writing 0x5000-0x5fff.
- In MESS: Supported
+ iNES: mapper 215
- -------------------------------------------------*/
+ In MAME: Preliminary supported.
-void nes_8237_device::prg_cb(int start, int bank)
-{
- if (!(m_reg[0] & 0x80))
- prg8_x(start, bank);
-}
+ TODO: Lion King crashes after the first level in mc_9king.
+ Also in mc_9king Lion King, Somari and Aladdin all reset
+ to Aladdin instead of the menu.
-void nes_8237_device::chr_cb(int start, int bank, int source)
-{
- bank |= ((m_reg[1] << 6) & 0x100);
- chr1_x(start, bank, source);
-}
+ -------------------------------------------------*/
-void nes_8237_device::write_l(offs_t offset, uint8_t data)
+void nes_8237_device::update_banks()
{
- LOG_MMC(("unl_8237 write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ int a17 = BIT(m_reg[0], 6);
+ m_chr_base = m_board ? (m_reg[1] & 0x0e) << 7 : (m_reg[1] & 0x0c) << 6;
+ m_chr_base |= (BIT(m_reg[1], 5) & a17) << 7;
+ m_chr_mask = 0xff >> a17;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
- if (offset == 0x1000)
- {
- m_reg[0] = data;
- if (m_reg[0] & 0x80)
- {
- if (m_reg[0] & 0x20)
- prg32((m_reg[0] & 0x0f) >> 1);
- else
- {
- prg16_89ab(m_reg[0] & 0x1f);
- prg16_cdef(m_reg[0] & 0x1f);
- }
- }
- else
- set_prg(m_prg_base, m_prg_mask);
- }
+ m_prg_base = m_board ? bitswap<3>(m_reg[1], 3, 1, 0) : m_reg[1] & 0x03;
+ m_prg_base = m_prg_base << 5 | (m_reg[1] & (a17 << 4));
+ m_prg_mask = 0x1f >> a17;
- if (offset == 0x1001)
+ if (BIT(m_reg[0], 7))
{
- m_reg[1] = data;
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ u8 bank = m_prg_base >> 1 | (m_reg[0] & (m_prg_mask >> 1));
+ u8 mode = BIT(m_reg[0], 5);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
}
+ set_prg(m_prg_base, m_prg_mask);
+}
- if (offset == 0x1007)
- {
- m_reg[2] = data & 0x07; // this selects different permutations for addresses and regs (to be implemented)
- }
+void nes_8237_device::prg_cb(int start, int bank)
+{
+ if (!BIT(m_reg[0], 7))
+ nes_txrom_device::prg_cb(start, bank);
}
-void nes_8237_device::write_h(offs_t offset, uint8_t data)
+void nes_8237_device::write_l(offs_t offset, u8 data)
{
- static const uint8_t conv_table[8] = {0, 2, 6, 1, 7, 3, 4, 5};
- LOG_MMC(("unl_8237 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("unl_8237 write_l, offset: %04x, data: %02x\n", offset, data);
+ offset += 0x100;
- switch (offset & 0x7000)
+ switch (offset & 0x1007)
{
- case 0x0000:
case 0x1000:
- set_nt_mirroring((data | (data >> 7)) & 0x01 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
+ case 0x1001:
+ m_reg[offset & 1] = data;
+ update_banks();
break;
-
- case 0x2000:
- case 0x3000:
- m_cd_enable = 1;
- data = (data & 0xc0) | conv_table[data & 0x07];
- txrom_write(0x0000, data);
+ case 0x1007:
+ m_reg[2] = data & 0x07;
break;
+ }
+}
- case 0x4000:
- case 0x5000:
- if (m_cd_enable)
- {
- m_cd_enable = 0;
- txrom_write(0x0001, data);
- }
- break;
+void nes_8237_device::write_h(offs_t offset, u8 data)
+{
+ LOG("unl_8237 write_h, offset: %04x, data: %02x\n", offset, data);
- case 0x6000:
- break;
+ static constexpr u8 reg_table[8][8] =
+ {
+ {0, 1, 2, 3, 4, 5, 6, 7},
+ {0, 2, 6, 1, 7, 3, 4, 5},
+ {0, 5, 4, 1, 7, 2, 6, 3},
+ {0, 6, 3, 7, 5, 2, 4, 1},
+ {0, 2, 5, 3, 6, 1, 7, 4},
+ {0, 1, 2, 3, 4, 5, 6, 7},
+ {0, 1, 2, 3, 4, 5, 6, 7},
+ {0, 1, 2, 3, 4, 5, 6, 7}
+ };
- case 0x7000:
- txrom_write(0x6001, data);
- txrom_write(0x4000, data);
- txrom_write(0x4001, data);
- break;
- }
+ static constexpr u16 addr_table[8][8] =
+ {
+ {0x8000, 0x8001, 0xa000, 0xa001, 0xc000, 0xc001, 0xe000, 0xe001},
+ {0xa001, 0xa000, 0x8000, 0xc000, 0x8001, 0xc001, 0xe000, 0xe001},
+ {0x8000, 0x8001, 0xa000, 0xa001, 0xc000, 0xc001, 0xe000, 0xe001},
+ {0xc001, 0x8000, 0x8001, 0xa000, 0xa001, 0xe001, 0xe000, 0xc000},
+ {0xa001, 0x8001, 0x8000, 0xc000, 0xa000, 0xc001, 0xe000, 0xe001},
+ {0x8000, 0x8001, 0xa000, 0xa001, 0xc000, 0xc001, 0xe000, 0xe001},
+ {0x8000, 0x8001, 0xa000, 0xa001, 0xc000, 0xc001, 0xe000, 0xe001},
+ {0x8000, 0x8001, 0xa000, 0xa001, 0xc000, 0xc001, 0xe000, 0xe001},
+ };
+
+ u16 addr = addr_table[m_reg[2]][bitswap<3>(offset, 14, 13, 0)];
+ if (addr == 0x8000)
+ data = (data & 0xc0) | reg_table[m_reg[2]][data & 0x07];
+ txrom_write(addr & 0x6001, data);
}
/*-------------------------------------------------
- Bootleg Board by Super Game
+ Board UNL-158B
- Games: The Lion King
+ Games: Blood of Jurassic, Super Hang-On
- MMC3 clone.
+ MMC3 clone that appears to be the same as the 8237
+ boards above with added protection reads at 0x5000.
- iNES: mapper 114
+ NES 2.0: mapper 258
- In MESS: Supported.
+ In MAME: Preliminary supported.
+
+ TODO: Sprites in BoJ can sometimes become a garbled
+ mess. Not sure if zapper hit detection is ok either,
+ or why it seems you can't shoot at times (reload?).
+ Super Hang-On is a hack of Rad Racer/Highway Star so
+ it has all the graphics issues those games have.
-------------------------------------------------*/
-void nes_sglionk_device::write_m(offs_t offset, uint8_t data)
+u8 nes_158b_device::read_l(offs_t offset)
{
- LOG_MMC(("sglionk write_m, offset: %04x, data: %02x\n", offset, data));
-
- m_reg = data;
+ LOG("unl_158b read_l, offset: %04x\n", offset);
- if (m_reg & 0x80)
+ static constexpr u8 prot_table[8][8] =
{
- prg16_89ab(data & 0x1f);
- prg16_cdef(data & 0x1f);
- }
- else
- set_prg(m_prg_base, m_prg_mask);
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x05, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0f, 0x00}
+ };
+
+ u8 temp = get_open_bus();
+
+ offset += 0x100;
+ if (offset >= 0x1000)
+ temp = (temp & 0xf0) | prot_table[m_prot][offset & 0x07];
+ return temp;
}
-void nes_sglionk_device::write_h(offs_t offset, uint8_t data)
+void nes_158b_device::write_l(offs_t offset, u8 data)
{
- static const uint8_t conv_table[8] = {0, 3, 1, 5, 6, 7, 2, 4};
- LOG_MMC(("sglionk write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("unl_158b write_l, offset: %04x, data: %02x\n", offset, data);
- if (offset < 0x6000)
- {
- switch (offset & 0x6000)
- {
- case 0x0000:
- set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
- break;
- case 0x2000:
- m_reg_enabled = 1;
- data = (data & 0xc0) | conv_table[data & 0x07];
- txrom_write(0x0000, data);
- break;
- case 0x4000:
- if (m_reg_enabled && (m_reg & 0x80) == 0)
- {
- m_reg_enabled = 0;
- txrom_write(0x0001, data);
- }
- break;
- }
- }
- else
+ switch ((offset + 0x100) & 0x1003)
{
- switch (offset & 0x03)
- {
- case 0x02:
- txrom_write(0x6000, data);
- break;
- case 0x03:
- txrom_write(0x6001, data);
- txrom_write(0x4000, data);
- txrom_write(0x4001, data);
- break;
- }
+ case 0x1002:
+ m_prot = data & 0x07;
+ break;
+ default:
+ nes_8237_device::write_l(offset, data);
+ break;
}
}
/*-------------------------------------------------
- Bootleg Board by Super Game
+ Bootleg Board by Kasing
- Games: Boogerman, Mortal Kombat III
+ Games: AV Jiu Ji Mahjong, Bao Qing Tian, Thunderbolt 2,
+ Shisen Mahjong 2, Garou Densetsu Special
- MMC3 clone. Also, it probably needs a hack to support both
- variants (Boogerman & MK3).
+ MMC3 clone with extra banking modes at 0x6000-0x7fff.
- iNES: mapper 215
+ iNES: mapper 115
- In MESS: Preliminary support.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_sgboog_device::prg_cb(int start, int bank)
-{
- if (!(m_reg[0] & 0x80)) // if this is != 0 we should never even arrive here
- {
- if (m_reg[1] & 0x08)
- bank = (bank & 0x1f) | 0x20;
- else
- bank = (bank & 0x0f) | (m_reg[1] & 0x10);
-
- prg8_x(start, bank);
- }
-}
-
-void nes_sgboog_device::chr_cb(int start, int bank, int source)
-{
- if ((m_reg[1] & 0x04))
- bank |= 0x100;
- else
- bank = (bank & 0x7f) | ((m_reg[1] & 0x10) << 3);
-
- chr1_x(start, bank, source);
-}
-
-void nes_sgboog_device::set_prg(int prg_base, int prg_mask)
+void nes_kasing_device::prg_cb(int start, int bank)
{
- if (m_reg[0] & 0x80)
- {
- prg16_89ab((m_reg[0] & 0xf0) | (m_reg[1] & 0x10));
- prg16_cdef((m_reg[0] & 0xf0) | (m_reg[1] & 0x10));
- }
- else
- {
- // here standard MMC3 bankswitch
- uint8_t prg_flip = (m_latch & 0x40) ? 2 : 0;
-
- prg_cb(0, prg_base | (m_mmc_prg_bank[0 ^ prg_flip] & prg_mask));
- prg_cb(1, prg_base | (m_mmc_prg_bank[1] & prg_mask));
- prg_cb(2, prg_base | (m_mmc_prg_bank[2 ^ prg_flip] & prg_mask));
- prg_cb(3, prg_base | (m_mmc_prg_bank[3] & prg_mask));
- }
+ if (m_mmc3_mode)
+ nes_txrom_device::prg_cb(start, bank);
}
-void nes_sgboog_device::write_l(offs_t offset, uint8_t data)
+void nes_kasing_device::write_m(offs_t offset, u8 data)
{
- LOG_MMC(("sgboog write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ LOG("kasing write_m, offset: %04x, data: %02x\n", offset, data);
- if (offset == 0x1000)
- {
- m_reg[0] = data;
- set_prg(m_prg_base, m_prg_mask);
- }
- else if (offset == 0x1001)
+ if (BIT(offset, 0))
{
- m_reg[1] = data;
+ m_chr_base = BIT(data, 0) << 8;
set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
- else if (offset == 0x1007)
- {
- m_latch = 0;
- m_mode = data;
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- }
-}
-
-void nes_sgboog_device::write_m(offs_t offset, uint8_t data)
-{
- LOG_MMC(("sgboog write_m, offset: %04x, data: %02x\n", offset, data));
-
- if (offset == 0x0000)
- {
- m_reg[0] = data;
- set_prg(m_prg_base, m_prg_mask);
- }
- else if (offset == 0x0001)
- {
- m_reg[1] = data;
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- }
- else if (offset == 0x0007)
- {
- m_latch = 0;
- m_mode = data;
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- }
-}
-
-void nes_sgboog_device::write_h(offs_t offset, uint8_t data)
-{
- static const uint8_t conv_table[8] = {0,2,5,3,6,1,7,4};
- LOG_MMC(("sgboog write_h, offset: %04x, data: %02x\n", offset, data));
-
- if (m_mode)
+ else
{
- switch (offset & 0x6001)
+ m_mmc3_mode = !BIT(data, 7);
+ if (m_mmc3_mode)
+ set_prg(m_prg_base, m_prg_mask);
+ else
{
- case 0x0000:
- break;
-
- case 0x0001:
- if (m_reg[2] && ((m_reg[0] & 0x80) == 0 || (m_latch & 0x07) < 6)) // if we use the prg16 banks and cmd=6,7 DON'T enter!
- {
- m_reg[2] = 0;
- txrom_write(0x0001, data);
- }
- break;
-
- case 0x2000:
- data = (data & 0xc0) | conv_table[data & 0x07];
- m_reg[2] = 1;
- txrom_write(0x0000, data);
- break;
-
- case 0x4000:
- set_nt_mirroring(((data >> 7) | data) & 0x01 ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
- break;
-
- case 0x4001:
- txrom_write(0x6001, data);
- break;
-
- case 0x6001:
- txrom_write(0x4000, data);
- txrom_write(0x4001, data);
- break;
-
- default:
- txrom_write(offset, data);
- break;
+ u8 bank = data & 0x0f;
+ u8 mode = BIT(data, 5);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
}
}
- else
- txrom_write(offset, data);
}
/*-------------------------------------------------
- Bootleg Board by Kasing
+ Bootleg Boards by Super Game and Hosenkan
- Games: AV Jiu Ji Mahjong, Bao Qing Tian, Thunderbolt 2,
- Shisen Mahjong 2
+ Games: The Lion King, Aladdin, Boogerman, Pocohon,
+ Super Donkey Kong
- MMC3 clone
+ MMC3 clone with register and address scrambling and
+ a few extra banking modes by writing 0x6000-0x7fff.
+ This is the same as mapper 115 with scrambling.
- iNES: mapper 115
+ iNES: mapper 114 (and 182)
- In MESS: Supported
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_kasing_device::prg_cb(int start, int bank)
+void nes_sglionk_device::write_h(offs_t offset, u8 data)
{
- if (BIT(m_reg, 7))
- prg32(m_reg >> 1);
- else
- prg8_x(start, bank);
-}
+ LOG("sglionk write_h, offset: %04x, data: %02x\n", offset, data);
-void nes_kasing_device::write_m(offs_t offset, uint8_t data)
-{
- LOG_MMC(("kasing write_m, offset: %04x, data: %02x\n", offset, data));
+ static constexpr u8 reg_table[2][8] =
+ {
+ {0, 3, 1, 5, 6, 7, 2, 4},
+ {0, 2, 5, 3, 6, 1, 7, 4}
+ };
- switch (offset & 0x01)
+ static constexpr u16 addr_table[2][8] =
{
- case 0x00:
- m_reg = data;
- set_prg(m_prg_base, m_prg_mask);
- break;
- case 0x01:
- m_chr_base = (data & 0x01) ? 0x100 : 0x000;
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- break;
- }
+ {0xa001, 0xa000, 0x8000, 0xc000, 0x8001, 0xc001, 0xe000, 0xe001},
+ {0xa001, 0x8001, 0x8000, 0xc001, 0xa000, 0xc000, 0xe000, 0xe001}
+ };
+
+ u16 addr = addr_table[m_board][bitswap<3>(offset, 14, 13, 0)];
+ if (addr == 0x8000)
+ data = (data & 0xc0) | reg_table[m_board][data & 0x07];
+ txrom_write(addr & 0x6001, data);
}
/*-------------------------------------------------
- Bootleg Board by Kay (for Panda Prince)
+ A9711/A9713 Bootleg Boards by Kay (for Panda Prince)
Games: The Panda Prince, Sonic 3d Blast 6, SFZ2 '97, YuYu '97
(and its title hack MK6), UMK3, Super Lion King 2
@@ -1168,137 +1536,89 @@ void nes_kasing_device::write_m(offs_t offset, uint8_t data)
iNES: mapper 121
- In MESS: Most game works, with some graphical issues.
+ In MAME: Supported.
+
+ TODO: Most of the fighting games have graphical issues
+ with backgrounds on some stages. Due to common timing
+ issue with PPU/MMC3? Super Lion King 2's title screen
+ is also inexplicably broken.
-------------------------------------------------*/
-void nes_kay_device::write_l(offs_t offset, uint8_t data)
+void nes_kay_device::write_l(offs_t offset, u8 data)
{
- LOG_MMC(("kay write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ LOG("kay write_l, offset: %04x, data: %02x\n", offset, data);
+ offset += 0x100;
if (offset >= 0x1000)
+ m_low_reg = data & 0x03;
+
+ if ((offset & 0x1180) == 0x1180) // only written by Super 3-in-1
{
- switch (data & 0x03)
- {
- case 0x00:
- case 0x01:
- m_low_reg = 0x83;
- break;
- case 0x02:
- m_low_reg = 0x42;
- break;
- case 0x03:
- m_low_reg = 0x00;
- break;
- }
+ m_prg_base = (data & 0x80) >> 2;
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = m_prg_base << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
}
-uint8_t nes_kay_device::read_l(offs_t offset)
+u8 nes_kay_device::read_l(offs_t offset)
{
- LOG_MMC(("kay read_l, offset: %04x\n", offset));
- offset += 0x100;
+ LOG("kay read_l, offset: %04x\n", offset);
+
+ static constexpr u8 prot_table[4] = {0x83, 0x83, 0x42, 0x00};
+ offset += 0x100;
if (offset >= 0x1000)
- return m_low_reg;
+ return prot_table[m_low_reg];
else
- return 0xff;
+ return get_open_bus();
}
-void nes_kay_device::update_regs()
+void nes_kay_device::chr_cb(int start, int bank, int source)
{
- switch (m_reg[5] & 0x3f)
- {
- case 0x20:
- case 0x29:
- case 0x2b:
- case 0x3f:
- m_reg[7] = 1;
- m_reg[1] = m_reg[6];
- break;
- case 0x26:
- m_reg[7] = 0;
- m_reg[1] = m_reg[6];
- break;
- case 0x2c:
- m_reg[7] = 1;
- if (m_reg[6])
- m_reg[1] = m_reg[6];
- break;
-
- case 0x28:
- m_reg[7] = 0;
- m_reg[2] = m_reg[6];
- break;
-
- case 0x2a:
- m_reg[7] = 0;
- m_reg[3] = m_reg[6];
- break;
-
- case 0x2f:
- break;
-
- default:
- m_reg[5] = 0;
- break;
- }
+ bank |= (m_latch << 1) & (start << 6) & 0x100;
+ chr1_x(start, bank, source);
}
-void nes_kay_device::prg_cb(int start, int bank)
+void nes_kay_device::set_prg(int prg_base, int prg_mask)
{
- if (m_reg[5] & 0x3f)
+ nes_txrom_device::set_prg(prg_base, prg_mask);
+
+ if (BIT(m_reg[4], 5))
{
- prg8_x(start, bank & 0x3f);
- prg8_ef(m_reg[1]);
- prg8_cd(m_reg[2]);
- prg8_ab(m_reg[3]);
+ prg8_ab(prg_base | m_reg[0]);
+ prg8_cd(prg_base | m_reg[1]);
+ prg8_ef(prg_base | m_reg[2]);
}
- else
- prg8_x(start, bank & 0x3f);
}
-void nes_kay_device::chr_cb(int start, int bank, int source)
+void nes_kay_device::write_h(offs_t offset, u8 data)
{
- uint8_t chr_page = (m_latch & 0x80) >> 5;
-
- if ((start & 0x04) == chr_page)
- bank |= 0x100;
-
- chr1_x(start, bank, source);
-}
+ LOG("kay write_h, offset: %04x, data: %02x\n", offset, data);
-void nes_kay_device::write_h(offs_t offset, uint8_t data)
-{
- LOG_MMC(("kay write_h, offset: %04x, data: %02x\n", offset, data));
+ txrom_write(offset, data);
switch (offset & 0x6003)
{
- case 0x0000:
- txrom_write(offset, data);
- set_prg(m_prg_base, m_prg_mask);
- break;
-
case 0x0001:
- m_reg[6] = (BIT(data, 0) << 5) | (BIT(data, 1) << 4) | (BIT(data, 2) << 3)
- | (BIT(data, 3) << 2) | (BIT(data, 4) << 1) | BIT(data, 5);
- if (!m_reg[7])
- update_regs();
- txrom_write(offset, data);
- set_prg(m_prg_base, m_prg_mask);
+ m_reg[3] = bitswap<6>(data, 0, 1, 2, 3, 4, 5);
+ switch (m_reg[4])
+ {
+ case 0x26:
+ case 0x28:
+ case 0x2a:
+ m_reg[(0x2a - m_reg[4]) / 2] = m_reg[3];
+ set_prg(m_prg_base, m_prg_mask);
+ break;
+ }
break;
-
case 0x0003:
- m_reg[5] = data;
- update_regs();
- txrom_write(0x0000, data);
+ m_reg[4] = data & 0x3f;
+ if (BIT(m_reg[4], 5) && m_reg[3])
+ m_reg[2] = m_reg[3];
set_prg(m_prg_base, m_prg_mask);
break;
-
- default:
- txrom_write(offset, data);
- break;
}
}
@@ -1306,66 +1626,49 @@ void nes_kay_device::write_h(offs_t offset, uint8_t data)
UNL-H2288
+ Games: Earthworm Jim 2, Ultimate Mortal Kombat 3
+
+ iNES: mapper 123
+
+ In MAME: Supported.
+
-------------------------------------------------*/
void nes_h2288_device::prg_cb(int start, int bank)
{
- if (!(m_reg[0] & 0x40))
- prg8_x(start, bank);
+ if (m_mmc3_mode)
+ nes_txrom_device::prg_cb(start, bank);
}
-void nes_h2288_device::write_l(offs_t offset, uint8_t data)
+void nes_h2288_device::write_l(offs_t offset, u8 data)
{
- LOG_MMC(("h2288 write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ LOG("h2288 write_l, offset: %04x, data: %02x\n", offset, data);
+ offset += 0x100;
if (offset >= 0x1800)
{
- m_reg[offset & 1] = data;
- if (m_reg[0] & 0x40)
- {
- uint8_t helper1 = (m_reg[0] & 0x05) | ((m_reg[0] >> 2) & 0x0a);
- uint8_t helper2 = BIT(m_reg[0], 1);
- prg16_89ab(helper1 & ~helper2);
- prg16_cdef(helper1 | helper2);
- }
- else
+ m_mmc3_mode = !BIT(data, 6);
+ if (m_mmc3_mode)
set_prg(m_prg_base, m_prg_mask);
- }
-}
-
-uint8_t nes_h2288_device::read_l(offs_t offset)
-{
- LOG_MMC(("h2288 read_l, offset: %04x\n", offset));
- offset += 0x100;
-
- if (offset >= 0x1000)
- {
- int helper = offset >> 8;
- if (offset & 1)
- return helper | 0x01;
else
- return helper ^ 0x01;
+ {
+ u8 bank = bitswap<4>(data, 5, 2, 3, 0);
+ u8 mode = BIT(data, 1);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
}
-
- return 0;
}
-void nes_h2288_device::write_h(offs_t offset, uint8_t data)
+void nes_h2288_device::write_h(offs_t offset, u8 data)
{
- static const uint8_t conv_table[8] = {0, 3, 1, 5, 6, 7, 2, 4};
- LOG_MMC(("h2288 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("h2288 write_h, offset: %04x, data: %02x\n", offset, data);
- switch (offset & 0x6001)
- {
- case 0x0000:
- txrom_write(0x0000, (data & 0xc0) | conv_table[data & 0x07]);
- break;
+ static constexpr u8 reg_table[8] = {0, 3, 1, 5, 6, 7, 2, 4};
- default:
- txrom_write(offset, data);
- break;
- }
+ if (!(offset & 0x6001))
+ data = (data & 0xc0) | reg_table[data & 0x07];
+ txrom_write(offset, data);
}
/*-------------------------------------------------
@@ -1374,13 +1677,13 @@ void nes_h2288_device::write_h(offs_t offset, uint8_t data)
MMC3 + protection access in 0x4020 - 0x7fff
- in MESS: Partial support
+ in MAME: Partial support
-------------------------------------------------*/
void nes_6035052_device::write_ex(offs_t offset, uint8_t data)
{
- LOG_MMC(("6035052 write_ex, offset: %04x, data: %02x\n", offset, data));
+ LOG("6035052 write_ex, offset: %04x, data: %02x\n", offset, data);
m_prot = data & 0x03;
if (m_prot == 1)
m_prot = 2;
@@ -1388,7 +1691,7 @@ void nes_6035052_device::write_ex(offs_t offset, uint8_t data)
uint8_t nes_6035052_device::read_ex(offs_t offset)
{
- LOG_MMC(("6035052 read_ex, offset: %04x\n", offset));
+ LOG("6035052 read_ex, offset: %04x\n", offset);
return m_prot;
}
@@ -1402,185 +1705,102 @@ uint8_t nes_6035052_device::read_ex(offs_t offset)
iNES: mapper 189
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
void nes_txc_tw_device::write_l(offs_t offset, uint8_t data)
{
- LOG_MMC(("txc_tw write_l, offset: %04x, data: %02x\n", offset, data));
+ LOG("txc_tw write_l, offset: %04x, data: %02x\n", offset, data);
prg32((data >> 4) | data);
}
-/* writes to 0x8000-0xffff are like MMC3 but no PRG bankswitch (beacuse it is handled by low writes) */
+// writes to 0x8000-0xffff are like MMC3 but no PRG bankswitch (because it is handled by low writes)
void nes_txc_tw_device::prg_cb(int start, int bank)
{
- return;
}
/*-------------------------------------------------
Board UNL-KOF97
- Games: King of Fighters 97 (Rex Soft)
+ Games: King of Fighters 97 (Rex Soft), Boogerman II
MMC3 clone
- In MESS: Not working
+ In MAME: Supported.
-------------------------------------------------*/
-inline uint8_t kof97_unscramble( uint8_t data )
+void nes_kof97_device::write_h(offs_t offset, u8 data)
{
- return ((data >> 1) & 0x01) | ((data >> 4) & 0x02) | ((data << 2) & 0x04) | ((data >> 0) & 0xd8) | ((data << 3) & 0x20);
-}
+ LOG("kof97 write_h, offset: %04x, data: %02x\n", offset, data);
-void nes_kof97_device::write_h(offs_t offset, uint8_t data)
-{
- LOG_MMC(("kof97 write_h, offset: %04x, data: %02x\n", offset, data));
+ // unscramble address and data
+ offset = (offset & 0x6000) | BIT(offset, 12);
+ data = bitswap<8>(data, 7, 6, 2, 4, 3, 0, 5, 1);
- /* Addresses 0x9000, 0xa000, 0xd000 & 0xf000 behaves differently than MMC3 */
- if (offset == 0x1000)
- txrom_write(0x0001, kof97_unscramble(data));
- else if (offset == 0x2000)
- txrom_write(0x0000, kof97_unscramble(data));
- else if (offset == 0x5000)
- txrom_write(0x4001, kof97_unscramble(data));
- else if (offset == 0x7000)
- txrom_write(0x6001, kof97_unscramble(data));
- /* Other addresses behaves like MMC3, up to unscrambling data */
- else
- txrom_write(offset, kof97_unscramble(data));
+ txrom_write(offset, data);
}
/*-------------------------------------------------
Bootleg Board for KOF96
- Games: The King of Fighters 96, Sonic 3D Blast 6, Street
- Fighter Zero 2
+ Games: The King of Fighters 96, Street Fighter Zero 2
MMC3 clone
iNES: mapper 187
- In MESS: Preliminary Support.
+ In MAME: Supported.
-------------------------------------------------*/
void nes_kof96_device::prg_cb(int start, int bank)
{
- if (!(m_reg[0] & 0x80))
- prg8_x(start, bank);
+ if (m_mmc3_mode)
+ nes_txrom_device::prg_cb(start, bank);
}
void nes_kof96_device::chr_cb(int start, int bank, int source)
{
- uint8_t chr_page = (m_latch & 0x80) >> 5;
-
- if ((start & 0x04) == chr_page)
- bank |= 0x100;
-
+ bank |= (m_latch << 1) & (start << 6) & 0x100;
chr1_x(start, bank, source);
}
-void nes_kof96_device::write_l(offs_t offset, uint8_t data)
+void nes_kof96_device::write_l(offs_t offset, u8 data)
{
- uint8_t new_bank;
- LOG_MMC(("kof96 write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ LOG("kof96 write_l, offset: %04x, data: %02x\n", offset, data);
- if (offset == 0x1000)
+ offset += 0x100;
+ if ((offset & 0x1001) == 0x1000)
{
- m_reg[0] = data;
-
- if (m_reg[0] & 0x80)
- {
- new_bank = (m_reg[0] & 0x1f);
-
- if (m_reg[0] & 0x20)
- prg32(new_bank >> 2);
- else
- {
- prg16_89ab(new_bank);
- prg16_cdef(new_bank);
- }
- }
- else
+ m_mmc3_mode = !BIT(data, 7);
+ if (m_mmc3_mode)
set_prg(m_prg_base, m_prg_mask);
- }
-
- if (offset >= 0x1000)
- {
- switch (data & 0x03)
+ else
{
- case 0x00:
- case 0x01:
- m_reg[1] = 0x83;
- break;
- case 0x02:
- m_reg[1] = 0x42;
- break;
- case 0x03:
- m_reg[1] = 0x00;
- break;
+ u8 bank = BIT(data, 1, 4);
+ u8 mode = BIT(data, 5);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
}
-
- }
-
- if (!m_reg[3] && offset > 0x1000)
- {
- m_reg[3] = 1;
- poke(0x4017, 0x40); // FIXME
}
}
-uint8_t nes_kof96_device::read_l(offs_t offset)
+u8 nes_kof96_device::read_l(offs_t offset)
{
- LOG_MMC(("kof96 read_l, offset: %04x\n", offset));
- offset += 0x100;
+ LOG("kof96 read_l, offset: %04x\n", offset);
- if (!(offset < 0x1000))
- return m_reg[1];
+ offset += 0x100;
+ if (offset >= 0x1000)
+ return 0x80; // unknown protection read, kof96 expects that MSB is set
else
return 0;
}
-void nes_kof96_device::write_h(offs_t offset, uint8_t data)
-{
- LOG_MMC(("kof96 write_h, offset: %04x, data: %02x\n", offset, data));
-
- switch (offset & 0x6003)
- {
- case 0x0000:
- m_reg[2] = 1;
- txrom_write(0x0000, data);
- break;
-
- case 0x0001:
- if (m_reg[2])
- txrom_write(0x0001, data);
- break;
-
- case 0x0002:
- break;
-
- case 0x0003:
- m_reg[2] = 0;
-
- if (data == 0x28)
- prg8_cd(0x17);
- else if (data == 0x2a)
- prg8_ab(0x0f);
- break;
-
- default:
- txrom_write(offset, data);
- break;
- }
-}
-
/*-------------------------------------------------
Bootleg Board for Super Fighter III
@@ -1589,7 +1809,7 @@ void nes_kof96_device::write_h(offs_t offset, uint8_t data)
iNES: mapper 197
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
@@ -1603,7 +1823,7 @@ void nes_sf3_device::set_chr(uint8_t chr_source, int chr_base, int chr_mask)
void nes_sf3_device::write_h(offs_t offset, uint8_t data)
{
uint8_t cmd;
- LOG_MMC(("sf3 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("sf3 write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x6001)
{
@@ -1631,6 +1851,35 @@ void nes_sf3_device::write_h(offs_t offset, uint8_t data)
/*-------------------------------------------------
+ Cocoma Core Pro Board
+
+ Games: BrilliantCom Cocoma Pack 1 and 2
+
+ MMC3 clone with an extra outer bank latch.
+
+ NES 2.0: mapper 516
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_cocoma_device::write_h(offs_t offset, u8 data)
+{
+ LOG("cocoma write_h, offset: %04x, data: %02x\n", offset, data);
+
+ if (BIT(offset, 4))
+ {
+ m_prg_base = (offset & 0x03) << 4;
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = (offset & 0x0c) << 5;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+ else
+ txrom_write(offset, data);
+}
+
+/*-------------------------------------------------
+
Bootleg Board 37017 (?) by Gouder
Games: Street Fighter IV
@@ -1639,13 +1888,13 @@ void nes_sf3_device::write_h(offs_t offset, uint8_t data)
iNES: mapper 208
- In MESS: Preliminary Support.
+ In MAME: Preliminary Support.
-------------------------------------------------*/
-void nes_gouder_device::write_l(offs_t offset, uint8_t data)
+void nes_gouder_device::write_l(offs_t offset, u8 data)
{
- static const uint8_t conv_table[256] =
+ static constexpr u8 conv_table[256] =
{
0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x49,0x19,0x09,0x59,0x49,0x19,0x09,
0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x51,0x41,0x11,0x01,0x51,0x41,0x11,0x01,
@@ -1665,30 +1914,38 @@ void nes_gouder_device::write_l(offs_t offset, uint8_t data)
0x09,0x19,0x49,0x59,0x09,0x19,0x49,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
- LOG_MMC(("gouder write_l, offset: %04x, data: %02x\n", offset, data));
+ LOG("gouder write_l, offset: %04x, data: %02x\n", offset, data);
- if (!(offset < 0x1700))
- m_reg[offset & 0x03] = data ^ conv_table[m_reg[4]];
- else if (!(offset < 0xf00))
- m_reg[4] = data;
- else if (!(offset < 0x700))
- prg32(((data >> 3) & 0x02) | (data & 0x01));
+ offset += 0x100;
+ switch (offset & 0x1800)
+ {
+ case 0x0800:
+ prg32(bitswap<2>(data, 4, 0));
+ set_nt_mirroring(BIT(data, 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
+ break;
+ case 0x1000:
+ m_reg[4] = data;
+ break;
+ case 0x1800:
+ m_reg[offset & 0x03] = data ^ conv_table[m_reg[4]];
+ break;
+ }
}
-uint8_t nes_gouder_device::read_l(offs_t offset)
+u8 nes_gouder_device::read_l(offs_t offset)
{
- LOG_MMC(("gouder read_l, offset: %04x\n", offset));
+ LOG("gouder read_l, offset: %04x\n", offset);
- if (!(offset < 0x1700))
+ offset += 0x100;
+ if (offset >= 0x1800)
return m_reg[offset & 0x03];
- return 0x00;
+ return get_open_bus();
}
-/* writes to 0x8000-0xffff are like MMC3 but no PRG bankswitch (beacuse it is handled by low writes) */
+// writes to 0x8000-0xffff are like MMC3 but no PRG bankswitch (because it is handled by low writes)
void nes_gouder_device::prg_cb(int start, int bank)
{
- return;
}
@@ -1698,7 +1955,7 @@ void nes_gouder_device::prg_cb(int start, int bank)
Sachen boards used for a chinese port of Princess Maker (?)
- in MESS: Very Preliminary support, based on Cah4e3
+ in MAME: Very Preliminary support, based on Cah4e3
code in FCEUMM
-------------------------------------------------*/
@@ -1724,7 +1981,7 @@ void nes_sa9602b_device::prg_cb(int start, int bank)
void nes_sa9602b_device::write_h(offs_t offset, uint8_t data)
{
- LOG_MMC(("sa9602b write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("sa9602b write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x6001)
{
@@ -1733,7 +1990,7 @@ void nes_sa9602b_device::write_h(offs_t offset, uint8_t data)
break;
case 0x0001:
if ((m_reg & 7) < 6)
- m_prg_chip = (data & 0xc0) >> 6;
+ m_prg_chip = BIT(data, 6, 2);
set_prg(0, m_prg_mask);
break;
}
@@ -1747,24 +2004,23 @@ void nes_sa9602b_device::write_h(offs_t offset, uint8_t data)
Sachen boards used for Street Heroes
- in MESS: Very Preliminary support
+ NES 2.0: mapper 262
- -------------------------------------------------*/
+ In MAME: Supported.
+ -------------------------------------------------*/
-void nes_sachen_shero_device::chr_cb( int start, int bank, int source )
+void nes_sachen_shero_device::chr_cb(int start, int bank, int source)
{
- int shift = start < 2 ? 5 :
- start < 4 ? 6 :
- start < 6 ? 8 : 7;
+ static constexpr u8 shift[4] = {5, 6, 8, 7};
+
if (!BIT(m_reg, 6))
- chr1_x(start, ((m_reg << shift) & 0x100) | bank, source);
+ chr1_x(start, ((m_reg << shift[start >> 1]) & 0x100) | bank, source);
}
-
-void nes_sachen_shero_device::write_l(offs_t offset, uint8_t data)
+void nes_sachen_shero_device::write_l(offs_t offset, u8 data)
{
- LOG_MMC(("shero write_l, offset: %04x, data: %02x\n", offset, data));
+ LOG("shero write_l, offset: %04x, data: %02x\n", offset, data);
offset += 0x4100;
if (offset == 0x4100)
@@ -1777,16 +2033,145 @@ void nes_sachen_shero_device::write_l(offs_t offset, uint8_t data)
}
}
-uint8_t nes_sachen_shero_device::read_l(offs_t offset)
+u8 nes_sachen_shero_device::read_l(offs_t offset)
{
- LOG_MMC(("shero read_l, offset: %04x\n", offset));
+ LOG("shero read_l, offset: %04x\n", offset);
offset += 0x4100;
if (offset == 0x4100)
+ return m_jumper->read();
+ else
+ return get_open_bus();
+}
+
+/*-------------------------------------------------
+
+ SACHEN-ZGDH
+
+ Sachen board used for Zhongguo Daheng
+
+ NES 2.0: mapper 512
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+u8 nes_sachen_zgdh_device::nt_r(offs_t offset)
+{
+ if (m_reg == 1)
+ return m_vram[0x1000 + (offset & 0x0fff)];
+ else
+ return device_nes_cart_interface::nt_r(offset);
+}
+
+void nes_sachen_zgdh_device::nt_w(offs_t offset, u8 data)
+{
+ if (m_reg == 1)
+ m_vram[0x1000 + (offset & 0x0fff)] = data;
+ else
+ device_nes_cart_interface::nt_w(offset, data);
+}
+
+void nes_sachen_zgdh_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (m_reg <= 1)
+ {
+ chr = CHRROM;
+ m_chr_mask = 0x7f;
+ }
+ else
{
- // DSW read!
+ chr = CHRRAM;
+ m_chr_mask = 0x03;
+ }
+ nes_txrom_device::set_chr(chr, chr_base, m_chr_mask);
+}
+
+void nes_sachen_zgdh_device::write_l(offs_t offset, u8 data)
+{
+ LOG("zgdh write_l, offset: %04x, data: %02x\n", offset, data);
+
+ offset += 0x100;
+ if ((offset & 0x1100) == 0x0100)
+ {
+ m_reg = data & 0x03;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+/*-------------------------------------------------
+
+ UNL-A9746
+
+ Games: Toy Story, Super 1997 4 in 1 (NT-8029)
+
+ MMC3 clone
+
+ iNES: mapper 219
+
+ Preliminary emulation based on Cah4e3's code
+
+ -------------------------------------------------*/
+
+void nes_a9746_device::update_banks(uint8_t value)
+{
+ uint8_t bank = bitswap<8>(value & 0x3c,7,6,0,1,2,3,4,5);
+
+ switch (m_reg[0])
+ {
+ case 0x26: prg8_89(bank); break;
+ case 0x25: prg8_ab(bank); break;
+ case 0x24: prg8_cd(bank); break;
+ case 0x23: prg8_ef(bank); break;
+ }
+
+ switch (m_reg[1])
+ {
+ case 0x08: case 0x0a: case 0x0c: case 0x0e:
+ case 0x10: case 0x12: case 0x14: case 0x16:
+ case 0x18: case 0x1a: case 0x1c: case 0x1e:
+ m_reg[2] = value << 4;
+ break;
+ case 0x09: chr1_0(m_reg[2] | (value >> 1), m_chr_source); break;
+ case 0x0b: chr1_1(m_reg[2] | (value >> 1) | 1, m_chr_source); break;
+ case 0x0d: chr1_2(m_reg[2] | (value >> 1), m_chr_source); break;
+ case 0x0f: chr1_3(m_reg[2] | (value >> 1) | 1, m_chr_source); break;
+ case 0x11: chr1_4(m_reg[2] | (value >> 1), m_chr_source); break;
+ case 0x15: chr1_5(m_reg[2] | (value >> 1), m_chr_source); break;
+ case 0x19: chr1_6(m_reg[2] | (value >> 1), m_chr_source); break;
+ case 0x1d: chr1_7(m_reg[2] | (value >> 1), m_chr_source); break;
+ }
+}
+
+void nes_a9746_device::write_h(offs_t offset, uint8_t data)
+{
+ LOG("unl_a9746 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ switch (offset & 0x6003)
+ {
+ case 0x0000:
+ m_reg[1] = data;
+ m_reg[0] = 0;
+ break;
+ case 0x0001:
+ update_banks(data);
+ break;
+ case 0x0002:
+ m_reg[0] = data;
+ m_reg[1] = 0;
+ break;
+
+ case 0x0003:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ break;
+
+ default:
+ txrom_write(offset, data);
+ break;
}
- return get_open_bus(); // open bus
}
@@ -1797,16 +2182,16 @@ uint8_t nes_sachen_shero_device::read_l(offs_t offset)
-------------------------------------------------*/
- /*-------------------------------------------------
+/*-------------------------------------------------
- Board BMC-FK23C
+ Board BMC-FK23C
- MMC3 clone
+ MMC3 clone
- In MESS: partially supported (still to sort initial banking
- for many games)
+ In MAME: partially supported (still to sort initial banking
+ for many games)
- -------------------------------------------------*/
+ -------------------------------------------------*/
#if 0
// alt version...
@@ -1851,7 +2236,7 @@ void nes_fk23c_device::chr_cb(int start, int bank, int source)
void nes_fk23c_device::fk23c_set_prg()
{
if ((m_reg[0] & 0x07) == 4)
- prg32((m_reg[1] & 0x7f) >> 1);
+ prg32(BIT(m_reg[1], 1, 6));
else if ((m_reg[0] & 0x07) == 3)
{
prg16_89ab(m_reg[1] & 0x7f);
@@ -1888,7 +2273,7 @@ void nes_fk23c_device::fk23c_set_chr()
void nes_fk23c_device::write_l(offs_t offset, uint8_t data)
{
- LOG_MMC(("fk23c write_l, offset: %04x, data: %02x\n", offset, data));
+ LOG("fk23c write_l, offset: %04x, data: %02x\n", offset, data);
offset += 0x100;
if (offset >= 0x1000)
@@ -1905,7 +2290,7 @@ void nes_fk23c_device::write_l(offs_t offset, uint8_t data)
void nes_fk23c_device::write_h(offs_t offset, uint8_t data)
{
- LOG_MMC(("fk23c write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("fk23c write_h, offset: %04x, data: %02x\n", offset, data);
if (m_reg[0] & 0x40)
{
@@ -1945,11 +2330,40 @@ void nes_fk23c_device::write_h(offs_t offset, uint8_t data)
/*-------------------------------------------------
+ BMC-NT-639
+
+ Unknown Bootleg Multigame Board
+ Games: 2 in 1 Mortal Kombat VI/VII
+
+ NES 2.0: mapper 291
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_nt639_device::write_m(offs_t offset, u8 data)
+{
+ LOG("nt639 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (BIT(data, 5))
+ prg32(bitswap<3>(data, 6, 2, 1));
+ else
+ {
+ m_prg_base = (data & 0x40) >> 2;
+ set_prg(m_prg_base, m_prg_mask);
+ }
+
+ m_chr_base = (data & 0x40) << 2;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+}
+
+/*-------------------------------------------------
+
Board BMC-SUPER24IN1SC03
Games: Super 24-in-1
- In MESS: Partially Supported
+ In MAME: Partially Supported
-------------------------------------------------*/
@@ -1973,7 +2387,7 @@ void nes_s24in1sc03_device::chr_cb(int start, int bank, int source)
void nes_s24in1sc03_device::write_l(offs_t offset, uint8_t data)
{
- LOG_MMC(("s24in1sc03 write_l, offset: %04x, data: %02x\n", offset, data));
+ LOG("s24in1sc03 write_l, offset: %04x, data: %02x\n", offset, data);
offset += 0x100;
if (offset == 0x1ff0)
@@ -1998,30 +2412,147 @@ void nes_s24in1sc03_device::write_l(offs_t offset, uint8_t data)
/*-------------------------------------------------
- BMC-15IN1
+ BMC-TECHLINE9IN1
Unknown Bootleg Multigame Board
- Games: 3 in 1, 15 in 1
+ Games: 9 in 1
- iNES: mapper 205, MMC3 clone
+ NES 2.0: mapper 351
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_bmc_15in1_device::write_m(offs_t offset, uint8_t data)
+void nes_tech9in1_device::update_banks()
{
- LOG_MMC(("bmc_15in1 write_m, offset: %04x, data: %02x\n", offset, data));
-
- if (offset & 0x0800)
+ if (BIT(m_reg[2], 7)) // NROM mode
{
- m_prg_base = (data & 0x03) << 4;
- m_prg_mask = (data & 0x02) ? 0x0f : 0x1f;
- m_chr_base = (data & 0x03) << 7;
- m_chr_mask = (data & 0x02) ? 0x7f : 0xff;
+ u8 bank = m_reg[1] >> 2;
+ u8 mode = !BIT(m_reg[2], 6);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
+ else // MMC3 mode
+ {
+ m_prg_base = (m_reg[1] & 0xfc) >> 1;
+ m_prg_mask = 0x1f >> BIT(m_reg[2], 5);
set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
+
+ m_chr_base = (m_reg[0] & 0xfc) << 1;
+ m_chr_mask = BIT(m_reg[2], 7) ? 0x1f : 0xff >> BIT(m_reg[2], 5);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+}
+
+void nes_tech9in1_device::write_l(offs_t offset, u8 data)
+{
+ LOG("tech9in1 write_l, offset: %04x, data: %02x\n", offset, data);
+ offset += 0x100;
+
+ switch (offset & 0x1003) // writes $5000-$5002, mask is a best guess
+ {
+ case 0x1000: case 0x1001: case 0x1002:
+ m_reg[offset & 3] = data;
+ update_banks();
+ break;
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-5IN1
+
+ Unknown Bootleg Multigame Board
+ Games: 5 in 1 1993 Copyright
+
+ NES 2.0: mapper 334
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+u8 nes_bmc_5in1_device::read_m(offs_t offset)
+{
+ LOG("bmc_5in1 read_m, offset: %04x\n", offset);
+
+ if ((offset & 0x03) == 0x02)
+ return (get_open_bus() & 0xfe) | m_jumper->read();
+ else
+ return get_open_bus();
+}
+
+void nes_bmc_5in1_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_5in1 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if ((m_wram_protect & 0xc0) == 0x80)
+ {
+ if (!(offset & 0x03))
+ prg32(BIT(data, 1, 2));
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-NEWSTAR-GRM070-8IN1
+
+ Unknown Bootleg Multigame Board
+ Games: New Star Super 8 in 1
+
+ NES 2.0: mapper 333
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_8in1_device::write_h(offs_t offset, u8 data)
+{
+ LOG("bmc_8in1 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ if (BIT(offset, 12))
+ {
+ if (BIT(data, 4))
+ {
+ m_prg_base = (data & 0x0c) << 2;
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = m_prg_base << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+ else
+ prg32(data & 0x0f);
+ }
+ else
+ txrom_write(offset, data);
+}
+
+/*-------------------------------------------------
+
+ BMC-15IN1 (PCB JC-016-2?)
+
+ Games: 3 in 1, 15 in 1
+
+ MMC3 clone with banking for multigame menu.
+
+ iNES: mapper 205
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_15in1_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_15in1 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (data & 1)
+ data |= m_jumper; // TODO: add jumper settings, m_jumper is 0 for now
+
+ m_prg_base = (data & 0x03) << 4;
+ m_prg_mask = 0x1f >> BIT(data, 1);
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = m_prg_base << 3;
+ m_chr_mask = 0xff >> BIT(data, 1);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
/*-------------------------------------------------
@@ -2033,18 +2564,18 @@ void nes_bmc_15in1_device::write_m(offs_t offset, uint8_t data)
iNES: mapper 44
- In MESS: Supported. It also uses mmc3_irq.
+ In MAME: Supported. It also uses mmc3_irq.
-------------------------------------------------*/
void nes_bmc_sbig7_device::write_h(offs_t offset, uint8_t data)
{
uint8_t page;
- LOG_MMC(("bmc_sbig7 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("bmc_sbig7 write_h, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x6001)
{
- case 0x2001: /* $a001 - Select 128K ROM/VROM base (0..5) or last 256K ROM/VRAM base (6) */
+ case 0x2001: // $a001 - Select 128K ROM/VROM base (0..5) or last 256K ROM/VRAM base (6)
page = (data & 0x07);
if (page > 6)
page = 6;
@@ -2068,50 +2599,169 @@ void nes_bmc_sbig7_device::write_h(offs_t offset, uint8_t data)
BMC-HIK8IN1
Known Boards: Unknown Multigame Bootleg Board
- Games: Street Fighter V, various multigame carts
+ Games: Many, many multigame carts
iNES: mapper 45
- In MESS: Supported. It also uses mmc3_irq.
+ In MAME: Supported. It also uses mmc3_irq.
+
+ -------------------------------------------------*/
+
+void nes_bmc_hik8_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_hik8 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ nes_txrom_device::write_m(offset, data); // registers overlay WRAM
+
+ if (!BIT(m_reg[3], 6)) // outer register lock bit
+ {
+ m_reg[m_count] = data;
+ m_count = (m_count + 1) & 0x03;
+
+ m_prg_base = (m_reg[2] & 0xc0) << 2 | m_reg[1];
+ m_prg_mask = ~m_reg[3] & 0x3f;
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = (m_reg[2] & 0xf0) << 4 | m_reg[0];
+ m_chr_mask = 0xff >> (~m_reg[2] & 0x0f);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-JY-208
+
+ Games: Rockman 7 in 1
+
+ Variant of the HIK8IN1 boards that adds 8K of VRAM
+ to be used presumably by Rockman 4/6 and a 4 screen
+ mirroring mode for Sachen's Rocman X.
+
+ NES 2.0: mapper 356
+
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_bmc_hik8_device::write_m(offs_t offset, uint8_t data)
+void nes_bmc_jy208_device::set_chr(u8 chr, int chr_base, int chr_mask)
{
- LOG_MMC(("bmc_hik8 write_m, offset: %04x, data: %02x\n", offset, data));
+ if (BIT(m_reg[2], 5))
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+ else
+ chr8(0, CHRRAM);
+}
+
+void nes_bmc_jy208_device::write_m(offs_t offset, u8 data)
+{
+ nes_bmc_hik8_device::write_m(offset, data);
- /* This bit is the "register lock". Once register are locked, writes go to WRAM
- and there is no way to unlock them (except by resetting the machine) */
- if ((m_reg[3] & 0x40) && !m_prgram.empty())
- m_prgram[offset] = data;
+ if (BIT(m_reg[2], 6))
+ m_mirroring = PPU_MIRROR_4SCREEN; // prevent MMC3 mirror switching
else
+ m_mirroring = BIT(m_mmc_mirror, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT; // allow MMC3 mirror switching and get its current setting
+
+ set_nt_mirroring(m_mirroring); // actually change nametable pointers
+}
+
+/*-------------------------------------------------
+
+ BMC-JY-302
+
+ Games: Super 8 in 1
+
+ Variant of the HIK8IN1 boards that adds 8K of VRAM
+ which seems the same as the SFC-12 board below,
+ other than the line which selects VRAM/VROM.
+
+ NES 2.0: mapper 410
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_jy302_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (BIT(m_reg[2], 6))
+ chr8(0, CHRRAM);
+ else
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+}
+
+/*-------------------------------------------------
+
+ BMC-KC885
+
+ Games: Super 8 in 1 VIP19
+
+ Variant of the HIK8IN1 boards that has different
+ upper address lines for PRG banking. Exactly how
+ these lines are selected is determined by three
+ jumper/solder pads.
+
+ NES 2.0: mapper 401
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+u8 nes_bmc_kc885_device::read_h(offs_t offset)
+{
+ LOGMASKED(LOG_HIFREQ, "bmc_kc885 read_h, offset: %04x\n", offset);
+
+ if (BIT(m_reg[1], 7) & BIT(m_jumper->read(), 2))
+ return get_open_bus();
+ else
+ return hi_access_rom(offset);
+}
+
+void nes_bmc_kc885_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_kc885 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (!BIT(m_reg[3], 6)) // outer register lock bit
{
+ if (m_count == 1)
+ data = (data & ~0x60) | bitswap<2>(data, 5, 6) << 5;
m_reg[m_count] = data;
m_count = (m_count + 1) & 0x03;
- if (!m_count)
- {
- LOG_MMC(("bmc_hik8 write_m, command completed %02x %02x %02x %02x\n", m_reg[3],
- m_reg[2], m_reg[1], m_reg[0]));
-
- m_prg_base = m_reg[1];
- m_prg_mask = 0x3f ^ (m_reg[3] & 0x3f);
- m_chr_base = ((m_reg[2] & 0xf0) << 4) | m_reg[0];
- if (BIT(m_reg[2], 3))
- m_chr_mask = (1 << ((m_reg[2] & 7) + 1)) - 1;
- else if (m_reg[2])
- m_chr_mask = 0;
- else
- m_chr_mask = 0xff; // i.e. we use the vrom_bank with no masking
+ u8 mask = 0x80 | (m_jumper->read() & 0x03) << 5;
+ m_prg_base = (m_reg[2] & mask) | (m_reg[1] & ~mask);
+ m_prg_mask = ~m_reg[3] & 0x1f;
+ set_prg(m_prg_base, m_prg_mask);
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- }
+ m_chr_base = (m_reg[2] & 0xf0) << 4 | m_reg[0];
+ m_chr_mask = 0xff >> (~m_reg[2] & 0x0f);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
}
/*-------------------------------------------------
+ BMC-SFC-12
+
+ Games: Rockman 6 in 1 (alt 2)
+
+ Variant of the HIK8IN1 boards that adds 8K of VRAM
+ to be used presumably by Rockman 4/6.
+
+ NES 2.0: mapper 372
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_sfc12_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (BIT(m_reg[2], 5))
+ chr8(0, CHRRAM);
+ else
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+}
+
+/*-------------------------------------------------
+
BMC-SUPERHIK-4IN1
Known Boards: Unknown Multigame Bootleg Board
@@ -2119,73 +2769,253 @@ void nes_bmc_hik8_device::write_m(offs_t offset, uint8_t data)
iNES: mapper 49
- In MESS: Supported. It also uses mmc3_irq.
+ In MAME: Supported. It also uses mmc3_irq.
-------------------------------------------------*/
-void nes_bmc_hik4_device::write_m(offs_t offset, uint8_t data)
+void nes_bmc_hik4_device::prg_cb(int start, int bank)
{
- LOG_MMC(("bmc_hik4 write_m, offset: %04x, data: %02x\n", offset, data));
+ if (m_mmc3_mode) // all games use MMC3 PRG banking except Master Fighter III
+ nes_txrom_device::prg_cb(start, bank);
+}
- /* mid writes only work when WRAM is enabled. not sure if I should
- change the condition to m_mmc_latch2==0x80 (i.e. what is the effect of
- the read-only bit?) */
- if (m_wram_protect & 0x80)
+void nes_bmc_hik4_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_hik4 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ // mid writes only work when WRAM is enabled and writable
+ if ((m_wram_protect & 0xc0) == 0x80)
{
- if (data & 0x01) /* if this is 0, then we have 32k PRG blocks */
+ m_mmc3_mode = data & 0x01;
+ if (m_mmc3_mode)
{
m_prg_base = (data & 0xc0) >> 2;
- m_prg_mask = 0x0f;
set_prg(m_prg_base, m_prg_mask);
}
- else
- prg32((data & 0x30) >> 4);
+ else // Master Fighter III only
+ prg32(BIT(data, 4, 2));
m_chr_base = (data & 0xc0) << 1;
- m_chr_mask = 0x7f;
set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
}
/*-------------------------------------------------
- BMC-MARIOPARTY-7IN1
+ BMC-A88S-1
- Known Boards: Unknown Multigame Bootleg Board
- Games: Mario 7 in 1
+ Games: 1997 Super 7 in 1, 6 in 1 (JY-201 to JY-206)
- MMC3 clone
+ MMC3 clone with banking for multigame menu.
- iNES: mapper 52
+ NES 2.0: mapper 411
+
+ In MAME: Preliminary supported.
- In MESS: Supported.
+ TODO: Investigate...
+ - Hokuto no Ken has broken sound on each cart it's on.
+ - Bird Fighter boss fights have corrupt graphics.
+ - whether not being able to reset from within certain
+ games is correct. Examples are Samurai (title scroll
+ only) and Bomber Man (in game only) on JY-202, or
+ SD Gunman in JY-204.
-------------------------------------------------*/
-void nes_bmc_mario7in1_device::write_m(offs_t offset, uint8_t data)
+void nes_a88s1_device::update_banks()
+{
+ u8 outer = bitswap<2>(m_reg[1], 6, 3);
+ u8 size_128k = !BIT(m_reg[1], 1);
+
+ if (BIT(m_reg[0], 6)) // NROM mode
+ {
+ u8 bank = outer << 3 | bitswap<3>(m_reg[0], 2, 3, 0);
+ u8 mode = BIT(m_reg[0], 1);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
+ else // MMC3 mode
+ {
+ m_prg_base = (outer & (0xfe | size_128k)) << 4;
+ m_prg_mask = 0x1f >> size_128k;
+ set_prg(m_prg_base, m_prg_mask);
+ }
+
+ m_chr_base = (m_reg[0] & 0x10) << 4 | (BIT(m_reg[1], 2) & size_128k) << 7;
+ m_chr_mask = 0xff >> size_128k;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+}
+
+void nes_a88s1_device::prg_cb(int start, int bank)
+{
+ if (!BIT(m_reg[0], 6))
+ nes_txrom_device::prg_cb(start, bank);
+}
+
+void nes_a88s1_device::write_l(offs_t offset, u8 data)
+{
+ LOG("a88s1 write_l, offset: %04x, data: %02x\n", offset, data);
+
+ offset += 0x100;
+ if (offset >= 0x1000)
+ {
+ m_reg[offset & 1] = data;
+ update_banks();
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-F-15
+
+ Unknown Multigame Bootleg Board
+ Games: 150 in 1 Unchained Melody
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 259
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_f15_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_f15 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (BIT(m_wram_protect, 7))
+ {
+ u8 bank = data & 0x0f;
+ u8 mode = BIT(data, 3);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
+}
+
+void nes_bmc_f15_device::prg_cb(int start, int bank)
+{
+ // Ignore MMC3 PRG bank switching. Master Fighter II (game #150) uses the bank switching above.
+}
+
+/*-------------------------------------------------
+
+ BMC-F600
+
+ Games: Golden Mario Party II 6 in 1
+
+ MMC3 clone with banking for multigame menu. Note,
+ this cart has one TxSROM game (SMB4) and so it uses
+ the nonstandard MMC3 mirroring of those boards.
+
+ NES 2.0: mapper 370
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+u8 nes_bmc_f600_device::read_l(offs_t offset)
+{
+ LOG("bmc_f600 read_l, offset: %04x\n", offset);
+
+ offset += 0x100;
+ if (offset >= 0x1000)
+ return (get_open_bus() & 0x7f) | m_jumper->read();
+ else
+ return get_open_bus();
+}
+
+void nes_bmc_f600_device::write_l(offs_t offset, u8 data)
+{
+ LOG("bmc_f600 write_l, offset: %04x, data: %02x\n", offset, data);
+
+ offset += 0x100;
+ if (offset >= 0x1000)
+ {
+ m_reg = offset;
+
+ m_prg_base = (m_reg & 0x38) << 1;
+ m_prg_mask = 0x1f >> BIT(m_reg, 5);
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = (m_reg & 0x07) << 7;
+ m_chr_mask = 0xff >> BIT(~m_reg, 2);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+void nes_bmc_f600_device::write_h(offs_t offset, u8 data)
{
- uint8_t helper1, helper2;
- LOG_MMC(("bmc_mario7in1 write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("bmc_f600 write_h, offset: %04x, data: %02x\n", offset, data);
+ if ((m_reg & 0x07) == 1)
+ nes_txsrom_device::write_h(offset, data);
+ else
+ nes_txrom_device::write_h(offset, data);
+}
+
+void nes_bmc_f600_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if ((m_reg & 0x07) == 1)
+ nes_txsrom_device::set_chr(chr, chr_base, chr_mask);
+ else
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+}
+
+/*-------------------------------------------------
+
+ BMC EL860947C and EL861121C boards
+
+ Games: 8 in 1 (JY-111, JY-112, and JY-119)
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 267 and mapper 377
- /* mid writes only work when WRAM is enabled. not sure if I should
- change the condition to m_map52_reg_written == 0x80 (i.e. what is the effect of
- the read-only bit?) and it only can happen once! */
- if ((m_wram_protect & 0x80) && !m_reg_written)
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_el86xc_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_el86xc write_m, offset: %04x, data: %02x\n", offset, data);
+ if (!(offset & 0x1000)) // game only banks via 0x6000, this mask is a guess
{
- helper1 = (data & 0x08);
- helper2 = (data & 0x40);
+ int outer = bitswap<3>(data, 5, 2, 1);
+ m_prg_base = outer << (31 - count_leading_zeros_32(m_outer_prg_size) - 3); // << std::countr_zero(m_outer_prg_size) - 3; in C++20
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = outer << 7;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-GN-45
- m_prg_base = helper1 ? ((data & 0x07) << 4) : ((data & 0x06) << 4);
- m_prg_mask = helper1 ? 0x0f : 0x1f;
- m_chr_base = ((data & 0x20) << 4) | ((data & 0x04) << 6) | (helper2 ? ((data & 0x10) << 3) : 0);
- m_chr_mask = helper2 ? 0x7f : 0xff;
+ Games: 4 in 1 (K-3131GS and K-3131SS)
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 366
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_gn45_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_gn45 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ nes_txrom_device::write_m(offset, data); // registers overlay WRAM
+
+ if (!m_lock)
+ {
+ m_prg_base = offset & 0x70;
set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = m_prg_base << 3;
set_chr(m_chr_source, m_chr_base, m_chr_mask);
- m_reg_written = 1;
+ m_lock = BIT(offset, 7);
}
- else
- m_prgram[offset] = data;
}
/*-------------------------------------------------
@@ -2195,241 +3025,529 @@ void nes_bmc_mario7in1_device::write_m(offs_t offset, uint8_t data)
Known Boards: Unknown Multigame Bootleg Board
Games: Super HIK Gold 7 in 1, Golden 7 in 1 and many more
- MMC3 clone, same as BMC-MARIOPARTY-7IN1 but with switched CHR
- bank lines
+ MMC3 clone with banking for multigame menu.
iNES: mapper 52
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_bmc_gold7in1_device::write_m(offs_t offset, uint8_t data)
+void nes_bmc_gold7in1_device::write_m(offs_t offset, u8 data)
{
- uint8_t helper1, helper2;
- LOG_MMC(("bmc_gold7in1 write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("bmc_gold7in1 write_m, offset: %04x, data: %02x\n", offset, data);
- if ((m_wram_protect & 0x80) && !m_reg_written)
+ if ((m_wram_protect & 0xc0) == 0x80 && !m_lock)
{
- helper1 = (data & 0x08);
- helper2 = (data & 0x40);
+ u8 prg128k = BIT(data, 3);
+ u8 chr128k = BIT(data, 6);
- m_prg_base = helper1 ? ((data & 0x07) << 4) : ((data & 0x06) << 4);
- m_prg_mask = helper1 ? 0x0f : 0x1f;
- m_chr_base = ((data & 0x20) << 3) | ((data & 0x04) << 7) | (helper2 ? ((data & 0x10) << 3) : 0);
- m_chr_mask = helper2 ? 0x7f : 0xff;
+ m_prg_base = (data & (0x06 | prg128k)) << 4;
+ m_prg_mask = 0x1f >> prg128k;
+ m_chr_base = (bitswap<3>(data, 2, 5, 4) & (0x06 | chr128k)) << 7;
+ m_chr_mask = 0xff >> chr128k;
set_prg(m_prg_base, m_prg_mask);
set_chr(m_chr_source, m_chr_base, m_chr_mask);
- m_reg_written = BIT(data, 7); // mc_2hikg & mc_s3nt3 write here multiple time
+ m_lock = BIT(data, 7); // mc_2hikg & mc_s3nt3 write here multiple time
}
else
- m_prgram[offset] = data;
+ nes_txrom_device::write_m(offset, data); // write WRAM
}
/*-------------------------------------------------
- BMC-GOLDENCARD-6IN1
+ BMC-K-3006
- Known Boards: Unknown Bootleg Multigame Board
- Games: Golden Card 6 in 1
+ Games: 21 in 1
- MMC3 clone
+ MMC3 clone with banking for multigame menu.
- iNES: mapper 217
+ NES 2.0: mapper 339
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_bmc_gc6in1_device::prg_cb(int start, int bank)
+void nes_bmc_k3006_device::write_m(offs_t offset, u8 data)
{
- if (m_reg[1] & 0x08)
- bank &= 0x1f;
- else
+ LOG("bmc_k3006 write_m, offset: %04x, data: %02x\n", offset, data);
+ if ((m_wram_protect & 0xc0) == 0x80)
{
- bank &= 0x0f;
- bank |= m_reg[1] & 0x10;
+ if (BIT(offset, 5)) // MMC3 mode
+ {
+ m_prg_base = (offset & 0x18) << 1;
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = m_prg_base << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+ else // NROM mode
+ {
+ u8 bank = offset & 0x1f;
+ u8 mode = (offset & 0x06) == 0x06;
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
}
-
- prg8_x(start, bank | ((m_reg[1] & 0x03) << 5));
}
-void nes_bmc_gc6in1_device::chr_cb(int start, int bank, int source)
-{
- if (!(m_reg[1] & 0x08))
- bank = ((m_reg[1] & 0x10) << 3) | (bank & 0x7f);
+/*-------------------------------------------------
+
+ BMC-K-3033
+ Games: 35 in 1
- bank |= ((m_reg[1] << 6) & 0x100);
- chr1_x(start, ((m_reg[1] & 0x03) << 8) | bank, source);
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 322
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_k3033_device::prg_cb(int start, int bank)
+{
+ if (m_mmc3_mode)
+ nes_txrom_device::prg_cb(start, bank);
}
-void nes_bmc_gc6in1_device::write_l(offs_t offset, uint8_t data)
+void nes_bmc_k3033_device::write_m(offs_t offset, u8 data)
{
- uint8_t bank;
- LOG_MMC(("bmc_gc6in1 write_l, offset: %04x, data: %02x\n", offset, data));
- offset += 0x100;
+ LOG("bmc_k3033 write_m, offset: %04x, data: %02x\n", offset, data);
- if (offset == 0x1000)
+ if ((m_wram_protect & 0xc0) == 0x80)
{
- m_reg[0] = data;
- if (data & 0x80)
+ m_mmc3_mode = BIT(offset, 5);
+
+ u8 mode_128k = !(BIT(offset, 7) && m_mmc3_mode);
+ m_chr_base = bitswap<3>(offset, 6, 4, 3) << (8 - mode_128k);
+ m_chr_mask = 0xff >> mode_128k;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+
+ if (m_mmc3_mode)
{
- bank = (data & 0x0f) | ((m_reg[1] & 0x03) << 4);
- prg16_89ab(bank);
- prg16_cdef(bank);
- }
- else
+ m_prg_base = m_chr_base >> 3;
+ m_prg_mask = m_chr_mask >> 3;
set_prg(m_prg_base, m_prg_mask);
+ }
+ else // NROM mode
+ {
+ u8 bank = (offset & 0x40) >> 1 | (offset & 0x1f);
+ u8 mode = !!(offset & 0x03);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
}
- else if (offset == 0x1001)
+}
+
+/*-------------------------------------------------
+
+ BMC-L6IN1
+
+ Games: New Star 6 in 1
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 345
+
+ Note: Cabal leaves the APU in a bad state so that
+ after soft resetting and loading Track & Field there
+ is a constant drone pitch. This is likely a game bug.
+
+ -------------------------------------------------*/
+
+void nes_bmc_l6in1_device::set_prg(int prg_base, int prg_mask)
+{
+ if (m_reg & 0x0c) // MMC3 mode
+ nes_txrom_device::set_prg(prg_base, prg_mask);
+ else // AxROM mode
+ prg32(prg_base >> 2 | (m_reg & 0x03));
+}
+
+void nes_bmc_l6in1_device::set_mirror()
+{
+ if (BIT(m_reg, 5))
+ set_nt_mirroring(BIT(m_reg, 4) ? PPU_MIRROR_HIGH : PPU_MIRROR_LOW);
+ else
+ set_nt_mirroring(m_mmc_mirror ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
+}
+
+void nes_bmc_l6in1_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_l6in1 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if ((m_wram_protect & 0xc0) == 0x80)
{
- m_reg[1] = data;
+ m_reg = data;
+ m_prg_base = (m_reg & 0xc0) >> 2;
set_prg(m_prg_base, m_prg_mask);
+ set_mirror();
}
- else if (offset == 0x1007)
+}
+
+void nes_bmc_l6in1_device::write_h(offs_t offset, u8 data)
+{
+ LOG("bmc_l6in1 write_h, offset: %04x, data: %02x\n", offset, data);
+
+ txrom_write(offset, data);
+ if ((offset & 0x6001) == 0x2000)
+ set_mirror();
+}
+
+/*-------------------------------------------------
+
+ BMC-00202650
+
+ Games: 8 in 1
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 392
+
+ In MAME: Supported.
+
+ TODO: Soft reset doesn't work for some games some of
+ the time. Seems to be caused by main RAM contents.
+ Does this happen on hardware?
+
+ -------------------------------------------------*/
+
+void nes_bmc_00202650_device::set_prg(int prg_base, int prg_mask)
+{
+ if (m_mmc3_mode)
+ nes_txrom_device::set_prg(prg_base, prg_mask);
+}
+
+void nes_bmc_00202650_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (m_mmc3_mode)
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+}
+
+void nes_bmc_00202650_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_00202650 write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (!m_mmc3_mode)
{
- m_reg[2] = data;
+ m_mmc3_mode = BIT(data, 4);
+
+ m_prg_base = (data & 0x07) << 4;
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = m_prg_base << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
}
-void nes_bmc_gc6in1_device::write_h(offs_t offset, uint8_t data)
+/*-------------------------------------------------
+
+ BMC-411120C, BMC-810849-C
+
+ Games: 4 in 1, 19 in 1
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 287
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_411120c_device::prg_cb(int start, int bank)
{
- uint8_t cmd;
- static const uint8_t conv_table[8] = {0, 6, 3, 7, 5, 2, 4, 1};
- LOG_MMC(("bmc_gc6in1 write_h, offset: %04x, data: %02x\n", offset, data));
+ if (!BIT(m_reg, 3)) // all games use MMC3 PRG banking except Master Fighter II
+ nes_txrom_device::prg_cb(start, bank);
+}
+
+void nes_bmc_411120c_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_411120c write_m, offset: %04x, data: %02x\n", offset, data);
- if (!m_reg[2])
+ if (BIT(m_wram_protect, 7))
{
- // in this case we act like MMC3, only with alt prg/chr handlers
- txrom_write(offset, data);
+ m_reg = offset;
+ if (BIT(m_reg, 3))
+ prg32(bitswap<5>(m_reg, 2, 1, 0, 5, 4));
+ else
+ {
+ m_prg_base = (m_reg & 0x07) << 4;
+ set_prg(m_prg_base, m_prg_mask);
+ }
+ m_chr_base = (m_reg & 0x07) << 7;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
- else
+}
+
+/*-------------------------------------------------
+
+ BMC-81-03-05-C
+
+ Games: 92' Super Mario Family
+
+ MMC3 clone with banking for multigame menu. Note,
+ this cart has one TxSROM game (SMB4) and so it uses
+ the nonstandard MMC3 mirroring of those boards.
+
+ NES 2.0: mapper 353
+
+ In MAME: Partially supported.
+
+ TODO: Banking isn't quite right. Golden Mario, the
+ 4th game, should be SMB2J but loads as plain old
+ Mario Bros with garbled graphics. Golden Mario
+ should be on the last outer bank #3.
+
+ -------------------------------------------------*/
+
+void nes_bmc_810305c_device::set_prg(int prg_base, int prg_mask)
+{
+ u8 a17 = BIT(m_mmc_vrom_bank[0], 7);
+
+ nes_txrom_device::set_prg(prg_base | (m_outer == 2 && a17) << 4, prg_mask);
+
+ if (m_outer == 3 && !a17)
{
- switch (offset & 0x6001)
- {
- case 0x0000:
- txrom_write(0x4000, data);
- break;
+ prg8_cd(m_mmc_prg_bank[0] | 0x70);
+ prg8_ef(m_mmc_prg_bank[1] | 0x70);
+ }
+}
- case 0x0001:
- data = (data & 0xc0) | conv_table[data & 0x07];
- m_reg[3] = 1;
- txrom_write(0x0000, data);
- break;
+void nes_bmc_810305c_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (m_outer == 2 && BIT(m_mmc_vrom_bank[0], 7))
+ chr8(0, CHRRAM);
+ else if (m_outer)
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
+ else
+ nes_txsrom_device::set_chr(chr, chr_base, chr_mask);
+}
- case 0x2000:
- cmd = m_latch & 0x07;
- if (m_reg[3])
- {
- m_reg[3] = 0;
- switch (cmd)
- {
- case 0: case 1: // these do not need to be separated: we take care of them in set_chr!
- case 2: case 3: case 4: case 5:
- m_mmc_vrom_bank[cmd] = data;
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- break;
- case 6:
- case 7:
- m_mmc_prg_bank[cmd - 6] = data;
- set_prg(m_prg_base, m_prg_mask);
- break;
- }
- }
- break;
+void nes_bmc_810305c_device::write_h(offs_t offset, u8 data)
+{
+ LOG("bmc_810305c write_h, offset: %04x, data: %02x\n", offset, data);
+ if (BIT(offset, 7)) // outer register
+ {
+ m_outer = BIT(offset, 13, 2);
- case 0x2001:
- set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
- break;
+ m_prg_base = m_outer << 5;
+ m_prg_mask = 0x1f >> ((m_outer == 2) ? 1 : 0);
+ set_prg(m_prg_base, m_prg_mask);
- default:
- txrom_write(offset, data);
- break;
- }
+ m_chr_base = m_outer << 7;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
+ else if (m_outer) // standard MMC3 registers
+ nes_txrom_device::write_h(offset, data);
+ else // TxSROM MMC3 registers without mirroring bit
+ nes_txsrom_device::write_h(offset, data);
}
/*-------------------------------------------------
- BMC-411120C
+ BMC-820720C
+ Games: 1993 Super HiK 8 in 1 (G-002)
- MMC3 clone
+ MMC3 clone with banking for multigame menu.
+ NES 2.0: mapper 393
- In MESS: Very Preliminary Support
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_bmc_411120c_device::prg_cb(int start, int bank)
+void nes_bmc_820720c_device::set_prg(int prg_base, int prg_mask)
{
- if (m_reg & 8) // & 0xc when DSW change (diff menu?)
- prg32(((m_reg >> 4) & 3) | 0x0c);
+ switch (m_reg >> 4)
+ {
+ case 0: // MMC3 mode
+ case 1:
+ nes_txrom_device::set_prg(prg_base, prg_mask);
+ break;
+ case 2: // BNROM mode
+ prg32((prg_base | (m_mmc_prg_bank[BIT(m_latch, 6) << 1] & prg_mask)) >> 2);
+ break;
+ case 3: // UNROM mode
+ prg16_89ab(m_prg_base >> 1);
+ prg16_cdef(m_prg_base >> 1 | 0x07);
+ break;
+ }
+}
+
+void nes_bmc_820720c_device::set_chr(u8 chr, int chr_base, int chr_mask)
+{
+ if (BIT(m_reg, 3))
+ chr8(0, CHRRAM);
else
- prg8_x(start, (bank & 0x0f) | ((m_reg & 0x03) << 4));
+ nes_txrom_device::set_chr(chr, chr_base, chr_mask);
}
-void nes_bmc_411120c_device::chr_cb(int start, int bank, int source)
+void nes_bmc_820720c_device::write_m(offs_t offset, u8 data)
{
- chr1_x(start, bank | ((m_reg & 3) << 7), source);
+ LOG("bmc_820720c write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if ((m_wram_protect & 0xc0) == 0x80)
+ {
+ m_reg = offset & 0x3f;
+
+ m_prg_base = (m_reg & 0x07) << 4;
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = (m_reg & 0x01) << 8;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
}
-void nes_bmc_411120c_device::write_m(offs_t offset, uint8_t data)
+void nes_bmc_820720c_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("bmc_411120c write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("bmc_820720c write_h, offset: %04x, data: %02x\n", offset, data);
- m_reg = data;
- set_prg(m_prg_base, m_prg_mask);
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ txrom_write(offset, data); // MMC3 regs always written (for mirroring in non-MMC3 modes)
+
+ if ((m_reg & 0x30) == 0x30) // UNROM mode
+ {
+ prg16_89ab(m_prg_base >> 1 | (data & 0x07));
+ prg16_cdef(m_prg_base >> 1 | 0x07);
+ }
}
/*-------------------------------------------------
BMC-830118C
+ Games: 7 in 1 (EW-002, M-022, M-026, M-027)
- MMC3 clone
+ MMC3 clone with banking for multigame menu.
+ NES 2.0: mapper 348
- In MESS: Very Preliminary Support
+ In MAME: Preliminary supported.
+
+ TODO: Only M-022 seems to reliably soft reset to the
+ menu for all games. The other three carts are hit or
+ miss. MMC3 games in particular are not likely to
+ reset to the menu. Investigate further...
-------------------------------------------------*/
void nes_bmc_830118c_device::prg_cb(int start, int bank)
{
- if ((m_reg & 0x0c) != 0x0c)
- prg8_x(start, (bank & 0x0f) | ((m_reg & 0x0c) << 2));
- else
+ if (m_prg_base == 0x30)
{
- if (start == 0)
+ if (start <= 1)
{
- prg8_89((bank & 0x0f) | ((m_reg & 0x0c) << 2));
- prg8_ab((bank & 0x0f) | 0x20);
- }
- else if (start == 2)
- {
- prg8_cd((bank & 0x0f) | ((m_reg & 0x0c) << 2));
- prg8_ef((bank & 0x0f) | 0x20);
+ prg8_x(start, bank & ~2);
+ prg8_x(start + 2, bank | 2);
}
}
+ else
+ nes_txrom_device::prg_cb(start, bank);
}
-void nes_bmc_830118c_device::chr_cb(int start, int bank, int source)
+void nes_bmc_830118c_device::write_m(offs_t offset, u8 data)
{
- chr1_x(start, (bank & 0x7f) | ((m_reg & 0x0c) << 5), source);
+ LOG("bmc_830118c write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if ((m_wram_protect & 0xc0) == 0x80)
+ {
+ m_prg_base = (data & 0x0c) << 2;
+ set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = m_prg_base << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
}
-void nes_bmc_830118c_device::write_m(offs_t offset, uint8_t data)
+/*-------------------------------------------------
+
+ BMC-830832C
+
+ Games: 1994 Super HiK 3 in 1 (JY-007)
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 364
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_830832c_device::write_m(offs_t offset, u8 data)
{
- LOG_MMC(("bmc_830118c write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("bmc_830832c write_m, offset: %04x, data: %02x\n", offset, data);
+ if (offset & 0x1000) // game only writes 0x7000, this mask is a guess
+ {
+ m_prg_base = (data & 0x40) >> 1;
+ m_prg_mask = 0x1f >> BIT(data, 5);
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = (data & 0x10) << 4;
+ m_chr_mask = 0xff >> BIT(data, 5);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-YY841101C
- if (offset >= 0x800 && offset < 0x900)
+ Games: 4 in 1 (OK-411, JY-009, JY-018, JY-019, JY-020)
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 361
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_yy841101c_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_yy841101c write_m, offset: %04x, data: %02x\n", offset, data);
+ if (offset & 0x1000) // games only write 0x7000, this mask is a guess
{
- m_reg = data;
+ m_prg_base = data & 0xf0;
set_prg(m_prg_base, m_prg_mask);
+ m_chr_base = (data & 0xf0) << 3;
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
+}
+
+/*-------------------------------------------------
+
+ BMC-YY841155C
+
+ Games: Donkey Kong 8 in 1 (JY-041)
+
+ MMC3 clone with banking for multigame menu.
+
+ NES 2.0: mapper 376
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_bmc_yy841155c_device::write_m(offs_t offset, u8 data)
+{
+ LOG("bmc_yy841155c write_m, offset: %04x, data: %02x\n", offset, data);
+
+ if (offset >= 0x1000)
+ {
+ m_reg[offset & 1] = data;
+
+ m_prg_base = (m_reg[1] & 0x01) << 5 | (m_reg[0] & 0x40) >> 2;
+ if (BIT(m_reg[0], 7)) // NROM mode
+ {
+ u8 bank = m_prg_base >> 1 | (m_reg[0] & 0x07);
+ u8 mode = BIT(m_reg[0], 5);
+ prg16_89ab(bank & ~mode);
+ prg16_cdef(bank | mode);
+ }
+ else // MMC3 mode
+ set_prg(m_prg_base, m_prg_mask);
+
+ m_chr_base = m_prg_base << 3;
set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
}
@@ -2480,7 +3598,7 @@ inline void nes_pjoy84_device::set_base_mask()
void nes_pjoy84_device::write_m(offs_t offset, uint8_t data)
{
- LOG_MMC(("pjoy84 write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("pjoy84 write_m, offset: %04x, data: %02x\n", offset, data);
switch (offset & 0x03)
{
@@ -2488,6 +3606,7 @@ void nes_pjoy84_device::write_m(offs_t offset, uint8_t data)
case 0x03:
if (m_reg[3] & 0x80)
return; // else we act as if offset & 3 = 1,2
+ [[fallthrough]];
case 0x01:
case 0x02:
m_reg[offset & 0x03] = data;
@@ -2503,124 +3622,78 @@ void nes_pjoy84_device::write_m(offs_t offset, uint8_t data)
/*-------------------------------------------------
- COOLBOY
+ COOLBOY, MINDKIDS, and others with SMD132/133 chips
+
+ Games: many multicarts, Chinese games, and some
+ modern re-releases such as Metal Storm and Holy Diver
+
+ NES 2.0: mapper 268
- Games: several multigame carts
+ In MAME: Partially supported.
- In MESS: Not Supported.
+ TODO: There are many unimplemented features, though
+ there may be no carts that use them. Some of the
+ unemulated stuff: regs 4 and 5 not used, more GNROM
+ bits in reg 2, "weird" modes, WRAM at 0x5000, etc.
-------------------------------------------------*/
-void nes_coolboy_device::prg_cb(int start, int bank)
+void nes_smd133_device::prg_cb(int start, int bank)
{
- bank = (bank & 3) | ((bank & 8) >> 1) | ((bank & 4) << 1);
+ if (BIT(m_reg[3], 4)) // GNROM mode
+ {
+ u8 mask = (m_reg[1] & 0x02) | 0x01;
+ bank &= ~0x0f;
+ bank |= (m_reg[3] & ~mask & 0x0f) | (start & mask);
+ }
+
prg8_x(start, bank);
}
-void nes_coolboy_device::chr_cb(int start, int bank, int source)
+void nes_smd133_device::chr_cb(int start, int bank, int source)
{
- bank = (bank & 0xdd) | ((bank & 0x20) >> 4) | ((bank & 2) << 4);
+ if (BIT(m_reg[3], 4)) // GNROM mode
+ {
+ bank &= ~m_chr_mask;
+ bank |= (m_reg[2] & 0x0f) << 3 | start;
+ }
+
chr1_x(start, bank, source);
}
-void nes_coolboy_device::write_m(offs_t offset, uint8_t data)
+void nes_smd133_device::smd133_write(offs_t offset, u8 data)
{
- LOG_MMC(("coolboy write_m, offset: %04x, data: %02x\n", offset, data));
-
- m_reg[offset & 0x03] = data;
- //set_base_mask();
- set_chr(m_chr_source, m_chr_base, m_chr_mask);
- set_prg(m_prg_base, m_prg_mask);
-}
-
-#ifdef UNUSED_FUNCTION
-/*-------------------------------------------------
+ int reg = offset & 0x07;
- UNL-A9746
-
-
- MMC3 clone
-
-
- Preliminary emulation based on Cah4e3's code
- No dump is available (yet) for this.
-
- -------------------------------------------------*/
-
-void nes_a9746_device::device_start()
-{
- mmc3_start();
- save_item(NAME(m_reg));
-}
+ if (reg < 6 && (BIT(m_reg[3], 4) || !BIT(m_reg[3], 7)))
+ {
+ m_reg[reg] = data;
-void nes_a9746_device::pcb_reset()
-{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
+ m_prg_base = (m_reg[0] & 0x30) << 6 | (m_reg[1] & 0x0c) << 6 | (m_reg[1] & 0x10) << 3 | (m_reg[0] & 0x07) << 4;
+ m_prg_mask = (bitswap<3>(m_reg[1], 5, 6, 7) << 5 | (m_reg[0] & 0x40) >> 2 | 0x0f) ^ 0x30;
+ set_prg(m_prg_base, m_prg_mask);
- m_reg[0] = 0;
- m_reg[1] = 0;
- m_reg[2] = 0;
- mmc3_common_initialize(0x7f, 0xff, 0);
+ m_chr_base = (m_reg[0] & 0x80) & ((m_reg[0] & 0x08) << 4);
+ m_chr_mask = 0xff >> BIT(m_reg[0], 7);
+ set_chr(m_chr_source, m_chr_base, m_chr_mask);
+ }
}
-void nes_a9746_device::update_banks(uint8_t value)
+void nes_smd133_device::write_l(offs_t offset, u8 data)
{
- uint8_t bank = bitswap<8>(value & 0x3c,7,6,0,1,2,3,4,5);
+ LOG("smd133 write_l, offset: %04x, data: %02x\n", offset, data);
- switch (m_reg[0])
- {
- case 0x26: prg8_89(bank); break;
- case 0x25: prg8_ab(bank); break;
- case 0x24: prg8_cd(bank); break;
- case 0x23: prg8_ef(bank); break;
- }
-
- switch (m_reg[1])
- {
- case 0x08: case 0x0a: case 0x0c: case 0x0e:
- case 0x10: case 0x12: case 0x14: case 0x16:
- case 0x18: case 0x1a: case 0x1c: case 0x1e:
- m_reg[2] = (value << 4);
- break;
- case 0x09: chr1_0(m_reg[2] | (value >> 1), m_chr_source); break;
- case 0x0b: chr1_1(m_reg[2] | (value >> 1) | 1, m_chr_source); break;
- case 0x0d: chr1_2(m_reg[2] | (value >> 1), m_chr_source); break;
- case 0x0f: chr1_3(m_reg[2] | (value >> 1) | 1, m_chr_source); break;
- case 0x11: chr1_4(m_reg[2] | (value >> 1), m_chr_source); break;
- case 0x15: chr1_5(m_reg[2] | (value >> 1), m_chr_source); break;
- case 0x19: chr1_6(m_reg[2] | (value >> 1), m_chr_source); break;
- case 0x1d: chr1_7(m_reg[2] | (value >> 1), m_chr_source); break;
- }
+ offset += 0x100;
+ if (offset >= 0x1000 && m_smd133_addr == 0x5000)
+ smd133_write(offset, data);
}
-void nes_a9746_device::write_h(offs_t offset, uint8_t data)
+void nes_smd133_device::write_m(offs_t offset, u8 data)
{
- LOG_MMC(("unl_a9746 write_h, offset: %04x, data: %02x\n", offset, data));
-
- switch (offset & 0x6003)
- {
- case 0x0000:
- m_reg[1] = data;
- m_reg[0] = 0;
- break;
- case 0x0001:
- update_banks(data);
- break;
- case 0x0002:
- m_reg[0] = data;
- m_reg[1] = 0;
- break;
+ LOG("smd133 write_m, offset: %04x, data: %02x\n", offset, data);
- case 0x0003:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- break;
+ nes_txrom_device::write_m(offset, data); // registers overlay WRAM
- default:
- txrom_write(offset, data);
- break;
- }
+ if (offset < 0x1000 && m_smd133_addr == 0x6000)
+ smd133_write(offset, data);
}
-#endif