diff options
Diffstat (limited to 'src/devices/bus/nes/multigame.cpp')
-rw-r--r-- | src/devices/bus/nes/multigame.cpp | 1147 |
1 files changed, 718 insertions, 429 deletions
diff --git a/src/devices/bus/nes/multigame.cpp b/src/devices/bus/nes/multigame.cpp index bc947a1ef51..33e377fc6eb 100644 --- a/src/devices/bus/nes/multigame.cpp +++ b/src/devices/bus/nes/multigame.cpp @@ -8,9 +8,9 @@ Here we emulate several PCBs used in multigame pirate carts (not MMC-3 based) - TODO: Investigate further Gunsmoke on mc_8et40 and mc_2gn91. Both exhibit the - same bug where enemies/barrels don't appear until they are halfway down the - screen. They are both almost the same minor hack of the US release. + TODO: Investigate further Gunsmoke on mc_8et40, mc_2gn91, mc_8x801. All have + the same bug where enemies/barrels don't appear until they are halfway down + the screeen. They all seem to be a minor hack of the US release. ***********************************************************************************************************/ @@ -19,13 +19,14 @@ #include "multigame.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" //------------------------------------------------- @@ -51,9 +52,13 @@ DEFINE_DEVICE_TYPE(NES_BMC_810544C, nes_bmc_810544c_device, "nes_bmc_81054 DEFINE_DEVICE_TYPE(NES_BMC_830425C, nes_bmc_830425c_device, "nes_bmc_830425c", "NES Cart BMC 830425C-4391T PCB") DEFINE_DEVICE_TYPE(NES_BMC_830928C, nes_bmc_830928c_device, "nes_bmc_830928c", "NES Cart BMC 830928C PCB") DEFINE_DEVICE_TYPE(NES_BMC_850437C, nes_bmc_850437c_device, "nes_bmc_850437c", "NES Cart BMC 850437C PCB") +DEFINE_DEVICE_TYPE(NES_BMC_891227, nes_bmc_891227_device, "nes_bmc_891227", "NES Cart BMC 891227 PCB") DEFINE_DEVICE_TYPE(NES_BMC_970630C, nes_bmc_970630c_device, "nes_bmc_970630c", "NES Cart BMC 970630C PCB") DEFINE_DEVICE_TYPE(NES_NTD03, nes_ntd03_device, "nes_ntd03", "NES Cart NTD-03 PCB") DEFINE_DEVICE_TYPE(NES_BMC_CTC09, nes_bmc_ctc09_device, "nes_bmc_ctc09", "NES Cart BMC CTC-09 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_CTC12IN1, nes_bmc_ctc12in1_device, "nes_bmc_ctc12in1", "NES Cart BMC CTC-12IN1 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_DS927, nes_bmc_ds927_device, "nes_bmc_ds927", "NES Cart BMC DS-9-27 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_FAM250, nes_bmc_fam250_device, "nes_bmc_fam250", "NES Cart BMC FAM250 PCB") DEFINE_DEVICE_TYPE(NES_BMC_GKA, nes_bmc_gka_device, "nes_bmc_gka", "NES Cart BMC GK-A PCB") DEFINE_DEVICE_TYPE(NES_BMC_GKB, nes_bmc_gkb_device, "nes_bmc_gkb", "NES Cart BMC GK-B PCB") DEFINE_DEVICE_TYPE(NES_BMC_GKCXIN1, nes_bmc_gkcxin1_device, "nes_bmc_gkcxin1", "NES Cart BMC GKCXIN1 PCB") @@ -62,7 +67,11 @@ DEFINE_DEVICE_TYPE(NES_BMC_HP898F, nes_bmc_hp898f_device, "nes_bmc_hp898 DEFINE_DEVICE_TYPE(NES_BMC_K1029, nes_bmc_k1029_device, "nes_bmc_k1029", "NES Cart BMC K-1029 PCB") DEFINE_DEVICE_TYPE(NES_BMC_K3036, nes_bmc_k3036_device, "nes_bmc_k3036", "NES Cart BMC K-3036 PCB") DEFINE_DEVICE_TYPE(NES_BMC_K3046, nes_bmc_k3046_device, "nes_bmc_k3046", "NES Cart BMC K-3046 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_K3071, nes_bmc_k3071_device, "nes_bmc_k3071", "NES Cart BMC K-3071 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_S009, nes_bmc_s009_device, "nes_bmc_s009", "NES Cart BMC S-009 PCB") DEFINE_DEVICE_TYPE(NES_BMC_SA005A, nes_bmc_sa005a_device, "nes_bmc_sa005a", "NES Cart BMC SA005-A PCB") +DEFINE_DEVICE_TYPE(NES_BMC_TF2740, nes_bmc_tf2740_device, "nes_bmc_tf2740", "NES Cart BMC TF2740 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_TH2348, nes_bmc_th2348_device, "nes_bmc_th2348", "NES Cart BMC TH2348 PCB") DEFINE_DEVICE_TYPE(NES_BMC_TJ03, nes_bmc_tj03_device, "nes_bmc_tj03", "NES Cart BMC TJ-03 PCB") DEFINE_DEVICE_TYPE(NES_BMC_WS, nes_bmc_ws_device, "nes_bmc_ws", "NES Cart BMC WS PCB") DEFINE_DEVICE_TYPE(NES_BMC_11160, nes_bmc_11160_device, "nes_bmc_1160", "NES Cart BMC-1160 PCB") @@ -90,9 +99,9 @@ DEFINE_DEVICE_TYPE(NES_BMC_190IN1, nes_bmc_190in1_device, "nes_bmc_190in DEFINE_DEVICE_TYPE(NES_BMC_500IN1, nes_bmc_500in1_device, "nes_bmc_500in1", "NES Cart BMC 500 in 1 PCB") DEFINE_DEVICE_TYPE(NES_BMC_800IN1, nes_bmc_800in1_device, "nes_bmc_800in1", "NES Cart BMC 800 in 1 PCB") DEFINE_DEVICE_TYPE(NES_BMC_1200IN1, nes_bmc_1200in1_device, "nes_bmc_1200in1", "NES Cart BMC 1200 in 1 PCB") -DEFINE_DEVICE_TYPE(NES_BMC_GOLD150, nes_bmc_gold150_device, "nes_bmc_gold150", "NES Cart BMC Golden 150 in 1 PCB") -DEFINE_DEVICE_TYPE(NES_BMC_GOLD260, nes_bmc_gold260_device, "nes_bmc_gold260", "NES Cart BMC Golden 260 in 1 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_GOLD260, nes_bmc_gold260_device, "nes_bmc_gold260", "NES Cart BMC Golden Game X in 1 PCB") DEFINE_DEVICE_TYPE(NES_BMC_TH22913, nes_bmc_th22913_device, "nes_bmc_th22913", "NES Cart BMC TH2291-3 PCB") +DEFINE_DEVICE_TYPE(NES_BMC_82AB, nes_bmc_82ab_device, "nes_bmc_82ab", "NES Cart BMC 82AB PCB") DEFINE_DEVICE_TYPE(NES_BMC_4IN1RESET, nes_bmc_4in1reset_device, "nes_bmc_4in1reset", "NES Cart BMC 4 in 1 (Reset Based) PCB") DEFINE_DEVICE_TYPE(NES_BMC_42IN1RESET, nes_bmc_42in1reset_device, "nes_bmc_42in1reset", "NES Cart BMC 42 in 1 (Reset Based) PCB") DEFINE_DEVICE_TYPE(NES_BMC_NC20MB, nes_bmc_nc20mb_device, "nes_bmc_nc20mb", "NES Cart BMC NC-20MB PCB") @@ -122,7 +131,7 @@ ioport_constructor nes_bmc_8157_device::device_input_ports() const // LIVE DEVICE //************************************************************************** -nes_action52_device::nes_action52_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_action52_device::nes_action52_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_ACTION52, tag, owner, clock) { } @@ -222,7 +231,7 @@ nes_bmc_970630c_device::nes_bmc_970630c_device(const machine_config &mconfig, co { } -nes_ntd03_device::nes_ntd03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_ntd03_device::nes_ntd03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_NTD03, tag, owner, clock) { } @@ -232,6 +241,11 @@ nes_bmc_ctc09_device::nes_bmc_ctc09_device(const machine_config &mconfig, const { } +nes_bmc_ds927_device::nes_bmc_ds927_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_DS927, tag, owner, clock), m_latch(0), m_mode(0) +{ +} + nes_bmc_gka_device::nes_bmc_gka_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_BMC_GKA, tag, owner, clock) { @@ -267,11 +281,31 @@ nes_bmc_k3046_device::nes_bmc_k3046_device(const machine_config &mconfig, const { } +nes_bmc_k3071_device::nes_bmc_k3071_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_K3071, tag, owner, clock) +{ +} + +nes_bmc_s009_device::nes_bmc_s009_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_S009, tag, owner, clock), m_reg(0) +{ +} + nes_bmc_sa005a_device::nes_bmc_sa005a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_BMC_SA005A, tag, owner, clock) { } +nes_bmc_tf2740_device::nes_bmc_tf2740_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_TF2740, tag, owner, clock), m_jumper(0) +{ +} + +nes_bmc_th2348_device::nes_bmc_th2348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_TH2348, tag, owner, clock), m_latch(0) +{ +} + nes_bmc_tj03_device::nes_bmc_tj03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_BMC_TJ03, tag, owner, clock) { @@ -324,8 +358,8 @@ nes_bmc_22games_device::nes_bmc_22games_device(const machine_config &mconfig, co { } -nes_bmc_64y2k_device::nes_bmc_64y2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_nrom_device(mconfig, NES_BMC_64Y2K, tag, owner, clock) +nes_bmc_64y2k_device::nes_bmc_64y2k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_nrom_device(mconfig, NES_BMC_64Y2K, tag, owner, clock), m_reg_mask(0) { } @@ -334,7 +368,7 @@ nes_bmc_420y2k_device::nes_bmc_420y2k_device(const machine_config &mconfig, cons { } -nes_bmc_12in1_device::nes_bmc_12in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_bmc_12in1_device::nes_bmc_12in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_BMC_12IN1, tag, owner, clock) { } @@ -409,12 +443,7 @@ nes_bmc_1200in1_device::nes_bmc_1200in1_device(const machine_config &mconfig, co { } -nes_bmc_gold150_device::nes_bmc_gold150_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_nrom_device(mconfig, NES_BMC_GOLD150, tag, owner, clock), m_latch(0) -{ -} - -nes_bmc_gold260_device::nes_bmc_gold260_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_bmc_gold260_device::nes_bmc_gold260_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_BMC_GOLD260, tag, owner, clock) { } @@ -424,18 +453,18 @@ nes_bmc_4in1reset_device::nes_bmc_4in1reset_device(const machine_config &mconfig { } -nes_bmc_42in1reset_device::nes_bmc_42in1reset_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : nes_nrom_device(mconfig, type, tag, owner, clock), m_latch(0), m_mirror_flip(type == NES_BMC_NC20MB) +nes_bmc_42in1reset_device::nes_bmc_42in1reset_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 mirror_flip) + : nes_nrom_device(mconfig, type, tag, owner, clock), m_latch(0), m_mirror_flip(mirror_flip) { } nes_bmc_42in1reset_device::nes_bmc_42in1reset_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : nes_bmc_42in1reset_device(mconfig, NES_BMC_42IN1RESET, tag, owner, clock) + : nes_bmc_42in1reset_device(mconfig, NES_BMC_42IN1RESET, tag, owner, clock, 0) { } nes_bmc_nc20mb_device::nes_bmc_nc20mb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : nes_bmc_42in1reset_device(mconfig, NES_BMC_NC20MB, tag, owner, clock) + : nes_bmc_42in1reset_device(mconfig, NES_BMC_NC20MB, tag, owner, clock, 1) { } @@ -454,36 +483,59 @@ nes_bmc_60311c_device::nes_bmc_60311c_device(const machine_config &mconfig, cons { } -nes_bmc_k1029_device::nes_bmc_k1029_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : nes_vram_protect_device(mconfig, NES_BMC_K1029, tag, owner, clock) +nes_bmc_ctc12in1_device::nes_bmc_ctc12in1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : nes_vram_protect_device(mconfig, type, tag, owner, clock) { } -nes_n625092_device::nes_n625092_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : nes_vram_protect_device(mconfig, NES_N625092, tag, owner, clock) +nes_bmc_ctc12in1_device::nes_bmc_ctc12in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_ctc12in1_device(mconfig, NES_BMC_CTC12IN1, tag, owner, clock) { } -nes_bmc_th22913_device::nes_bmc_th22913_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : nes_vram_protect_device(mconfig, NES_BMC_TH22913, tag, owner, clock) +nes_bmc_891227_device::nes_bmc_891227_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_ctc12in1_device(mconfig, NES_BMC_891227, tag, owner, clock) +{ +} + +nes_bmc_k1029_device::nes_bmc_k1029_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : nes_vram_protect_device(mconfig, type, tag, owner, clock) +{ +} + +nes_bmc_k1029_device::nes_bmc_k1029_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_k1029_device(mconfig, NES_BMC_K1029, tag, owner, clock) { } +nes_bmc_fam250_device::nes_bmc_fam250_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_k1029_device(mconfig, NES_BMC_FAM250, tag, owner, clock), m_latch(0), m_reg(0) +{ +} +nes_n625092_device::nes_n625092_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_vram_protect_device(mconfig, NES_N625092, tag, owner, clock) +{ +} +nes_bmc_th22913_device::nes_bmc_th22913_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 vram_prot_bit) + : nes_vram_protect_device(mconfig, type, tag, owner, clock), m_vram_prot_bit(vram_prot_bit) +{ +} -void nes_action52_device::device_start() +nes_bmc_th22913_device::nes_bmc_th22913_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_th22913_device(mconfig, NES_BMC_TH22913, tag, owner, clock, 10) { - common_start(); } -void nes_action52_device::pcb_reset() +nes_bmc_82ab_device::nes_bmc_82ab_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_bmc_th22913_device(mconfig, NES_BMC_82AB, tag, owner, clock, 9) { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); } + + + void nes_caltron6in1_device::device_start() { common_start(); @@ -523,7 +575,6 @@ void nes_rumblestat_device::device_start() void nes_rumblestat_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg32(0); chr8(0, m_chr_source); @@ -541,7 +592,6 @@ void nes_svision16_device::device_start() void nes_svision16_device::pcb_reset() { prg32(0); - chr8(0, CHRRAM); m_latch1 = 0; m_latch2 = 0; @@ -557,7 +607,6 @@ void nes_farid_unrom_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_reg &= 0x87; // only middle four bits cleared on soft reset } @@ -573,21 +622,12 @@ void nes_kn42_device::pcb_reset() m_latch ^= 0x10; prg16_89ab(m_latch); prg16_cdef(m_latch | 0x0f); // fixed to last bank for either game - chr8(0, CHRRAM); -} - -void nes_a65as_device::device_start() -{ - common_start(); } void nes_a65as_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg16_89ab(0); prg16_cdef(7); - set_nt_mirroring(PPU_MIRROR_VERT); - chr8(0, m_chr_source); } void nes_t262_device::device_start() @@ -600,29 +640,15 @@ void nes_t262_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_latch = 0; } -void nes_studyngame_device::device_start() -{ - common_start(); -} - -void nes_studyngame_device::pcb_reset() -{ - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); -} - void nes_sgun20in1_device::pcb_reset() { prg16_89ab(0); prg16_cdef(0); chr8(0, CHRROM); - set_nt_mirroring(PPU_MIRROR_VERT); } void nes_vt5201_device::device_start() @@ -650,18 +676,11 @@ void nes_bmc_80013b_device::device_start() void nes_bmc_80013b_device::pcb_reset() { - chr8(0, CHRRAM); - m_latch = 0x80; m_reg[0] = m_reg[1] = 0; update_prg(); } -void nes_bmc_810544c_device::device_start() -{ - common_start(); -} - void nes_bmc_810544c_device::pcb_reset() { prg16_89ab(0); @@ -679,8 +698,6 @@ void nes_bmc_830425c_device::pcb_reset() { prg16_89ab(0); prg16_cdef(0x0f); - chr8(0, CHRRAM); - set_nt_mirroring(PPU_MIRROR_VERT); m_latch = 0; } @@ -695,7 +712,6 @@ void nes_bmc_830928c_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_latch = 0; } @@ -710,7 +726,6 @@ void nes_bmc_850437c_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_reg[0] = m_reg[1] = 0; } @@ -725,29 +740,34 @@ void nes_bmc_970630c_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_latch = 0; } -void nes_ntd03_device::device_start() +void nes_bmc_ctc09_device::pcb_reset() { - common_start(); +// nes_slot's pcb_start sets us up in the main menu. Soft reset is empty so +// that games reset to their own title screens. This seems to be this cart's +// intended behavior as trying to reset to the menu here crashes (due to RAM +// contents?). Soft reset can similarly crash the main menu (BTANB?). } -void nes_ntd03_device::pcb_reset() +void nes_bmc_ds927_device::device_start() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); + common_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_mode)); } -void nes_bmc_ctc09_device::pcb_reset() +void nes_bmc_ds927_device::pcb_reset() { -// nes_slot's pcb_start sets us up in the main menu. Soft reset is empty so -// that games reset to their own title screens. This seems to be this cart's -// intended behavior as trying to reset to the menu here crashes (due to RAM -// contents?). Soft reset can similarly crash the main menu (BTANB?). + assert(m_prgram.size() >= 0x2000); + + prg16_89ab(0); + prg16_cdef(0); + + m_latch = 0; + m_mode = 0; } void nes_bmc_gka_device::device_start() @@ -775,7 +795,6 @@ void nes_bmc_gn91b_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_latch = 0; } @@ -784,14 +803,33 @@ void nes_bmc_k3036_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); } void nes_bmc_k3046_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); +} + +void nes_bmc_k3071_device::pcb_reset() +{ + prg16_89ab(0); + prg16_cdef(0); + chr8(0, CHRROM); +} + +void nes_bmc_s009_device::device_start() +{ + common_start(); + save_item(NAME(m_reg)); +} + +void nes_bmc_s009_device::pcb_reset() +{ + prg16_89ab(0); + prg16_cdef(7); + + m_reg = 0; } void nes_bmc_sa005a_device::pcb_reset() @@ -801,6 +839,36 @@ void nes_bmc_sa005a_device::pcb_reset() chr8(0, CHRROM); } +void nes_bmc_tf2740_device::device_start() +{ + common_start(); + save_item(NAME(m_reg)); + save_item(NAME(m_jumper)); +} + +void nes_bmc_tf2740_device::pcb_reset() +{ + prg16_89ab(0); + prg16_cdef(0); + chr8(0, CHRROM); + + m_reg[0] = m_reg[1] = m_reg[2] = 0; +} + +void nes_bmc_th2348_device::device_start() +{ + common_start(); + save_item(NAME(m_latch)); +} + +void nes_bmc_th2348_device::pcb_reset() +{ + prg16_89ab(0); + prg16_cdef(7); + + m_latch = 0; +} + void nes_bmc_ws_device::device_start() { common_start(); @@ -809,7 +877,6 @@ void nes_bmc_ws_device::device_start() void nes_bmc_ws_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg32(0); chr8(0, m_chr_source); @@ -839,7 +906,6 @@ void nes_bmc_8157_device::pcb_reset() { prg16_89ab(0); prg16_cdef(0); - chr8(0, CHRRAM); m_latch = 0; } @@ -860,7 +926,6 @@ void nes_bmc_ball11_device::device_start() void nes_bmc_ball11_device::pcb_reset() { prg32(0); - chr8(0, CHRRAM); m_reg[0] = 2; m_reg[1] = 0; @@ -887,7 +952,6 @@ void nes_bmc_22games_device::pcb_reset() set_nt_mirroring(PPU_MIRROR_VERT); m_reset = 1; } - chr8(0, CHRRAM); } void nes_bmc_64y2k_device::device_start() @@ -898,14 +962,11 @@ void nes_bmc_64y2k_device::device_start() void nes_bmc_64y2k_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - chr8(0, m_chr_source); - + m_reg_mask = m_chr_source == CHRROM ? 0x03 : 0x01; m_reg[0] = 0x80; m_reg[1] = 0x43; m_reg[2] = m_reg[3] = 0; - set_prg(); - set_nt_mirroring(PPU_MIRROR_VERT); + update_banks(); } void nes_bmc_420y2k_device::device_start() @@ -919,7 +980,6 @@ void nes_bmc_420y2k_device::pcb_reset() { prg16_89ab(0); prg16_cdef(7); - chr8(0, CHRRAM); m_latch = 0; m_reg = 0; @@ -933,49 +993,26 @@ void nes_bmc_12in1_device::device_start() void nes_bmc_12in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); - m_reg[0] = 0; - m_reg[1] = 0; - m_reg[2] = 0; + std::fill(std::begin(m_reg), std::end(m_reg), 0x00); update_banks(); } -void nes_bmc_35in1_device::device_start() -{ - common_start(); -} - void nes_bmc_35in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg16_89ab(0); prg16_cdef(0); chr8(0, m_chr_source); } -void nes_bmc_36in1_device::device_start() -{ - common_start(); -} - void nes_bmc_36in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg16_89ab(m_prg_chunks - 1); prg16_cdef(m_prg_chunks - 1); chr8(0, m_chr_source); } -void nes_bmc_64in1_device::device_start() -{ - common_start(); -} - void nes_bmc_64in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg16_89ab(0); prg16_cdef(0); chr8(0, m_chr_source); @@ -989,7 +1026,6 @@ void nes_bmc_70in1_device::device_start() void nes_bmc_70in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; chr8(0, m_chr_source); m_latch[0] = m_latch[1] = 0; @@ -1011,7 +1047,6 @@ void nes_bmc_76in1_device::device_start() void nes_bmc_76in1_device::pcb_reset() { prg32(0); - chr8(0, CHRRAM); m_reg[0] = m_reg[1] = 0; } @@ -1031,40 +1066,12 @@ void nes_bmc_1200in1_device::device_start() void nes_bmc_1200in1_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; prg16_89ab(0); prg16_cdef(0); chr8(0, m_chr_source); m_vram_protect = 0; } -void nes_bmc_gold150_device::device_start() -{ - common_start(); - save_item(NAME(m_latch)); -} - -void nes_bmc_gold150_device::pcb_reset() -{ - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); - - m_latch = 0; -} - -void nes_bmc_gold260_device::device_start() -{ - common_start(); -} - -void nes_bmc_gold260_device::pcb_reset() -{ - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg32(0); - chr8(0, m_chr_source); -} - // This PCB is fully emulated here :) void nes_bmc_4in1reset_device::device_start() { @@ -1093,7 +1100,6 @@ void nes_bmc_42in1reset_device::pcb_reset() { m_latch ^= 0x20; prg32(m_latch >> 1); - chr8(0, CHRRAM); } void nes_vram_protect_device::device_start() @@ -1105,7 +1111,6 @@ void nes_vram_protect_device::device_start() void nes_vram_protect_device::pcb_reset() { prg32(0); - chr8(0, CHRRAM); m_vram_protect = false; } @@ -1123,6 +1128,36 @@ void nes_bmc_60311c_device::pcb_reset() update_banks(); } +void nes_bmc_ctc12in1_device::device_start() +{ + nes_vram_protect_device::device_start(); + save_item(NAME(m_reg)); +} + +void nes_bmc_ctc12in1_device::pcb_reset() +{ + nes_vram_protect_device::pcb_reset(); + prg16_89ab(0); + prg16_cdef(0); + + m_reg[0] = m_reg[1] = 0; +} + +void nes_bmc_fam250_device::device_start() +{ + nes_bmc_k1029_device::device_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_reg)); +} + +void nes_bmc_fam250_device::pcb_reset() +{ + nes_bmc_k1029_device::pcb_reset(); + + m_latch = 0; + m_reg = 0; +} + void nes_n625092_device::device_start() { nes_vram_protect_device::device_start(); @@ -1160,24 +1195,17 @@ void nes_bmc_th22913_device::pcb_reset() -------------------------------------------------*/ -void nes_action52_device::write_h(offs_t offset, uint8_t data) +void nes_action52_device::write_h(offs_t offset, u8 data) { - uint8_t pmode = offset & 0x20; - int pbank = (offset & 0x1fc0) >> 6; - int cbank = (data & 0x03) | ((offset & 0x0f) << 2); - LOG_MMC(("ae_act52_w, offset: %04x, data: %02x\n", offset, data)); - - set_nt_mirroring(BIT(offset, 13) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + LOG("ae_act52_w, offset: %04x, data: %02x\n", offset, data); - chr8(cbank, CHRROM); + u8 bank = BIT(offset, 6, 7); + u8 mode = !BIT(offset, 5); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); - if (pmode) - { - prg16_89ab(pbank); - prg16_cdef(pbank); - } - else - prg32(pbank >> 1); + chr8((data & 0x03) | (offset & 0x0f) << 2, CHRROM); + set_nt_mirroring(BIT(offset, 13) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } /*------------------------------------------------- @@ -1199,7 +1227,7 @@ void nes_caltron6in1_device::update_chr() void nes_caltron6in1_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("caltron6in1 write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("caltron6in1 write_m, offset: %04x, data: %02x\n", offset, data); switch (offset & 0x1800) { @@ -1214,7 +1242,7 @@ void nes_caltron6in1_device::write_m(offs_t offset, u8 data) void nes_caltron6in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("caltron6in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("caltron6in1 write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); @@ -1240,8 +1268,8 @@ void nes_caltron6in1_device::write_h(offs_t offset, u8 data) void nes_caltron9in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("caltron9in1 write_h, offset: %04x, data: %02x\n", offset, data)); - int nibble = (offset >> 12) & 0x07; + LOG("caltron9in1 write_h, offset: %04x, data: %02x\n", offset, data); + int nibble = BIT(offset, 12, 3); m_latch[std::min(nibble, 2)] = offset & 0x7f; if (BIT(m_latch[1], 1)) @@ -1269,13 +1297,13 @@ void nes_caltron9in1_device::write_h(offs_t offset, u8 data) iNES: mapper 46 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ void nes_rumblestat_device::write_m(offs_t offset, uint8_t data) { - LOG_MMC(("rumblestation write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("rumblestation write_m, offset: %04x, data: %02x\n", offset, data); m_prg = (m_prg & 0x01) | ((data & 0x0f) << 1); m_chr = (m_chr & 0x07) | ((data & 0xf0) >> 1); @@ -1285,13 +1313,13 @@ void nes_rumblestat_device::write_m(offs_t offset, uint8_t data) void nes_rumblestat_device::write_h(offs_t offset, uint8_t data) { - LOG_MMC(("rumblestation write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("rumblestation write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); - m_prg = (m_prg & ~0x01) | (data & 0x01); - m_chr = (m_chr & ~0x07) | ((data & 0x70) >> 4); + m_prg = (m_prg & ~0x01) | BIT(data, 0); + m_chr = (m_chr & ~0x07) | BIT(data, 4, 3); prg32(m_prg); chr8(m_chr, CHRROM); } @@ -1328,7 +1356,7 @@ void nes_svision16_device::update_prg() void nes_svision16_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("svision16 write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("svision16 write_m, offset: %04x, data: %02x\n", offset, data); if (!BIT(m_latch1, 4)) { @@ -1340,14 +1368,14 @@ void nes_svision16_device::write_m(offs_t offset, u8 data) void nes_svision16_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("svision16 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("svision16 write_h, offset: %04x, data: %02x\n", offset, data); m_latch2 = data; update_prg(); } u8 nes_svision16_device::read_m(offs_t offset) { - LOG_MMC(("svision16 read_m, offset: %04x\n", offset)); + LOG("svision16 read_m, offset: %04x\n", offset); u8 bank = m_latch1 << 4 | 0x0f; return m_prg[((bank + 4) * 0x2000 + offset) % m_prg_size]; // +4 due to the 32KB menu @@ -1367,7 +1395,7 @@ u8 nes_svision16_device::read_m(offs_t offset) void nes_farid_unrom_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("farid_unrom write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("farid_unrom write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); @@ -1400,7 +1428,7 @@ void nes_farid_unrom_device::write_h(offs_t offset, u8 data) void nes_kn42_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("kn42 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("kn42 write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); @@ -1414,14 +1442,14 @@ void nes_kn42_device::write_h(offs_t offset, u8 data) Games: 3-in-1 (N068) - In MESS: Supported + In MAME: Supported -------------------------------------------------*/ void nes_a65as_device::write_h(offs_t offset, uint8_t data) { uint8_t helper = (data & 0x30) >> 1; - LOG_MMC(("a65as write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("a65as write_h, offset: %04x, data: %02x\n", offset, data); if (data & 0x80) set_nt_mirroring(BIT(data, 5) ? PPU_MIRROR_HIGH : PPU_MIRROR_LOW); @@ -1451,7 +1479,7 @@ void nes_a65as_device::write_h(offs_t offset, uint8_t data) void nes_t262_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("t262 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("t262 write_h, offset: %04x, data: %02x\n", offset, data); if (!BIT(m_latch, 13)) { @@ -1459,7 +1487,7 @@ void nes_t262_device::write_h(offs_t offset, u8 data) set_nt_mirroring(BIT(m_latch, 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } - u8 bank = (m_latch & 0x300) >> 3 | (m_latch & 0x60) >> 2 | (data & 0x07); // NesDev shows the high bit here, but is it correct? So far no cart is large enough to use this. + u8 bank = bitswap<4>(m_latch, 9, 8, 6, 5) << 3 | (data & 0x07); // NesDev shows the high bit here, but is it correct? So far no cart is large enough to use this. u8 mode = BIT(m_latch, 0); if (BIT(m_latch, 7)) // NROM mode { @@ -1481,14 +1509,14 @@ void nes_t262_device::write_h(offs_t offset, u8 data) iNES: mapper 39 - In MESS: Partially Supported (problems with PRG bankswitch, + In MAME: Partially Supported (problems with PRG bankswitch, only keyboard exercise work). -------------------------------------------------*/ void nes_studyngame_device::write_h(offs_t offset, uint8_t data) { - LOG_MMC(("studyngame write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("studyngame write_h, offset: %04x, data: %02x\n", offset, data); prg32(data); } @@ -1508,7 +1536,7 @@ void nes_studyngame_device::write_h(offs_t offset, uint8_t data) void nes_sgun20in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("supergun20in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("supergun20in1 write_h, offset: %04x, data: %02x\n", offset, data); // Hogan's Alley in 20-in-1 will occasionally sweep through 0x66xx-0x68xx which // causes an abrupt goto Bomberman title screen. This mask is a best guess. @@ -1516,7 +1544,7 @@ void nes_sgun20in1_device::write_h(offs_t offset, u8 data) { case 0x0000: case 0x7000: - offset = (offset >> 2) & (m_prg_mask >> 1); + offset >>= 2; prg16_89ab(offset); prg16_cdef(offset); chr8(offset, CHRROM); @@ -1544,13 +1572,13 @@ void nes_bmc_190in1_device::write_h(offs_t offset, u8 data) void nes_vt5201_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("vt5201 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("vt5201 write_h, offset: %04x, data: %02x\n", offset, data); if (!BIT(m_latch, 1)) // lock bit { m_latch = offset >> 8; - u8 bank = (offset >> 4) & 0x07; + u8 bank = BIT(offset, 4, 3); u8 mode = !BIT(offset, 7); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); @@ -1562,10 +1590,10 @@ void nes_vt5201_device::write_h(offs_t offset, u8 data) u8 nes_vt5201_device::read_h(offs_t offset) { - LOG_MMC(("bmc_vt5201 read_h, offset: %04x\n", offset)); + LOG("bmc_vt5201 read_h, offset: %04x\n", offset); if (BIT(m_latch, 0)) - return (get_open_bus() & 0xfc) | m_jumper; // TODO: add jumper settings, m_jumper is 0 for now + return (get_open_bus() & ~0x03) | m_jumper; // TODO: add jumper settings, m_jumper is 0 for now else return hi_access_rom(offset); } @@ -1590,7 +1618,7 @@ void nes_bmc_80013b_device::update_prg() void nes_bmc_80013b_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_80013b write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_80013b write_h, offset: %04x, data: %02x\n", offset, data); if (offset & 0x6000) { m_reg[1] = data & 0x7f; @@ -1606,9 +1634,9 @@ void nes_bmc_80013b_device::write_h(offs_t offset, u8 data) /*------------------------------------------------- - BMC-810544-C-A1 + BMC-810544-C-A1, NTDEC 2746 - Games: 200-in-1 Elfland + Games: 200-in-1 Elfland, 14 in 1 NES 2.0: mapper 261 @@ -1618,20 +1646,15 @@ void nes_bmc_80013b_device::write_h(offs_t offset, u8 data) void nes_bmc_810544c_device::write_h(offs_t offset, u8 data) { - u8 bank = (offset >> 7); - LOG_MMC(("bmc_810544c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_810544c write_h, offset: %04x, data: %02x\n", offset, data); - if (!BIT(offset, 6)) - { - prg16_89ab((bank << 1) | BIT(offset, 5)); - prg16_cdef((bank << 1) | BIT(offset, 5)); - } - else - prg32(bank); - - set_nt_mirroring(BIT(offset, 4) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + u8 bank = bitswap<4>(offset, 9, 8, 7, 5); + u8 mode = BIT(offset, 6); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); chr8(offset & 0x0f, CHRROM); + set_nt_mirroring(BIT(offset, 4) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } /*------------------------------------------------- @@ -1648,7 +1671,7 @@ void nes_bmc_810544c_device::write_h(offs_t offset, u8 data) void nes_bmc_830425c_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_830425c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_830425c write_h, offset: %04x, data: %02x\n", offset, data); if ((offset & 0x7fe0) == 0x70e0) m_latch = offset & 0x1f; @@ -1673,7 +1696,7 @@ void nes_bmc_830425c_device::write_h(offs_t offset, u8 data) void nes_bmc_830928c_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_830928c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_830928c write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); @@ -1708,7 +1731,7 @@ void nes_bmc_830928c_device::write_h(offs_t offset, u8 data) void nes_bmc_850437c_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_850437c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_850437c write_h, offset: %04x, data: %02x\n", offset, data); m_reg[(offset & 0x6000) == 0x2000] = data; // outer banking is always at 0xa000, mask is a guess @@ -1737,9 +1760,9 @@ void nes_bmc_850437c_device::write_h(offs_t offset, u8 data) void nes_bmc_970630c_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_970630c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_970630c write_h, offset: %04x, data: %02x\n", offset, data); - u8 bank = (offset >> 2) & 0x1f; + u8 bank = BIT(offset, 2, 5); if (BIT(offset, 9)) // NROM mode { u8 mode = !BIT(offset, 0); @@ -1758,7 +1781,7 @@ void nes_bmc_970630c_device::write_h(offs_t offset, u8 data) u8 nes_bmc_970630c_device::read_h(offs_t offset) { -// LOG_MMC(("bmc_970630c read_h, offset: %04x\n", offset)); + LOGMASKED(LOG_HIFREQ, "bmc_970630c read_h, offset: %04x\n", offset); if (m_latch) return 0; // TODO: menu supposedly varies by solder pad value returned here, but it doesn't seem to work... @@ -1778,23 +1801,17 @@ u8 nes_bmc_970630c_device::read_h(offs_t offset) -------------------------------------------------*/ -void nes_ntd03_device::write_h(offs_t offset, uint8_t data) +void nes_ntd03_device::write_h(offs_t offset, u8 data) { - uint8_t pbank = (offset >> 10) & 0x1e; - uint8_t cbank = ((offset & 0x300) >> 5) | (offset & 0x07); - LOG_MMC(("ntd03 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("ntd03 write_h, offset: %04x, data: %02x\n", offset, data); - if (BIT(offset, 7)) - { - prg16_89ab(pbank | BIT(offset, 6)); - prg16_cdef(pbank | BIT(offset, 6)); - } - else - prg32(pbank >> 1); + u8 bank = bitswap<5>(offset, 14, 13, 12, 11, 6); + u8 mode = !BIT(offset, 7); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); + chr8(bitswap<5>(offset, 9, 8, 2, 1, 0), CHRROM); set_nt_mirroring(BIT(offset, 10) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - - chr8(cbank, CHRROM); } /*------------------------------------------------- @@ -1811,7 +1828,7 @@ void nes_ntd03_device::write_h(offs_t offset, uint8_t data) void nes_bmc_ctc09_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_ctc09 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_ctc09 write_h, offset: %04x, data: %02x\n", offset, data); if (BIT(offset, 14)) { @@ -1831,6 +1848,73 @@ void nes_bmc_ctc09_device::write_h(offs_t offset, u8 data) /*------------------------------------------------- + Board DS-9-27 + + Games: 190 in 1 + + Bizarro board of mostly simple games that has + 8K of WRAM that is mappable, with mirroring in + NROM128 mode, to anywhere in upper memory. + + NES 2.0: mapper 452 + + In MAME: Supported. + + -------------------------------------------------*/ + +u8 nes_bmc_ds927_device::read_h(offs_t offset) +{ + LOGMASKED(LOG_HIFREQ, "bmc_ds927 read_h, offset: %04x\n", offset); + + int bits = m_mode == 1 ? 1 : 2; + + if (BIT(offset, 13, bits) == BIT(m_latch, 4, bits)) + return m_prgram[offset & 0x1fff]; + + return hi_access_rom(offset); +} + +void nes_bmc_ds927_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_ds927 write_h, offset: %04x, data: %02x\n", offset, data); + + if (offset < 0x6000) + { + m_latch = data; + m_mode = bitswap<2>(data, 3, 1); + + int bank = BIT(offset, 1, 7); + + switch (m_mode) + { + case 0: + prg16_89ab(bank >> 1); + prg16_cdef(0); + break; + case 1: + for (int i = 0; i < 4; i++) + prg8_x(i, bank); + break; + case 2: + case 3: + prg8_89(bank); + prg8_ab(bank | 1); + prg8_cd(bank | 2); + prg8_ef(bank | 3 | (data & 0x04)); + break; + } + } + + set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + + int bits = m_mode == 1 ? 1 : 2; + + if (BIT(offset, 13, bits) == BIT(m_latch, 4, bits)) + m_prgram[offset & 0x1fff] = data; +} + +/*------------------------------------------------- + Board BMC-GKA Unknown Bootleg Multigame Board @@ -1844,13 +1928,13 @@ void nes_bmc_ctc09_device::write_h(offs_t offset, u8 data) u8 nes_bmc_gka_device::read_m(offs_t offset) { - LOG_MMC(("bmc_gka read_m, offset: %04x\n", offset)); + LOG("bmc_gka read_m, offset: %04x\n", offset); return 0; // TODO: menus differ by jumper/DIP settings readable at 0x6000. } void nes_bmc_gka_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_gka write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_gka write_h, offset: %04x, data: %02x\n", offset, data); m_reg[BIT(offset, 11)] = data; @@ -1885,14 +1969,14 @@ void nes_bmc_gka_device::write_h(offs_t offset, u8 data) void nes_bmc_gkb_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_gkb write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_gkb write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = offset & 0x07; u8 mode = !BIT(offset, 6); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); - chr8((offset >> 3) & 0x07, CHRROM); + chr8(BIT(offset, 3, 3), CHRROM); set_nt_mirroring(BIT(offset, 7) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } @@ -1913,9 +1997,9 @@ void nes_bmc_gkb_device::write_h(offs_t offset, u8 data) void nes_bmc_gkcxin1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_gkcxin1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_gkcxin1 write_h, offset: %04x, data: %02x\n", offset, data); - prg32((offset >> 3) & 0x03); + prg32(BIT(offset, 3, 2)); chr8(offset & 0x07, CHRROM); } @@ -1934,7 +2018,7 @@ void nes_bmc_gkcxin1_device::write_h(offs_t offset, u8 data) void nes_bmc_gn91b_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_gn91b write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_gn91b write_h, offset: %04x, data: %02x\n", offset, data); if (offset < 0x4000) { @@ -1963,7 +2047,7 @@ void nes_bmc_gn91b_device::write_h(offs_t offset, u8 data) u8 nes_bmc_hp898f_device::read_l(offs_t offset) { - LOG_MMC(("bmc_hp898f read_l, offset: %04x\n", offset)); + LOG("bmc_hp898f read_l, offset: %04x\n", offset); offset += 0x100; if (offset & 0x1000) @@ -1974,7 +2058,7 @@ u8 nes_bmc_hp898f_device::read_l(offs_t offset) void nes_bmc_hp898f_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("bmc_hp898f write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_hp898f write_m, offset: %04x, data: %02x\n", offset, data); if (offset & 0x04) { @@ -2002,7 +2086,7 @@ void nes_bmc_hp898f_device::write_m(offs_t offset, u8 data) void nes_bmc_k3036_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_k3036 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_k3036 write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = offset & 0x1f; prg16_89ab(bank); prg16_cdef(bank | (BIT(offset, 5) ? 0 : 7)); @@ -2023,7 +2107,7 @@ void nes_bmc_k3036_device::write_h(offs_t offset, u8 data) void nes_bmc_k3046_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_k3046 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_k3046 write_h, offset: %04x, data: %02x\n", offset, data); // this pcb is subject to bus conflict data = account_bus_conflict(offset, data); @@ -2035,6 +2119,64 @@ void nes_bmc_k3046_device::write_h(offs_t offset, u8 data) /*------------------------------------------------- + BMC-K-3071 + + Games: 110 in 1 + + NES 2.0: mapper 438 + + In MAME: Supported. + + -------------------------------------------------*/ + +void nes_bmc_k3071_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_k3071 write_h, offset: %04x, data: %02x\n", offset, data); + + u8 bank = BIT(offset, 1, 5); + u8 mode = BIT(offset, 0); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); + + chr8(BIT(data, 1, 5), CHRROM); + set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); +} + +/*------------------------------------------------- + + BMC-S-009 + + Games: 8 in 1 + + NES 2.0: mapper 434 + + In MAME: Supported. + + -------------------------------------------------*/ + +void nes_bmc_s009_device::write_m(offs_t offset, u8 data) +{ + LOG("bmc_s009 write_m, offset: %04x, data: %02x\n", offset, data); + + m_reg = (data & 0x07) << 3; + prg16_89ab(m_reg); + prg16_cdef(m_reg | 0x07); + + set_nt_mirroring(BIT(data, 5) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ); +} + +void nes_bmc_s009_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_s009 write_h, offset: %04x, data: %02x\n", offset, data); + + // this pcb is subject to bus conflict + data = account_bus_conflict(offset, data); + + prg16_89ab(m_reg | (data & 0x07)); +} + +/*------------------------------------------------- + BMC-SA005-A Games: 16 in 1 @@ -2047,7 +2189,7 @@ void nes_bmc_k3046_device::write_h(offs_t offset, u8 data) void nes_bmc_sa005a_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_sa005a write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_sa005a write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = offset & 0x0f; prg16_89ab(bank); prg16_cdef(bank); @@ -2057,6 +2199,97 @@ void nes_bmc_sa005a_device::write_h(offs_t offset, u8 data) /*------------------------------------------------- + BMC-TF2740 + + Games: 14 in 1, 40 in 1, 158 in 1, 9999 in 1, + 10000000 in 1 + + NES 2.0: mapper 428 + + In MAME: Supported. + + -------------------------------------------------*/ + +void nes_bmc_tf2740_device::update_chr() +{ + chr8(m_reg[2] & 0xc0 ? (m_reg[1] & 0x04) | (m_reg[0] & 0x03) : m_reg[1] & 0x07, CHRROM); +} + +void nes_bmc_tf2740_device::write_m(offs_t offset, u8 data) +{ + LOG("bmc_tf2740 write_m, offset: %04x, data: %02x\n", offset, data); + + switch (offset & 0x03) + { + case 0x01: + { + u8 bank = data >> 5; + u8 mode = BIT(data, 4); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); + + set_nt_mirroring(BIT(data, 3) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + [[fallthrough]]; + } + case 0x02: + m_reg[offset & 0x03] = data; + update_chr(); + break; + } +} + +void nes_bmc_tf2740_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_tf2740 write_h, offset: %04x, data: %02x\n", offset, data); + m_reg[0] = data; + update_chr(); +} + +u8 nes_bmc_tf2740_device::read_m(offs_t offset) +{ + LOG("bmc_tf2740 read_m, offset: %04x\n", offset); + return (get_open_bus() & ~0x03) | m_jumper; // TODO: add jumper settings, m_jumper is 0 for now +} + +/*------------------------------------------------- + + BMC-TH2348 + + Games: Golden 8 in 1 + + NES 2.0: mapper 437 + + In MAME: Supported. + + -------------------------------------------------*/ + +void nes_bmc_th2348_device::write_l(offs_t offset, u8 data) +{ + LOG("bmc_th2348 write_l, offset: %04x, data: %02x\n", offset, data); + + offset += 0x100; + if (offset >= 0x1000) + { + m_latch = (offset & 0x07) << 3; + prg16_89ab(m_latch); + prg16_cdef(m_latch | 0x07); + + set_nt_mirroring(BIT(offset, 3) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + } +} + +void nes_bmc_th2348_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_th2348 write_h, offset: %04x, data: %02x\n", offset, data); + + // this pcb is subject to bus conflict + data = account_bus_conflict(offset, data); + + prg16_89ab(m_latch | (data & 0x07)); +} + +/*------------------------------------------------- + BMC-TJ-03 Games: 4 in 1 @@ -2069,8 +2302,8 @@ void nes_bmc_sa005a_device::write_h(offs_t offset, u8 data) void nes_bmc_tj03_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_tj03 write_h, offset: %04x, data: %02x\n", offset, data)); - u8 bank = (offset >> 8) & 0x03; + LOG("bmc_tj03 write_h, offset: %04x, data: %02x\n", offset, data); + u8 bank = BIT(offset, 8, 2); prg32(bank); chr8(bank, CHRROM); set_nt_mirroring(BIT(offset, 9) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); @@ -2082,15 +2315,14 @@ void nes_bmc_tj03_device::write_h(offs_t offset, u8 data) Games: Super 40-in-1 - In MESS: Partially Supported (some games, like Galaxian, have + In MAME: Partially Supported (some games, like Galaxian, have issues) -------------------------------------------------*/ void nes_bmc_ws_device::write_m(offs_t offset, uint8_t data) { - uint8_t mmc_helper; - LOG_MMC(("bmc_ws write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_ws write_m, offset: %04x, data: %02x\n", offset, data); if (offset < 0x1000) { @@ -2101,9 +2333,9 @@ void nes_bmc_ws_device::write_m(offs_t offset, uint8_t data) { m_latch = data & 0x20; set_nt_mirroring(BIT(data, 4) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - mmc_helper = (~data & 0x08) >> 3; - prg16_89ab(data & ~mmc_helper); - prg16_cdef(data | mmc_helper); + u8 mode = !BIT(data, 3); + prg16_89ab(data & ~mode); + prg16_cdef(data | mode); } break; case 1: @@ -2128,10 +2360,10 @@ void nes_bmc_ws_device::write_m(offs_t offset, uint8_t data) void nes_bmc_11160_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_11160 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_11160 write_h, offset: %04x, data: %02x\n", offset, data); - prg32((data & 0x30) >> 4); - chr8(((data & 0x30) >> 2) | (data & 0x03), CHRROM); + prg32(BIT(data, 4, 2)); + chr8(bitswap<4>(data, 5, 4, 1, 0), CHRROM); set_nt_mirroring(BIT(data, 7) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ); } @@ -2149,7 +2381,7 @@ void nes_bmc_11160_device::write_h(offs_t offset, u8 data) void nes_bmc_g146_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_g146 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_g146 write_h, offset: %04x, data: %02x\n", offset, data); u8 prg_lo = offset & 0x1f; u8 prg_hi = prg_lo; // default: NROM-128 mode @@ -2180,12 +2412,13 @@ void nes_bmc_g146_device::write_h(offs_t offset, u8 data) void nes_bmc_2751_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_2751 write_h, offset: %04x, data: %02x\n", offset, data)); - u8 bank = (offset >> 4) & 0x07; + LOG("bmc_2751 write_h, offset: %04x, data: %02x\n", offset, data); + u8 bank = BIT(offset, 4, 3); u8 mode = BIT(offset, 7); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); - chr8((offset >> 1) & 0x07, CHRROM); + + chr8(BIT(offset, 1, 3), CHRROM); set_nt_mirroring(BIT(offset, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } @@ -2208,9 +2441,9 @@ void nes_bmc_2751_device::write_h(offs_t offset, u8 data) void nes_bmc_8157_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_8157 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_8157 write_h, offset: %04x, data: %02x\n", offset, data); - u8 bank = (offset >> 2) & 0x1f; + u8 bank = BIT(offset, 2, 5); prg16_89ab(bank); if (BIT(offset, 9)) bank |= 0x07; @@ -2224,7 +2457,7 @@ void nes_bmc_8157_device::write_h(offs_t offset, u8 data) u8 nes_bmc_8157_device::read_h(offs_t offset) { - LOG_MMC(("bmc_8157 read_h, offset: %04x\n", offset)); + LOG("bmc_8157 read_h, offset: %04x\n", offset); if (m_latch) offset = (offset & ~0x01) | m_jumper->read(); return hi_access_rom(offset); @@ -2245,13 +2478,13 @@ u8 nes_bmc_8157_device::read_h(offs_t offset) u8 nes_bmc_hik300_device::read_m(offs_t offset) { - LOG_MMC(("bmc_hik300 read_m, offset: %04x, data: %02x\n", offset)); + LOG("bmc_hik300 read_m, offset: %04x, data: %02x\n", offset); return get_open_bus() | (!BIT(offset, 4) << 7); // some games have a protection MSB } void nes_bmc_hik300_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_hik300 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_hik300 write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = offset & 0x07; u8 mode = BIT(offset, 14); @@ -2285,9 +2518,9 @@ void nes_bmc_hik300_device::write_h(offs_t offset, u8 data) void nes_bmc_s700_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_s700 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_s700 write_h, offset: %04x, data: %02x\n", offset, data); - u8 bank = (offset & 0x40) | ((offset >> 8) & 0x3f); + u8 bank = (offset & 0x40) | BIT(offset, 8, 6); u8 mode = !BIT(offset, 5); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); @@ -2311,10 +2544,10 @@ void nes_bmc_s700_device::write_h(offs_t offset, u8 data) u8 nes_bmc_ball11_device::read_m(offs_t offset) { - LOG_MMC(("bmc_ball11 read_m, offset: %04x, data: %02x\n", offset)); + LOG("bmc_ball11 read_m, offset: %04x, data: %02x\n", offset); u8 bank = m_reg[1] << 2 | (m_reg[0] ? 0x23 : 0x2f); - return m_prg[bank * 0x2000 + offset]; + return m_prg[(bank * 0x2000 + offset) & (m_prg_size - 1)]; } void nes_bmc_ball11_device::update_prg() @@ -2330,7 +2563,7 @@ void nes_bmc_ball11_device::update_prg() void nes_bmc_ball11_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("bmc_ball11 write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_ball11 write_m, offset: %04x, data: %02x\n", offset, data); set_nt_mirroring(BIT(data, 4) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); m_reg[0] = data & 0x02; update_prg(); @@ -2338,7 +2571,7 @@ void nes_bmc_ball11_device::write_m(offs_t offset, u8 data) void nes_bmc_ball11_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_ball11 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_ball11 write_h, offset: %04x, data: %02x\n", offset, data); m_reg[1] = data & 0x1f; update_prg(); } @@ -2363,7 +2596,7 @@ void nes_bmc_ball11_device::write_h(offs_t offset, u8 data) void nes_bmc_22games_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_22games write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_22games write_h, offset: %04x, data: %02x\n", offset, data); if (m_latch) { @@ -2383,54 +2616,45 @@ void nes_bmc_22games_device::write_h(offs_t offset, u8 data) Games: 64-in-1 Y2K - In MESS: Supported + NES 2.0: mapper 314 + + In MAME: Supported. -------------------------------------------------*/ -void nes_bmc_64y2k_device::set_prg() +void nes_bmc_64y2k_device::update_banks() { - uint8_t helper1 = (m_reg[1] & 0x1f); - uint8_t helper2 = (helper1 << 1) | ((m_reg[1] & 0x40) >> 6); - - if (m_reg[0] & 0x80) + if (BIT(m_reg[0] & m_reg[1], 7)) + prg32(m_reg[1]); + else { - if (m_reg[1] & 0x80) - prg32(helper1); - else - { - prg16_89ab(helper2); - prg16_cdef(helper2); - } + u8 bank = m_reg[1] << 1 | BIT(m_reg[1], 6); + prg16_89ab(bank); + prg16_cdef(bank | (BIT(m_reg[0], 7) ? 0 : 7)); } - else - prg16_cdef(helper2); + + chr8(BIT(m_reg[0], 1, 2) | (m_reg[2] << 2), m_chr_source); + set_nt_mirroring(BIT(m_reg[0], 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } -void nes_bmc_64y2k_device::write_l(offs_t offset, uint8_t data) +void nes_bmc_64y2k_device::write_l(offs_t offset, u8 data) { - LOG_MMC(("bmc64y2k write_l, offset: %04x, data: %02x\n", offset, data)); - offset += 0x100; + LOG("bmc_64y2k write_l, offset: %04x, data: %02x\n", offset, data); - switch (offset) + offset += 0x100; + if (offset >= 0x1000) { - case 0x1000: - case 0x1001: - case 0x1002: - case 0x1003: - m_reg[offset & 0x03] = data; - set_prg(); - chr8(((m_reg[0] >> 1) & 0x03) | (m_reg[2] << 2), CHRROM); - break; + m_reg[offset & m_reg_mask] = data; + update_banks(); } - if (offset == 0x1000) /* write to reg[0] also sets mirroring */ - set_nt_mirroring(BIT(data, 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } -void nes_bmc_64y2k_device::write_h(offs_t offset, uint8_t data) +void nes_bmc_64y2k_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc64y2k write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_64y2k write_h, offset: %04x, data: %02x\n", offset, data); - m_reg[3] = data; // reg[3] is currently unused?!? + if (!BIT(m_reg[0], 7)) + prg16_89ab(((m_reg[1] << 1) & ~0x07) | (data & 0x07)); } /*------------------------------------------------- @@ -2449,7 +2673,7 @@ void nes_bmc_64y2k_device::write_h(offs_t offset, uint8_t data) void nes_bmc_420y2k_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_420y2k write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_420y2k write_h, offset: %04x, data: %02x\n", offset, data); if (BIT(m_latch, 1)) // lock bit m_reg = (m_reg & ~0x07) | (data & 0x07); @@ -2469,7 +2693,7 @@ void nes_bmc_420y2k_device::write_h(offs_t offset, u8 data) u8 nes_bmc_420y2k_device::read_h(offs_t offset) { - LOG_MMC(("bmc_420y2k read_h, offset: %04x\n", offset)); + LOG("bmc_420y2k read_h, offset: %04x\n", offset); // latch bit 0 is only used to determine the menu, and the behavior of // this cart seems hardwired to OR $02 (ORing $00-$03 allows four menus) return hi_access_rom(offset | (m_latch & 1) << 1); @@ -2480,42 +2704,37 @@ u8 nes_bmc_420y2k_device::read_h(offs_t offset) BMC-12IN1 Unknown Bootleg Multigame Board - Games: + Games: 7 in 1 + + NES 2.0: mapper 331 - iNES: + In MAME: Supported. - In MESS: Supported. + TODO: Supposedly PRG banks change depending on what + CHR page the PPU is rendering from. This is not + emulated but the cart still works since both inner + PRG registers are always set to the same value. -------------------------------------------------*/ void nes_bmc_12in1_device::update_banks() { - int bank = (m_reg[2] & 3) << 3; - - chr4_0((m_reg[0] >> 3) | (bank << 2), m_chr_source); - chr4_4((m_reg[1] >> 3) | (bank << 2), m_chr_source); + u8 outer = (m_reg[3] & 0x03) << 3; + u8 mode = BIT(m_reg[3], 3) ? 0x01 : 0x07; // NROM256 or UNROM-like mode + prg16_89ab(outer | (m_reg[1] & 0x07)); + prg16_cdef(outer | (m_reg[2] & 0x07) | mode); - if (m_reg[2] & 8) - prg32(((m_reg[0] & 7) >> 1) | bank); - else - { - prg16_89ab((m_reg[0] & 7) | bank); - prg16_cdef(7 | bank); - } + chr4_0(outer | (m_reg[1] >> 3), m_chr_source); + chr4_4(outer | (m_reg[2] >> 3), m_chr_source); - set_nt_mirroring(BIT(m_reg[2], 2) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + set_nt_mirroring(BIT(m_reg[3], 2) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } -void nes_bmc_12in1_device::write_h(offs_t offset, uint8_t data) +void nes_bmc_12in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_12in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_12in1 write_h, offset: %04x, data: %02x\n", offset, data); - switch (offset & 0x6000) - { - case 0x2000: m_reg[0] = data; break; - case 0x4000: m_reg[1] = data; break; - case 0x6000: m_reg[2] = data; break; - } + m_reg[BIT(offset, 13, 2)] = data; update_banks(); } @@ -2534,7 +2753,7 @@ void nes_bmc_12in1_device::write_h(offs_t offset, uint8_t data) void nes_bmc_20in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_20in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_20in1 write_h, offset: %04x, data: %02x\n", offset, data); prg16_89ab(offset & 0x1e); prg16_cdef((offset & 0x1e) | BIT(offset, 5)); @@ -2556,7 +2775,7 @@ void nes_bmc_20in1_device::write_h(offs_t offset, u8 data) void nes_bmc_21in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_21in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_21in1 write_h, offset: %04x, data: %02x\n", offset, data); prg32(offset & 0x03); chr8(offset & 0x07, CHRROM); @@ -2577,7 +2796,7 @@ void nes_bmc_21in1_device::write_h(offs_t offset, u8 data) void nes_bmc_31in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_31in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_31in1 write_h, offset: %04x, data: %02x\n", offset, data); set_nt_mirroring(BIT(offset, 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); offset &= 0x1f; @@ -2601,16 +2820,17 @@ void nes_bmc_31in1_device::write_h(offs_t offset, u8 data) iNES: mapper 203 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ -void nes_bmc_35in1_device::write_h(offs_t offset, uint8_t data) +void nes_bmc_35in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_35in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_35in1 write_h, offset: %04x, data: %02x\n", offset, data); - prg16_89ab((data >> 2) & 0x03); - prg16_cdef((data >> 2) & 0x03); + u8 bank = BIT(data, 2, 2); + prg16_89ab(bank); + prg16_cdef(bank); chr8(data & 0x03, CHRROM); } @@ -2623,13 +2843,13 @@ void nes_bmc_35in1_device::write_h(offs_t offset, uint8_t data) iNES: mapper 200 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ void nes_bmc_36in1_device::write_h(offs_t offset, uint8_t data) { - LOG_MMC(("bmc_36in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_36in1 write_h, offset: %04x, data: %02x\n", offset, data); prg16_89ab(offset & 0x07); prg16_cdef(offset & 0x07); @@ -2647,7 +2867,7 @@ void nes_bmc_36in1_device::write_h(offs_t offset, uint8_t data) iNES: mapper 204 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ @@ -2655,7 +2875,7 @@ void nes_bmc_64in1_device::write_h(offs_t offset, uint8_t data) { int bank = (offset >> 1) & (offset >> 2) & 0x01; - LOG_MMC(("bmc_64in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_64in1 write_h, offset: %04x, data: %02x\n", offset, data); prg16_89ab(offset & ~bank); prg16_cdef(offset | bank); @@ -2708,7 +2928,7 @@ void nes_bmc_70in1_device::update_prg(u8 bank) void nes_bmc_70in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc70in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc70in1 write_h, offset: %04x, data: %02x\n", offset, data); m_latch[BIT(offset, 14)] = offset; update_banks(); set_nt_mirroring(BIT(m_latch[0], 5) ? PPU_MIRROR_HORZ: PPU_MIRROR_VERT); @@ -2716,7 +2936,7 @@ void nes_bmc_70in1_device::write_h(offs_t offset, u8 data) uint8_t nes_bmc_70in1_device::read_h(offs_t offset) { - LOG_MMC(("bmc70in1 read_h, offset: %04x\n", offset)); + LOG("bmc70in1 read_h, offset: %04x\n", offset); if ((m_latch[1] & 0x30) == 0x10) offset = (offset & ~0x0f) | m_jumper; // TODO: make jumper selectable @@ -2759,7 +2979,7 @@ void nes_bmc_800in1_device::update_banks() u8 nes_bmc_72in1_device::read_l(offs_t offset) { - LOG_MMC(("bmc_72in1 read_l, offset: %04x\n", offset)); + LOG("bmc_72in1 read_l, offset: %04x\n", offset); offset += 0x100; if (offset >= 0x1800) // 4 nibbles of RAM mirrored above 0x5800 @@ -2770,7 +2990,7 @@ u8 nes_bmc_72in1_device::read_l(offs_t offset) void nes_bmc_72in1_device::write_l(offs_t offset, u8 data) { - LOG_MMC(("bmc_72in1 write_l, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_72in1 write_l, offset: %04x, data: %02x\n", offset, data); offset += 0x100; if (offset >= 0x1800) // 4 nibbles of RAM mirrored above 0x5800 @@ -2779,10 +2999,10 @@ void nes_bmc_72in1_device::write_l(offs_t offset, u8 data) void nes_bmc_72in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_72in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_72in1 write_h, offset: %04x, data: %02x\n", offset, data); u8 high = (offset >> 8) & 0x40; - u8 bank = high | ((offset >> 6) & 0x3f); + u8 bank = high | BIT(offset, 6, 6); u8 mode = !BIT(offset, 12); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); @@ -2814,7 +3034,7 @@ void nes_bmc_72in1_device::write_h(offs_t offset, u8 data) void nes_bmc_76in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_76in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_76in1 write_h, offset: %04x, data: %02x\n", offset, data); m_reg[offset & 0x01] = data; u8 bank = m_reg[1] << 6 | (m_reg[0] & 0x80) >> 2 | (m_reg[0] & 0x1f); @@ -2840,9 +3060,9 @@ void nes_bmc_76in1_device::write_h(offs_t offset, u8 data) void nes_bmc_150in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_150in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_150in1 write_h, offset: %04x, data: %02x\n", offset, data); - u8 bank = (offset >> 1) & 0x07; + u8 bank = BIT(offset, 1, 3); u8 mode = (bank & 0x06) == 0x06; prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); @@ -2866,8 +3086,8 @@ void nes_bmc_150in1_device::write_h(offs_t offset, u8 data) void nes_bmc_500in1_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc500in1 write_h, offset: %04x, data: %02x\n", offset, data)); - prg32((offset >> 2) & 0x07); + LOG("bmc500in1 write_h, offset: %04x, data: %02x\n", offset, data); + prg32(BIT(offset, 2, 3)); chr8(offset & 0x07, CHRROM); } @@ -2880,7 +3100,7 @@ void nes_bmc_500in1_device::write_h(offs_t offset, u8 data) iNES: mapper 227 - In MESS: Preliminary Supported. + In MAME: Preliminary Supported. -------------------------------------------------*/ @@ -2897,7 +3117,7 @@ void nes_bmc_1200in1_device::write_h(offs_t offset, uint8_t data) { int bank = ((offset >> 2) & 0x1f) | ((offset & 0x0100) >> 3); - LOG_MMC(("bmc_1200in1 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_1200in1 write_h, offset: %04x, data: %02x\n", offset, data); if (offset & 0x80) { @@ -2925,88 +3145,32 @@ void nes_bmc_1200in1_device::write_h(offs_t offset, uint8_t data) set_nt_mirroring(BIT(offset, 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } - /*------------------------------------------------- BMC-GOLDEN260IN1 Unknown Bootleg Multigame Board - Games: + Games: Golden Game 150 in 1, Golden Game 210 in 1, + Golden Game 260 in 1, 1500 in 1 iNES: mapper 235 - In MESS: Preliminary Supported. - - -------------------------------------------------*/ - -void nes_bmc_gold260_device::write_h(offs_t offset, uint8_t data) -{ - int bank = (offset & 0x1f) | ((offset & 0x0300) >> 3); - LOG_MMC(("bmc_gold260 write_h, offset: %04x, data: %02x\n", offset, data)); - - if (offset & 0x400) - set_nt_mirroring(PPU_MIRROR_LOW); - else - set_nt_mirroring(BIT(offset, 13) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - - if (offset & 0x800) - { - bank = (bank << 1) | BIT(offset, 12); - prg16_89ab(bank); - prg16_cdef(bank); - } - else - prg32(bank); -} - - -/*------------------------------------------------- - - BMC-GOLDEN150IN1 - - Unknown Bootleg Multigame Board - Games: - - iNES: mapper 235 - - Same as the above + open bus in 0x8000-0xffff when - enabled + In MAME: Supported. - In MESS: Preliminary Supported. + TODO: Return open bus when ROM sockets are empty? -------------------------------------------------*/ - -void nes_bmc_gold150_device::write_h(offs_t offset, uint8_t data) +void nes_bmc_gold260_device::write_h(offs_t offset, u8 data) { - int bank = (offset & 0x1f) | ((offset & 0x0200) >> 4); - LOG_MMC(("bmc_gold150 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_gold260 write_h, offset: %04x, data: %02x\n", offset, data); - m_latch = (offset & 0x0100); - - if (offset & 0x400) - set_nt_mirroring(PPU_MIRROR_LOW); - else - set_nt_mirroring(BIT(offset, 13) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - - if (offset & 0x800) - { - bank = (bank << 1) | BIT(offset, 12); - prg16_89ab(bank); - prg16_cdef(bank); - } - else - prg32(bank); -} - -uint8_t nes_bmc_gold150_device::read_h(offs_t offset) -{ - LOG_MMC(("bmc_gold150 read_h, offset: %04x\n", offset)); + u8 bank = bitswap<8>(offset, 9, 8, 4, 3, 2, 1, 0, 12); + u8 mode = !BIT(offset, 11); + prg16_89ab(bank & ~mode); + prg16_cdef(bank | mode); - if (m_latch) // open bus - return get_open_bus(); - else - return hi_access_rom(offset); + set_nt_mirroring(BIT(offset, 10) ? PPU_MIRROR_LOW : BIT(offset, 13) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); } /*------------------------------------------------- @@ -3051,7 +3215,7 @@ uint8_t nes_bmc_gold150_device::read_h(offs_t offset) void nes_bmc_42in1reset_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_42in1reset write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_42in1reset write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = m_latch | (data & 0x1f); u8 mode = !BIT(data, 5); @@ -3078,10 +3242,10 @@ void nes_bmc_42in1reset_device::write_h(offs_t offset, u8 data) void nes_bmc_lc160_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_lc160 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_lc160 write_h, offset: %04x, data: %02x\n", offset, data); if (offset >= 0x4000) { - u8 bank = (offset >> 2) & 0x3f; + u8 bank = BIT(offset, 2, 6); u8 mode = !BIT(offset, 1); prg16_89ab(bank & ~mode); prg16_cdef(bank | mode); @@ -3124,20 +3288,145 @@ void nes_bmc_60311c_device::update_banks() void nes_bmc_60311c_device::write_m(offs_t offset, u8 data) { - LOG_MMC(("bmc_60311c write_m, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_60311c write_m, offset: %04x, data: %02x\n", offset, data); m_reg[offset & 1] = data & 0x7f; update_banks(); } void nes_bmc_60311c_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_60311c write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_60311c write_h, offset: %04x, data: %02x\n", offset, data); m_reg[2] = data & 0x07; update_banks(); } /*------------------------------------------------- + BMC-CTC-12IN1 + + Games: 12 in 1 Game Card + + NES 2.0: mapper 337 + + In MAME: Supported. + + -------------------------------------------------*/ + +u8 nes_bmc_ctc12in1_device::read_m(offs_t offset) +{ + LOG("bmc_ctc12in1 read_m, offset: %04x, data: %02x\n", offset); + return m_prg[0x01 * 0x2000 + offset]; // fixed to bank 1 +} + +void nes_bmc_ctc12in1_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_ctc12in1 write_h, offset: %04x, data: %02x\n", offset, data); + m_reg[BIT(offset, 14)] = data; + + u8 bank = (m_reg[0] & 0x18) | (m_reg[1] & 0x07); + switch (m_reg[0] >> 6) + { + case 0: + prg16_89ab(bank); + prg16_cdef(bank); + break; + case 1: + prg32(bank >> 1); + break; + case 2: + case 3: + prg16_89ab(bank); + prg16_cdef(bank | 0x07); + break; + } + + m_vram_protect = !BIT(m_reg[0], 7) || (offset & 0x6000) == 0x6000; + set_nt_mirroring(BIT(m_reg[0], 5) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); +} + +/*------------------------------------------------- + + BMC-891227 + + Games: Super 15 in 1 Game Card + + NES 2.0: mapper 350 + + This board is similar to CTC-12IN1 above but with + the mirroring and banking mode bits moved and with + support for Contra on a separate 128K chip. + + In MAME: Supported. + + TODO: Contra bugs: Without input character sprite + is always in the UP position. Cannot pickup weapons. + + -------------------------------------------------*/ + +void nes_bmc_891227_device::write_h(offs_t offset, u8 data) +{ + LOG("bmc_891227 write_h, offset: %04x, data: %02x\n", offset, data); + + if (offset < 0x4000) + data = bitswap<8>(data, 6, 5, 7, 4, 3, 2, 1, 0); + + nes_bmc_ctc12in1_device::write_h(offset, data); + + if ((m_reg[0] & 0xc0) == 0xc0) // Contra only mode + { + prg16_89ab(0x20 | (m_reg[1] & 0x07)); + prg16_cdef(0x27); + } +} + +/*------------------------------------------------- + + BMC-FAM250 + + Games: 250 in 1 + + This board is very close to the K-1029 board of the + famous Contra 100 and 168 multicarts. It sports an + extra mode to support a Bubble Bobble FDS bootleg. + + NES 2.0: mapper 354 + + In MAME: Supported. + + TODO: Circus Charlie's mirroring is incorrectly set + to horizontal. Is this a BTANB? + + -------------------------------------------------*/ + +u8 nes_bmc_fam250_device::read_m(offs_t offset) +{ + LOGMASKED(LOG_HIFREQ, "fam250 read_m, offset: %04x\n", offset); + + if (m_latch == 5) // only the Bubble Bobble FDS bootleg uses this + return m_prg[(((m_reg & 0x1f) << 1 | BIT(m_reg, 7)) * 0x2000 + offset) & (m_prg_size - 1)]; + else + return get_open_bus(); +} + +void nes_bmc_fam250_device::write_h(offs_t offset, u8 data) +{ + LOG("fam250 write_h, offset: %04x, data: %02x\n", offset, data); + + if (offset >= 0x7000) + { + nes_bmc_k1029_device::write_h(offset, data); + + m_latch = offset & 0x07; + m_reg = data; + if (m_latch == 5) + prg32((m_reg & 0x18) >> 1 | 0x03); + + m_vram_protect = BIT(offset, 3); + } +} + +/*------------------------------------------------- + BMC-K-1029 Games: 100 in 1 Contra Function 16, 168 in 1 @@ -3154,7 +3443,7 @@ void nes_bmc_60311c_device::write_h(offs_t offset, u8 data) void nes_bmc_k1029_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_k1029 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_k1029 write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = data & 0x3f; switch (offset & 3) @@ -3204,11 +3493,11 @@ void nes_bmc_k1029_device::write_h(offs_t offset, u8 data) void nes_n625092_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("n625092 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("n625092 write_h, offset: %04x, data: %02x\n", offset, data); m_latch[BIT(offset, 14)] = offset; - u8 bank = (m_latch[0] & 0x200) >> 3 | (m_latch[0] & 0xe0) >> 2 | (m_latch[1] & 0x07); + u8 bank = bitswap<4>(m_latch[0], 9, 7, 6, 5) << 3 | (m_latch[1] & 0x07); u8 mode = BIT(m_latch[0], 1); if (mode && BIT(m_latch[0], 8)) // UNROM mode { @@ -3227,9 +3516,9 @@ void nes_n625092_device::write_h(offs_t offset, u8 data) /*------------------------------------------------- - BMC-TH2291-3, BMC-CH-011 + BMC-TH2291-3, BMC-CH-011, BMC-82AB - Games: Powerful 250 in 1, Powerful 255 in 1 + Games: Powerful 250 in 1, Powerful 255 in 1, 82 in 1 iNES: mapper 63 @@ -3239,7 +3528,7 @@ void nes_n625092_device::write_h(offs_t offset, u8 data) void nes_bmc_th22913_device::write_h(offs_t offset, u8 data) { - LOG_MMC(("bmc_th22913 write_h, offset: %04x, data: %02x\n", offset, data)); + LOG("bmc_th22913 write_h, offset: %04x, data: %02x\n", offset, data); u8 bank = offset >> 2; u8 mode = BIT(offset, 1); @@ -3247,5 +3536,5 @@ void nes_bmc_th22913_device::write_h(offs_t offset, u8 data) prg16_cdef(bank | mode); set_nt_mirroring(BIT(offset, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); - m_vram_protect = BIT(offset, 10); + m_vram_protect = BIT(offset, m_vram_prot_bit); } |