From efe9ae43b4453ae461241d74672bc51447afab34 Mon Sep 17 00:00:00 2001 From: 0kmg <9137159+0kmg@users.noreply.github.com> Date: Sun, 17 Apr 2022 14:08:31 -0800 Subject: [PATCH] bus/nes: Minor cleanups for some MMC3 boards. (#9579) - Fixed TXSROM's repeated setting of nametable pages. - NES-QJ, PAL-ZZ boards can only change outer banking bits when RAM enabled. --- src/devices/bus/nes/bootleg.cpp | 1 - src/devices/bus/nes/mmc3.cpp | 80 ++++++++++++----------------- src/devices/bus/nes/mmc3.h | 13 ++--- src/devices/bus/nes/mmc3_clones.cpp | 20 ++------ src/devices/bus/nes/mmc3_clones.h | 4 +- src/devices/bus/nes/pirate.cpp | 1 - 6 files changed, 48 insertions(+), 71 deletions(-) diff --git a/src/devices/bus/nes/bootleg.cpp b/src/devices/bus/nes/bootleg.cpp index be4f94e2e3e..f02f91c04e4 100644 --- a/src/devices/bus/nes/bootleg.cpp +++ b/src/devices/bus/nes/bootleg.cpp @@ -24,7 +24,6 @@ #include "bootleg.h" #include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE -#include "screen.h" #ifdef NES_PCB_DEBUG diff --git a/src/devices/bus/nes/mmc3.cpp b/src/devices/bus/nes/mmc3.cpp index f697d193434..2a1a15b1686 100644 --- a/src/devices/bus/nes/mmc3.cpp +++ b/src/devices/bus/nes/mmc3.cpp @@ -20,7 +20,6 @@ * 004 Mendel Palace has never worked properly * 004 Ninja Gaiden 2 has flashing bg graphics in the second level - * 119 Pin Bot has glitches when the ball is in the upper half of the screen ***********************************************************************************************************/ @@ -29,7 +28,6 @@ #include "mmc3.h" #include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE -#include "screen.h" #ifdef NES_PCB_DEBUG @@ -89,12 +87,12 @@ nes_tqrom_device::nes_tqrom_device(const machine_config &mconfig, const char *ta { } -nes_qj_device::nes_qj_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_qj_device::nes_qj_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_txrom_device(mconfig, NES_QJ_PCB, tag, owner, clock) { } -nes_zz_device::nes_zz_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_zz_device::nes_zz_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_txrom_device(mconfig, NES_ZZ_PCB, tag, owner, clock) { } @@ -185,14 +183,12 @@ void nes_hkrom_device::pcb_reset() void nes_qj_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; mmc3_common_initialize(0x0f, 0x7f, 0); } void nes_zz_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; mmc3_common_initialize(0x07, 0x7f, 0); } @@ -461,35 +457,23 @@ void nes_hkrom_device::write_h(offs_t offset, uint8_t data) iNES: mapper 118 - In MESS: Supported. It also uses mmc3_irq. + In MAME: Supported. It also uses mmc3_irq. -------------------------------------------------*/ -void nes_txsrom_device::set_mirror() +void nes_txsrom_device::set_chr(u8 chr, int chr_base, int chr_mask) { - if (m_latch & 0x80) - { - set_nt_page(0, CIRAM, BIT(m_mmc_vrom_bank[2],7), 1); - set_nt_page(1, CIRAM, BIT(m_mmc_vrom_bank[3],7), 1); - set_nt_page(2, CIRAM, BIT(m_mmc_vrom_bank[4],7), 1); - set_nt_page(3, CIRAM, BIT(m_mmc_vrom_bank[5],7), 1); - } - else - { - set_nt_page(0, CIRAM, BIT(m_mmc_vrom_bank[0],7), 1); - set_nt_page(1, CIRAM, BIT(m_mmc_vrom_bank[0],7), 1); - set_nt_page(2, CIRAM, BIT(m_mmc_vrom_bank[1],7), 1); - set_nt_page(3, CIRAM, BIT(m_mmc_vrom_bank[1],7), 1); - } + nes_txrom_device::set_chr(chr, chr_base, chr_mask); + + // do nametables + static constexpr u8 bank[8] = { 0, 0, 1, 1, 2, 3, 4, 5 }; + int start = (m_latch & 0x80) >> 5; + + for (int i = 0; i < 4; i++) + set_nt_page(i, CIRAM, BIT(m_mmc_vrom_bank[bank[start + i]], 7), 1); } -void nes_txsrom_device::chr_cb( int start, int bank, int source ) -{ - set_mirror(); // we could probably update only for one (e.g. the first) call, to slightly optimize the code - chr1_x(start, bank, source); -} - -void nes_txsrom_device::write_h(offs_t offset, uint8_t data) +void nes_txsrom_device::write_h(offs_t offset, u8 data) { LOG_MMC(("txsrom write_h, offset: %04x, data: %02x\n", offset, data)); @@ -497,7 +481,6 @@ void nes_txsrom_device::write_h(offs_t offset, uint8_t data) { case 0x2000: break; - default: txrom_write(offset, data); break; @@ -548,19 +531,19 @@ void nes_tqrom_device::set_chr( uint8_t chr, int chr_base, int chr_mask ) -------------------------------------------------*/ -void nes_qj_device::write_m(offs_t offset, uint8_t data) +void nes_qj_device::write_m(offs_t offset, u8 data) { LOG_MMC(("qj write_m, offset: %04x, data: %02x\n", offset, data)); - m_prg_base = BIT(data, 0) << 4; - m_prg_mask = 0x0f; - m_chr_base = BIT(data, 0) << 7; - m_chr_mask = 0x7f; - set_prg(m_prg_base, m_prg_mask); - set_chr(m_chr_source, m_chr_base, m_chr_mask); + if (BIT(m_wram_protect, 7) && !BIT(m_wram_protect, 6)) + { + m_prg_base = BIT(data, 0) << 4; + m_chr_base = BIT(data, 0) << 7; + set_prg(m_prg_base, m_prg_mask); + set_chr(m_chr_source, m_chr_base, m_chr_mask); + } } - /*------------------------------------------------- PAL-ZZ board (MMC3 variant for European 3-in-1 Nintendo cart @@ -568,17 +551,22 @@ void nes_qj_device::write_m(offs_t offset, uint8_t data) iNES: mapper 37 + TODO: this board apparently only resets to the menu + screen on systems with a CIC (the outer PRG lines + are somehow tied to the CIC's reset line). + -------------------------------------------------*/ -void nes_zz_device::write_m(offs_t offset, uint8_t data) +void nes_zz_device::write_m(offs_t offset, u8 data) { - uint8_t mmc_helper = data & 0x07; LOG_MMC(("zz write_m, offset: %04x, data: %02x\n", offset, data)); - m_prg_base = (BIT(mmc_helper, 2) << 4) | (((mmc_helper & 0x03) == 0x03) ? 0x08 : 0); - m_prg_mask = (mmc_helper << 1) | 0x07; - m_chr_base = BIT(mmc_helper, 2) << 7; - m_chr_mask = 0x7f; - set_prg(m_prg_base, m_prg_mask); - set_chr(m_chr_source, m_chr_base, m_chr_mask); + if (BIT(m_wram_protect, 7) && !BIT(m_wram_protect, 6)) + { + m_prg_base = ((data & 0x04) | (data & (data << 1) & 0x02)) << 2; + m_prg_mask = (m_prg_mask == 0x10) ? 0x0f : 0x07; + m_chr_base = BIT(data, 2) << 7; + set_prg(m_prg_base, m_prg_mask); + set_chr(m_chr_source, m_chr_base, m_chr_mask); + } } diff --git a/src/devices/bus/nes/mmc3.h b/src/devices/bus/nes/mmc3.h index 244863d6fe7..965a180474c 100644 --- a/src/devices/bus/nes/mmc3.h +++ b/src/devices/bus/nes/mmc3.h @@ -90,13 +90,12 @@ public: nes_txsrom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void write_h(offs_t offset, u8 data) override; - virtual void chr_cb(int start, int bank, int source) override; protected: // construction/destruction nes_txsrom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - void set_mirror(); + virtual void set_chr(u8 chr, int chr_base, int chr_mask) override; }; @@ -122,9 +121,10 @@ class nes_qj_device : public nes_txrom_device { public: // construction/destruction - nes_qj_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_qj_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void write_m(offs_t offset, u8 data) override; - virtual void write_m(offs_t offset, uint8_t data) override; virtual void pcb_reset() override; }; @@ -135,9 +135,10 @@ class nes_zz_device : public nes_txrom_device { public: // construction/destruction - nes_zz_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_zz_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void write_m(offs_t offset, u8 data) override; - virtual void write_m(offs_t offset, uint8_t data) override; virtual void pcb_reset() override; }; diff --git a/src/devices/bus/nes/mmc3_clones.cpp b/src/devices/bus/nes/mmc3_clones.cpp index 23e2969b149..fdf22c76a37 100644 --- a/src/devices/bus/nes/mmc3_clones.cpp +++ b/src/devices/bus/nes/mmc3_clones.cpp @@ -929,8 +929,6 @@ void nes_bmc_f600_device::device_start() void nes_bmc_f600_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - m_reg = 0; mmc3_common_initialize(0x1f, 0x7f, 0); } @@ -1041,8 +1039,6 @@ void nes_bmc_810305c_device::device_start() void nes_bmc_810305c_device::pcb_reset() { - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - m_outer = 0; mmc3_common_initialize(0x1f, 0x7f, 0); } @@ -3085,12 +3081,12 @@ void nes_bmc_f600_device::write_h(offs_t offset, u8 data) nes_txrom_device::write_h(offset, data); } -void nes_bmc_f600_device::chr_cb(int start, int bank, int source) +void nes_bmc_f600_device::set_chr(u8 chr, int chr_base, int chr_mask) { if ((m_reg & 0x07) == 1) - nes_txsrom_device::chr_cb(start, bank, source); + nes_txsrom_device::set_chr(chr, chr_base, chr_mask); else - nes_txrom_device::chr_cb(start, bank, source); + nes_txrom_device::set_chr(chr, chr_base, chr_mask); } /*------------------------------------------------- @@ -3452,16 +3448,10 @@ 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 + else if (m_outer) nes_txrom_device::set_chr(chr, chr_base, chr_mask); -} - -void nes_bmc_810305c_device::chr_cb(int start, int bank, int source) -{ - if (m_outer) - nes_txrom_device::chr_cb(start, bank, source); else - nes_txsrom_device::chr_cb(start, bank, source); + nes_txsrom_device::set_chr(chr, chr_base, chr_mask); } void nes_bmc_810305c_device::write_h(offs_t offset, u8 data) diff --git a/src/devices/bus/nes/mmc3_clones.h b/src/devices/bus/nes/mmc3_clones.h index c9cd8b0e57a..b4a4d8d43a7 100644 --- a/src/devices/bus/nes/mmc3_clones.h +++ b/src/devices/bus/nes/mmc3_clones.h @@ -901,7 +901,6 @@ public: virtual u8 read_l(offs_t offset) override; virtual void write_l(offs_t offset, u8 data) override; virtual void write_h(offs_t offset, u8 data) override; - virtual void chr_cb(int start, int bank, int source) override; virtual void pcb_reset() override; @@ -910,6 +909,8 @@ protected: virtual ioport_constructor device_input_ports() const override; virtual void device_start() override; + virtual void set_chr(u8 chr, int chr_base, int chr_mask) override; + private: required_ioport m_jumper; u8 m_reg; @@ -1074,7 +1075,6 @@ public: nes_bmc_810305c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void write_h(offs_t offset, u8 data) override; - virtual void chr_cb(int start, int bank, int source) override; virtual void pcb_reset() override; diff --git a/src/devices/bus/nes/pirate.cpp b/src/devices/bus/nes/pirate.cpp index 15db554f7f2..53301eb1aeb 100644 --- a/src/devices/bus/nes/pirate.cpp +++ b/src/devices/bus/nes/pirate.cpp @@ -18,7 +18,6 @@ #include "pirate.h" #include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE -#include "screen.h" #ifdef NES_PCB_DEBUG