summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes
diff options
context:
space:
mode:
author 0kmg <9137159+0kmg@users.noreply.github.com>2021-10-11 04:49:37 -0800
committer GitHub <noreply@github.com>2021-10-11 23:49:37 +1100
commit32574013d259d40e4cc1137e7d498e60493babac (patch)
treea0069d2235f302f25af770c97c4e825db73cb80f /src/devices/bus/nes
parentc4979ef8d1daa847af76aa8f828f3422c16ab791 (diff)
bus/nes: Improved support for various VRC clone boards. (#8687)
* Expanded VRC4 CHR bank regs to 9-bit. This functionality is verified on Konami VRC4 hardware as well but is only used by clones (World Hero here). * Removed board for World Hero. Its VRC4 clone chip is under a glop top but is thought to be identical to Konami's. * Reimplemented TF1201 (Lethal Weapon) as a VRC4 subclass. Its clone chip is only known to differ by the IRQ reload bit, which it ignores. * Reimplemented Shui Guan Pipe as a VRC4 subclass. Its clone chip has different PRG banking but is otherwise standard. Software list items promoted to working (nes.xml) --------------------------------------- Gimmick! (Asia, pirate) Lethal Weapon (China) World Hero (Asia) World Hero (Asia, alt)
Diffstat (limited to 'src/devices/bus/nes')
-rw-r--r--src/devices/bus/nes/bootleg.cpp113
-rw-r--r--src/devices/bus/nes/bootleg.h29
-rw-r--r--src/devices/bus/nes/konami.cpp6
-rw-r--r--src/devices/bus/nes/konami.h2
-rw-r--r--src/devices/bus/nes/nes_carts.cpp2
-rw-r--r--src/devices/bus/nes/nes_ines.hxx10
-rw-r--r--src/devices/bus/nes/nes_pcb.hxx1
-rw-r--r--src/devices/bus/nes/nes_slot.h4
-rw-r--r--src/devices/bus/nes/pirate.cpp241
-rw-r--r--src/devices/bus/nes/pirate.h56
-rw-r--r--src/devices/bus/nes/vrc_clones.cpp160
-rw-r--r--src/devices/bus/nes/vrc_clones.h54
12 files changed, 226 insertions, 452 deletions
diff --git a/src/devices/bus/nes/bootleg.cpp b/src/devices/bus/nes/bootleg.cpp
index 842b932869f..a5262503ebd 100644
--- a/src/devices/bus/nes/bootleg.cpp
+++ b/src/devices/bus/nes/bootleg.cpp
@@ -70,7 +70,6 @@ DEFINE_DEVICE_TYPE(NES_LH53, nes_lh53_device, "nes_lh53", "N
DEFINE_DEVICE_TYPE(NES_2708, nes_2708_device, "nes_2708", "NES Cart BTL-2708 Pirate PCB")
DEFINE_DEVICE_TYPE(NES_AC08, nes_ac08_device, "nes_ac08", "NES Cart AC08 Pirate PCB")
DEFINE_DEVICE_TYPE(NES_MMALEE, nes_mmalee_device, "nes_mmalee", "NES Cart Super Mario Bros. Malee 2 Pirate PCB")
-DEFINE_DEVICE_TYPE(NES_SHUIGUAN, nes_shuiguan_device, "nes_shuiguan", "NES Cart Shui Guan Pipe Pirate PCB")
DEFINE_DEVICE_TYPE(NES_RT01, nes_rt01_device, "nes_rt01", "NES Cart RT-01 PCB")
DEFINE_DEVICE_TYPE(NES_YUNG08, nes_yung08_device, "nes_yung08", "NES Cart Super Mario Bros. 2 YUNG-08 PCB")
@@ -235,11 +234,6 @@ nes_mmalee_device::nes_mmalee_device(const machine_config &mconfig, const char *
{
}
-nes_shuiguan_device::nes_shuiguan_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_nrom_device(mconfig, NES_SHUIGUAN, tag, owner, clock), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
-{
-}
-
nes_rt01_device::nes_rt01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: nes_nrom_device(mconfig, NES_RT01, tag, owner, clock)
{
@@ -704,29 +698,6 @@ void nes_mmalee_device::pcb_reset()
prg32(0);
}
-void nes_shuiguan_device::device_start()
-{
- common_start();
- irq_timer = timer_alloc(TIMER_IRQ);
- // always running and checking for IRQ every 114 cycles? or resetting every frame?
- irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(114));
-
- save_item(NAME(m_irq_enable));
- save_item(NAME(m_irq_count));
- save_item(NAME(m_mmc_vrom_bank));
-}
-
-void nes_shuiguan_device::pcb_reset()
-{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- prg32((m_prg_chunks << 1) - 1);
- chr8(0, m_chr_source);
-
- m_irq_enable = 0;
- m_irq_count = 0;
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
-}
-
void nes_rt01_device::device_start()
{
common_start();
@@ -2220,90 +2191,6 @@ void nes_mmalee_device::write_m(offs_t offset, uint8_t data)
/*-------------------------------------------------
- BTL-SHUIGUANPIPE
-
- Games: Shui Guan Pipe (Gimmick Pirate)
-
- iNES: mapper 183
-
- In MAME: Supported, but there are glitches (PPU or IRQ?)
-
- -------------------------------------------------*/
-
-// timer always running and checking IRQ every 114 CPU cycles?
-void nes_shuiguan_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- if (id == TIMER_IRQ)
- {
- m_irq_count++;
- m_irq_count &= 0xff;
-
- if (m_irq_enable && !m_irq_count)
- hold_irq_line();
- }
-}
-
-void nes_shuiguan_device::write_h(offs_t offset, uint8_t data)
-{
- int bank;
- LOG_MMC(("shuiguan write_h, offset: %04x, data: %02x\n", offset, data));
-
- switch (offset & 0x7000)
- {
- case 0x0000:
- if (offset & 0x800 && !(offset & 0x0c)) // 0x8800-0x8803 + N*0x10
- prg8_89(data);
- break;
- case 0x1000:
- if (offset & 0x800 && !(offset & 0x0c)) // 0x9800-0x9803 + N*0x10
- {
- switch (data & 0x03)
- {
- case 0: set_nt_mirroring(PPU_MIRROR_VERT); break;
- case 1: set_nt_mirroring(PPU_MIRROR_HORZ); break;
- case 2: set_nt_mirroring(PPU_MIRROR_LOW); break;
- case 3: set_nt_mirroring(PPU_MIRROR_HIGH); break;
- }
- }
- break;
- case 0x2000:
- if (!(offset & 0x800) && !(offset & 0x0c)) // 0xa000-0xa003 + N*0x10
- prg8_cd(data);
- if (offset & 0x800 && !(offset & 0x0c)) // 0xa800-0xa803 + N*0x10
- prg8_ab(data);
- break;
- case 0x3000:
- case 0x4000:
- case 0x5000:
- case 0x6000:
- bank = (((offset + 0x1000) >> 11) | (offset >> 3)) & 0x07;
- if (offset & 4)
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x0f) << 4);
- else
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | ((data & 0x0f) << 0);
- chr1_x(bank, m_mmc_vrom_bank[bank], m_chr_source);
- break;
- case 0x7000:
- switch (offset & 0x0c)
- {
- case 0x00: m_irq_count = (m_irq_count & 0xf0) | ((data & 0x0f) << 0); break;
- case 0x04: m_irq_count = (m_irq_count & 0x0f) | ((data & 0x0f) << 4); break;
- case 0x08: m_irq_enable = data; break;
- case 0x0c: break;
- }
- break;
- }
-}
-
-uint8_t nes_shuiguan_device::read_m(offs_t offset)
-{
- // always first bank??
- LOG_MMC(("shuiguan read_m, offset: %04x\n", offset));
- return m_prg[offset & 0x1fff];
-}
-
-/*-------------------------------------------------
-
RT-01
Games: Russian test cart
diff --git a/src/devices/bus/nes/bootleg.h b/src/devices/bus/nes/bootleg.h
index 081173d3e2e..f26ad81af4d 100644
--- a/src/devices/bus/nes/bootleg.h
+++ b/src/devices/bus/nes/bootleg.h
@@ -686,34 +686,6 @@ protected:
};
-// ======================> nes_shuiguan_device
-
-class nes_shuiguan_device : public nes_nrom_device
-{
-public:
- // construction/destruction
- nes_shuiguan_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual uint8_t read_m(offs_t offset) override;
- virtual void write_h(offs_t offset, uint8_t data) override;
-
- virtual void pcb_reset() override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
-private:
- uint16_t m_irq_count;
- int m_irq_enable;
- uint8_t m_mmc_vrom_bank[8];
-
- static const device_timer_id TIMER_IRQ = 0;
- emu_timer *irq_timer;
-};
-
-
// ======================> nes_rt01_device
class nes_rt01_device : public nes_nrom_device
@@ -794,7 +766,6 @@ DECLARE_DEVICE_TYPE(NES_LH53, nes_lh53_device)
DECLARE_DEVICE_TYPE(NES_2708, nes_2708_device)
DECLARE_DEVICE_TYPE(NES_AC08, nes_ac08_device)
DECLARE_DEVICE_TYPE(NES_MMALEE, nes_mmalee_device)
-DECLARE_DEVICE_TYPE(NES_SHUIGUAN, nes_shuiguan_device)
DECLARE_DEVICE_TYPE(NES_RT01, nes_rt01_device)
DECLARE_DEVICE_TYPE(NES_YUNG08, nes_yung08_device)
diff --git a/src/devices/bus/nes/konami.cpp b/src/devices/bus/nes/konami.cpp
index 2f77b855205..64b8d92d1f0 100644
--- a/src/devices/bus/nes/konami.cpp
+++ b/src/devices/bus/nes/konami.cpp
@@ -484,7 +484,7 @@ void nes_konami_vrc4_device::set_prg()
void nes_konami_vrc4_device::write_h(offs_t offset, uint8_t data)
{
- uint8_t bank, shift, mask;
+ int bank, shift, mask;
uint16_t add_lines = ((offset << (9 - m_vrc_ls_prg_a)) & 0x200) | ((offset << (8 - m_vrc_ls_prg_b)) & 0x100);
LOG_MMC(("VRC-4 write_h, offset: %04x, data: %02x\n", offset, data));
@@ -520,8 +520,8 @@ void nes_konami_vrc4_device::write_h(offs_t offset, uint8_t data)
case 0x6000:
bank = ((offset & 0x7000) - 0x3000) / 0x0800 + BIT(add_lines, 9);
shift = BIT(add_lines, 8) * 4;
- mask = (0xf0 >> shift);
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & mask) | ((data & 0x0f) << shift);
+ mask = shift ? 0x1f0 : 0x0f;
+ m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & ~mask) | ((data << shift) & mask);
chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
break;
case 0x7000:
diff --git a/src/devices/bus/nes/konami.h b/src/devices/bus/nes/konami.h
index 7f7e7448938..1a451b00733 100644
--- a/src/devices/bus/nes/konami.h
+++ b/src/devices/bus/nes/konami.h
@@ -105,7 +105,7 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
void set_prg();
- uint8_t m_mmc_vrom_bank[8];
+ uint16_t m_mmc_vrom_bank[8];
uint8_t m_latch, m_mmc_prg_bank;
void irq_tick();
diff --git a/src/devices/bus/nes/nes_carts.cpp b/src/devices/bus/nes/nes_carts.cpp
index 6deb671cf2f..cff3176786a 100644
--- a/src/devices/bus/nes/nes_carts.cpp
+++ b/src/devices/bus/nes/nes_carts.cpp
@@ -65,6 +65,7 @@
#include "pirate.h"
#include "mmc1_clones.h"
#include "mmc3_clones.h"
+#include "vrc_clones.h"
void nes_cart(device_slot_interface &device)
@@ -293,7 +294,6 @@ void nes_cart(device_slot_interface &device)
device.option_add_internal("edu2k", NES_EDU2K);
device.option_add_internal("t230", NES_T230);
device.option_add_internal("mk2", NES_MK2);
- device.option_add_internal("unl_whero", NES_WHERO); // mapper 27
device.option_add_internal("unl_43272", NES_43272); // used in Gaau Hok Gwong Cheung
device.option_add_internal("tf1201", NES_TF1201);
device.option_add_internal("unl_cfight", NES_CITYFIGHT); // used by City Fighter IV
diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx
index b70b8156f4c..506f4e25553 100644
--- a/src/devices/bus/nes/nes_ines.hxx
+++ b/src/devices/bus/nes/nes_ines.hxx
@@ -59,11 +59,11 @@ static const nes_mmc mmc_list[] =
{ 24, KONAMI_VRC6 },
{ 25, KONAMI_VRC4 },
{ 26, KONAMI_VRC6 },
- { 27, UNL_WORLDHERO }, // 27 World Hero board - Unsupported
- { 28, UNL_ACTION53 }, // 28 - Multi-discrete PCB designed by Tepples for Action 53
- { 29, UNL_CUFROM }, // 29 - homebrew PCB used by Glider
- { 30, UNL_UNROM512 }, // 30 - UNROM 512 + Flash
- { 31, UNL_2A03PURITANS }, // 31 - PCB designed by infinitelives & rainwarrior for 2A03 Puritans Album
+ { 27, UNL_CC21 }, // Mihunche, but previously used for World Hero
+ { 28, UNL_ACTION53 }, // Multi-discrete PCB designed by Tepples for Action 53
+ { 29, UNL_CUFROM }, // homebrew PCB used by Glider
+ { 30, UNL_UNROM512 }, // UNROM 512 + Flash
+ { 31, UNL_2A03PURITANS }, // PCB designed by infinitelives & rainwarrior for 2A03 Puritans Album
{ 32, IREM_G101 },
{ 33, TAITO_TC0190FMC },
{ 34, STD_BXROM },
diff --git a/src/devices/bus/nes/nes_pcb.hxx b/src/devices/bus/nes/nes_pcb.hxx
index 95b55264383..f79a8e09512 100644
--- a/src/devices/bus/nes/nes_pcb.hxx
+++ b/src/devices/bus/nes/nes_pcb.hxx
@@ -364,7 +364,6 @@ static const nes_pcb pcb_list[] =
{ "unl_malisb", UNL_MALISB },
{ "sgpipe", BTL_SHUIGUAN },
{ "rt01", UNL_RT01 }, // Russian Test Cart
- { "unl_whero", UNL_WORLDHERO },
{ "unl_43272", UNL_43272 },
{ "tf1201", UNL_TF1201 },
{ "unl_cfight", UNL_CITYFIGHT },
diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h
index e9d02522bce..98a48335128 100644
--- a/src/devices/bus/nes/nes_slot.h
+++ b/src/devices/bus/nes/nes_slot.h
@@ -114,8 +114,8 @@ enum
UNL_UXROM, UNL_MK2, UNL_XIAOZY, UNL_KOF96, UNL_FS6,
UNL_SF3, UNL_RACERMATE, UNL_EDU2K,
UNL_STUDYNGAME, UNL_603_5052, UNL_H2288, UNL_158B, UNL_2708,
- UNL_MALISB, UNL_AC08, UNL_A9746, UNL_WORLDHERO,
- UNL_43272, UNL_TF1201, UNL_CITYFIGHT, UNL_NINJARYU, UNL_EH8813A, UNL_RT01,
+ UNL_MALISB, UNL_AC08, UNL_A9746, UNL_43272, UNL_TF1201,
+ UNL_CITYFIGHT, UNL_NINJARYU, UNL_EH8813A, UNL_RT01,
// Bootleg boards
BTL_0353, BTL_09034A, BTL_AISENSHINICOL, BTL_BATMANFS,
BTL_CONTRAJ, BTL_DRAGONNINJA, BTL_L001, BTL_MARIOBABY,
diff --git a/src/devices/bus/nes/pirate.cpp b/src/devices/bus/nes/pirate.cpp
index ddfc93ae258..69cf7b08ad1 100644
--- a/src/devices/bus/nes/pirate.cpp
+++ b/src/devices/bus/nes/pirate.cpp
@@ -45,9 +45,7 @@ DEFINE_DEVICE_TYPE(NES_XIAOZY, nes_xiaozy_device, "nes_xiaozy", "
DEFINE_DEVICE_TYPE(NES_EDU2K, nes_edu2k_device, "nes_edu2k", "NES Cart Educational Computer 2000 PCB")
DEFINE_DEVICE_TYPE(NES_T230, nes_t230_device, "nes_t230", "NES Cart T-230 PCB")
DEFINE_DEVICE_TYPE(NES_MK2, nes_mk2_device, "nes_mk2", "NES Cart Mortal Kombat 2 PCB")
-DEFINE_DEVICE_TYPE(NES_WHERO, nes_whero_device, "nes_whero", "NES Cart World Heroes PCB")
DEFINE_DEVICE_TYPE(NES_43272, nes_43272_device, "nes_43272", "NES Cart UNL-43272 PCB")
-DEFINE_DEVICE_TYPE(NES_TF1201, nes_tf1201_device, "nes_tf1201", "NES Cart UNL-TF1201 PCB")
DEFINE_DEVICE_TYPE(NES_CITYFIGHT, nes_cityfight_device, "nes_cityfight", "NES Cart City Fighter PCB")
DEFINE_DEVICE_TYPE(NES_EH8813A, nes_eh8813a_device, "nes_eh8813a", "NES Cart UNL-EH8813A PCB")
@@ -107,21 +105,11 @@ nes_mk2_device::nes_mk2_device(const machine_config &mconfig, const char *tag, d
{
}
-nes_whero_device::nes_whero_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_nrom_device(mconfig, NES_WHERO, tag, owner, clock), m_reg(0), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_enable_latch(0)
-{
-}
-
nes_43272_device::nes_43272_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: nes_nrom_device(mconfig, NES_43272, tag, owner, clock), m_latch(0)
{
}
-nes_tf1201_device::nes_tf1201_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_nrom_device(mconfig, NES_TF1201, tag, owner, clock), m_prg(0), m_swap(0), m_irq_count(0), m_irq_enable(0), m_irq_enable_latch(0)
-{
-}
-
nes_cityfight_device::nes_cityfight_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: nes_nrom_device(mconfig, NES_CITYFIGHT, tag, owner, clock), m_prg_reg(0), m_prg_mode(0), m_irq_count(0), m_irq_enable(0), irq_timer(nullptr)
{
@@ -303,34 +291,6 @@ void nes_mk2_device::pcb_reset()
m_irq_count = m_irq_count_latch = 0;
}
-
-void nes_whero_device::device_start()
-{
- common_start();
- save_item(NAME(m_irq_enable));
- save_item(NAME(m_irq_enable_latch));
- save_item(NAME(m_irq_count));
- save_item(NAME(m_irq_count_latch));
- save_item(NAME(m_reg));
- save_item(NAME(m_mmc_vrom_bank));
-}
-
-void nes_whero_device::pcb_reset()
-{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- prg16_89ab(0);
- prg16_cdef(m_prg_chunks - 1);
- chr8(0x100, m_chr_source);
-
- m_irq_enable = 0;
- m_irq_enable_latch = 0;
- m_irq_count = 0;
- m_irq_count_latch = 0;
-
- m_reg = 0;
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
-}
-
void nes_43272_device::device_start()
{
common_start();
@@ -346,32 +306,6 @@ void nes_43272_device::pcb_reset()
m_latch = 0x81;
}
-void nes_tf1201_device::device_start()
-{
- common_start();
- save_item(NAME(m_prg));
- save_item(NAME(m_swap));
- save_item(NAME(m_irq_enable));
- save_item(NAME(m_irq_enable_latch));
- save_item(NAME(m_irq_count));
- save_item(NAME(m_mmc_vrom_bank));
-}
-
-void nes_tf1201_device::pcb_reset()
-{
- m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
- prg16_89ab(0);
- prg16_cdef(m_prg_chunks - 1);
- chr8(0, m_chr_source);
-
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
- m_prg = 0;
- m_swap = 0;
- m_irq_enable = 0;
- m_irq_enable_latch = 0;
- m_irq_count = 0;
-}
-
void nes_cityfight_device::device_start()
{
common_start();
@@ -915,102 +849,6 @@ void nes_mk2_device::write_m(offs_t offset, uint8_t data)
}
}
-
-/*-------------------------------------------------
-
- UNL-WORLDHERO board emulation
-
-
- iNES:
-
- -------------------------------------------------*/
-
-// Same as Konami VRC IRQ...
-void nes_whero_device::hblank_irq(int scanline, int vblank, int blanked)
-{
- /* Increment & check the IRQ scanline counter */
- if (m_irq_enable && (++m_irq_count == 0x100))
- {
- m_irq_count = m_irq_count_latch;
- m_irq_enable = m_irq_enable_latch;
- hold_irq_line();
- }
-}
-
-void nes_whero_device::write_h(offs_t offset, uint8_t data)
-{
- int bank, shift, mask1, mask2;
- LOG_MMC(("World Hero write_h, offset: %04x, data: %02x\n", offset, data));
-
- switch (offset & 0x70c3)
- {
- case 0x0000:
- if (!m_reg)
- prg8_89(data);
- else
- prg8_cd(data);
- break;
-
- case 0x1000:
- switch (data & 0x03)
- {
- case 0x00: set_nt_mirroring(PPU_MIRROR_VERT); break;
- case 0x01: set_nt_mirroring(PPU_MIRROR_HORZ); break;
- case 0x02: set_nt_mirroring(PPU_MIRROR_LOW); break;
- case 0x03: set_nt_mirroring(PPU_MIRROR_HIGH); break;
- }
- break;
-
- case 0x1002:
- case 0x1080:
- if (m_reg != (data & 2))
- {
- m_reg = data & 2;
- // swap banks!
- prg8_89(m_prg_bank[2]);
- prg8_cd(m_prg_bank[0]);
- }
- break;
-
- case 0x2000:
- prg8_ab(data);
- break;
-
- case 0x3000: case 0x3001: case 0x3002: case 0x3003:
- case 0x4000: case 0x4001: case 0x4002: case 0x4003:
- case 0x5000: case 0x5001: case 0x5002: case 0x5003:
- case 0x6000: case 0x6001: case 0x6002: case 0x6003:
- bank = ((offset & 0x7000) - 0x3000) / 0x0800 + BIT(offset, 1);
- shift = (offset & 1) << 2;
- mask1 = shift ? 0x00f : 0xff0;
- mask2 = shift ? 0xff0 : 0x00f;
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & mask1) | ((data << shift) & mask2);
- chr1_x(bank, m_mmc_vrom_bank[bank], CHRROM);
- break;
-
- case 0x7000:
- m_irq_count_latch = (m_irq_count_latch & 0xf0) | (data & 0x0f);
- break;
-
- case 0x7001:
- m_irq_count_latch = (m_irq_count_latch & 0x0f) | ((data & 0x0f) << 4);
- break;
-
- case 0x7002:
- // m_irq_mode = data & 0x04; // currently not implemented: 0 = prescaler mode / 1 = CPU mode
- m_irq_enable = data & 0x02;
- m_irq_enable_latch = data & 0x01;
- if (data & 0x02)
- m_irq_count = m_irq_count_latch;
- break;
-
- case 0x7003:
- m_irq_enable = m_irq_enable_latch;
- break;
- }
-}
-
-
/*-------------------------------------------------
UNL-43272
@@ -1040,85 +878,6 @@ uint8_t nes_43272_device::read_h(offs_t offset)
return hi_access_rom(offset & mask);
}
-
-/*-------------------------------------------------
-
- UNL-TF1201
-
- Games:
-
- In MESS: Preliminary Supported
-
- -------------------------------------------------*/
-
-void nes_tf1201_device::hblank_irq(int scanline, int vblank, int blanked)
-{
- if (m_irq_enable_latch != m_irq_enable && scanline < 240)
- m_irq_count -= 8;
-
- if (m_irq_enable)
- {
- m_irq_count++;
- if ((m_irq_count & 0xff) == 238)
- hold_irq_line();
- }
-}
-
-void nes_tf1201_device::update_prg()
-{
- prg8_89(m_swap ? 0xff : m_prg);
- prg8_cd(m_swap ? m_prg : 0xff );
-}
-
-void nes_tf1201_device::write_h(offs_t offset, uint8_t data)
-{
- int bank;
- LOG_MMC(("unl_tf1201 write_h, offset: %04x, data: %02x\n", offset, data));
-
- offset = (offset & 0x7003) | ((offset & 0x0c) >> 2); // nestopia does not OR here...
-
- switch (offset & 0x7003)
- {
- case 0x0000:
- m_prg = data;
- update_prg();
- break;
- case 0x1000:
- set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
- break;
- case 0x1001:
- m_swap = data & 0x03;
- update_prg();
- break;
- case 0x2000:
- prg8_ab(data);
- break;
- case 0x3000: case 0x3001: case 0x3002: case 0x3003:
- case 0x4000: case 0x4001: case 0x4002: case 0x4003:
- case 0x5000: case 0x5001: case 0x5002: case 0x5003:
- case 0x6000: case 0x6001: case 0x6002: case 0x6003:
- bank = (((offset - 0x3000) >> 11) | (offset & 0x1)) & 0x7;
- if (offset & 2)
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0x0f) | ((data & 0x0f) << 4);
- else
- m_mmc_vrom_bank[bank] = (m_mmc_vrom_bank[bank] & 0xf0) | ((data & 0x0f) << 0);
- chr1_x(bank, m_mmc_vrom_bank[bank], m_chr_source);
- break;
- case 0x7000:
- m_irq_count = (m_irq_count & 0xf0) | (data & 0x0f);
- break;
- case 0x7001:
- case 0x7003:
- m_irq_enable_latch = m_irq_enable;
- m_irq_enable = BIT(data, 1);
- break;
- case 0x7002:
- m_irq_count = (m_irq_count & 0x0f) | ((data & 0x0f) << 4);
- break;
- }
-}
-
-
/*-------------------------------------------------
UNL-CITYFIGHT
diff --git a/src/devices/bus/nes/pirate.h b/src/devices/bus/nes/pirate.h
index 9f54fc778ca..1b0766f9d92 100644
--- a/src/devices/bus/nes/pirate.h
+++ b/src/devices/bus/nes/pirate.h
@@ -235,33 +235,6 @@ private:
};
-// ======================> nes_whero_device
-
-class nes_whero_device : public nes_nrom_device
-{
-public:
- // construction/destruction
- nes_whero_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void write_h(offs_t offset, uint8_t data) override;
-
- virtual void hblank_irq(int scanline, int vblank, int blanked) override;
- virtual void pcb_reset() override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
-
-private:
- uint8_t m_reg;
- uint8_t m_mmc_vrom_bank[8];
-
- uint16_t m_irq_count, m_irq_count_latch;
- int m_irq_enable, m_irq_enable_latch;
-// int m_irq_mode;
-};
-
-
// ======================> nes_43272_device
class nes_43272_device : public nes_nrom_device
@@ -284,33 +257,6 @@ private:
};
-// ======================> nes_tf1201_device
-
-class nes_tf1201_device : public nes_nrom_device
-{
-public:
- // construction/destruction
- nes_tf1201_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void write_h(offs_t offset, uint8_t data) override;
-
- virtual void hblank_irq(int scanline, int vblank, int blanked) override;
- virtual void pcb_reset() override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
-
-private:
- void update_prg();
- uint8_t m_prg, m_swap;
- uint16_t m_irq_count;
- int m_irq_enable, m_irq_enable_latch;
-
- uint8_t m_mmc_vrom_bank[8];
-};
-
-
// ======================> nes_cityfight_device
class nes_cityfight_device : public nes_nrom_device
@@ -404,9 +350,7 @@ DECLARE_DEVICE_TYPE(NES_XIAOZY, nes_xiaozy_device)
DECLARE_DEVICE_TYPE(NES_EDU2K, nes_edu2k_device)
DECLARE_DEVICE_TYPE(NES_T230, nes_t230_device)
DECLARE_DEVICE_TYPE(NES_MK2, nes_mk2_device)
-DECLARE_DEVICE_TYPE(NES_WHERO, nes_whero_device)
DECLARE_DEVICE_TYPE(NES_43272, nes_43272_device)
-DECLARE_DEVICE_TYPE(NES_TF1201, nes_tf1201_device)
DECLARE_DEVICE_TYPE(NES_CITYFIGHT, nes_cityfight_device)
DECLARE_DEVICE_TYPE(NES_EH8813A, nes_eh8813a_device)
//DECLARE_DEVICE_TYPE(NES_FUJIYA, nes_fujiya_device)
diff --git a/src/devices/bus/nes/vrc_clones.cpp b/src/devices/bus/nes/vrc_clones.cpp
new file mode 100644
index 00000000000..e961b20ffb9
--- /dev/null
+++ b/src/devices/bus/nes/vrc_clones.cpp
@@ -0,0 +1,160 @@
+// license:BSD-3-Clause
+// copyright-holders: kmg, Fabio Priuli
+/***********************************************************************************************************
+
+
+ NES/Famicom cartridge emulation for Konami VRC clone PCBs
+
+
+ Here we emulate several pirate PCBs based on VRC2/4 boards
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "vrc_clones.h"
+
+
+#ifdef NES_PCB_DEBUG
+#define VERBOSE 1
+#else
+#define VERBOSE 0
+#endif
+
+#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
+
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+DEFINE_DEVICE_TYPE(NES_SHUIGUAN, nes_shuiguan_device, "nes_shuiguan", "NES Cart Shui Guan Pipe Pirate PCB")
+DEFINE_DEVICE_TYPE(NES_TF1201, nes_tf1201_device, "nes_tf1201", "NES Cart UNL-TF1201 PCB")
+
+
+nes_shuiguan_device::nes_shuiguan_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_konami_vrc4_device(mconfig, NES_SHUIGUAN, tag, owner, clock)
+{
+}
+
+nes_tf1201_device::nes_tf1201_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_konami_vrc4_device(mconfig, NES_TF1201, tag, owner, clock)
+{
+}
+
+
+
+void nes_shuiguan_device::device_start()
+{
+ nes_konami_vrc4_device::device_start();
+ save_item(NAME(m_reg));
+
+ // VRC4 pins 3 and 4
+ m_vrc_ls_prg_a = 3; // A3
+ m_vrc_ls_prg_b = 2; // A2
+}
+
+void nes_shuiguan_device::pcb_reset()
+{
+ nes_konami_vrc4_device::pcb_reset();
+ m_reg = 0;
+}
+
+void nes_tf1201_device::device_start()
+{
+ nes_konami_vrc4_device::device_start();
+
+ // VRC4 pins 3 and 4
+ m_vrc_ls_prg_a = 0; // A0
+ m_vrc_ls_prg_b = 1; // A1
+}
+
+
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+/*-------------------------------------------------
+
+ BTL-SHUIGUANPIPE
+
+ Games: Shui Guan Pipe (Gimmick Pirate)
+
+ VRC4 clone that differs in its PRG banking only.
+
+ iNES: mapper 183
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+u8 nes_shuiguan_device::read_m(offs_t offset)
+{
+// LOG_MMC(("shuiguan read_m, offset: %04x\n", offset));
+ return m_prg[(m_reg * 0x2000 + offset) & (m_prg_size - 1)];
+}
+
+void nes_shuiguan_device::write_m(offs_t offset, u8 data)
+{
+ LOG_MMC(("shuiguan write_m, offset: %04x, data: %02x\n", offset, data));
+ if ((offset & 0x1800) == 0x800)
+ m_reg = offset & 0x1f;
+}
+
+void nes_shuiguan_device::write_h(offs_t offset, u8 data)
+{
+ LOG_MMC(("shuiguan write_h, offset: %04x, data: %02x\n", offset, data));
+
+ switch (offset & 0x7800)
+ {
+ case 0x0000:
+ case 0x1000:
+ break; // writes to $8000 and $9000 ignored
+ case 0x0800:
+ prg8_89(data);
+ break;
+ case 0x2000:
+ prg8_cd(data);
+ break;
+ case 0x2800:
+ prg8_ab(data);
+ break;
+ default:
+ nes_konami_vrc4_device::write_h(offset, data);
+ break;
+ }
+}
+
+/*-------------------------------------------------
+
+ UNL-TF1201
+
+ Games: Leathal Weapon (Leathal Enforcers clone)
+
+ VRC4 clone where the only known difference is in the
+ IRQ behavior. This clone does not copy the IRQ reload
+ bit to the enable bit on writes to IRQ acknowledge.
+
+ NES 2.0: mapper 298
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+void nes_tf1201_device::write_h(offs_t offset, u8 data)
+{
+ LOG_MMC(("unl_tf1201 write_h, offset: %04x, data: %02x\n", offset, data));
+
+ if ((offset & 0x7003) == 0x7003)
+ set_irq_line(CLEAR_LINE);
+ else
+ nes_konami_vrc4_device::write_h(offset, data);
+}
+
+
+/*-------------------------------------------------
+
+ MULTIGAME CARTS BASED ON VRC
+
+ -------------------------------------------------*/
diff --git a/src/devices/bus/nes/vrc_clones.h b/src/devices/bus/nes/vrc_clones.h
new file mode 100644
index 00000000000..6fb950c1c7e
--- /dev/null
+++ b/src/devices/bus/nes/vrc_clones.h
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders: kmg, Fabio Priuli
+#ifndef MAME_BUS_NES_VRC_CLONES_H
+#define MAME_BUS_NES_VRC_CLONES_H
+
+#pragma once
+
+#include "konami.h"
+
+
+// ======================> nes_shuiguan_device
+
+class nes_shuiguan_device : public nes_konami_vrc4_device
+{
+public:
+ // construction/destruction
+ nes_shuiguan_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual u8 read_m(offs_t offset) override;
+ virtual void write_m(offs_t offset, u8 data) override;
+ virtual void write_h(offs_t offset, u8 data) override;
+
+ virtual void pcb_reset() override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+private:
+ u8 m_reg;
+};
+
+
+// ======================> nes_tf1201_device
+
+class nes_tf1201_device : public nes_konami_vrc4_device
+{
+public:
+ // construction/destruction
+ nes_tf1201_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual void write_h(offs_t offset, u8 data) override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(NES_SHUIGUAN, nes_shuiguan_device)
+DECLARE_DEVICE_TYPE(NES_TF1201, nes_tf1201_device)
+
+#endif // MAME_BUS_NES_VRC_CLONES_H