From 88b9d73061072c5e441fff32ca4961ce333a6c71 Mon Sep 17 00:00:00 2001
From: 0kmg <9137159+0kmg@users.noreply.github.com>
Date: Wed, 13 Apr 2022 07:25:29 -0800
Subject: [PATCH] bus/nes: Updated Taito X1-017 boards. (#9535)
- Replaced bad program ROMs with dumps with proper page order.
- Updated banking to work with proper dumps.
- Fixed CHR banking from possibly ignoring first writes.
- Added special latching bytes to internal X1-017 RAM.
- Added IRQ support (no games exist that use it).
---
hash/nes.xml | 16 ++--
src/devices/bus/nes/nes_ines.hxx | 4 +-
src/devices/bus/nes/taito.cpp | 133 ++++++++++++++++++-------------
src/devices/bus/nes/taito.h | 25 ++++--
4 files changed, 104 insertions(+), 74 deletions(-)
diff --git a/hash/nes.xml b/hash/nes.xml
index c0bca0d067d..d7417a031a8 100644
--- a/hash/nes.xml
+++ b/hash/nes.xml
@@ -21301,7 +21301,7 @@ license:CC0
- Kyuukyoku Harikiri Koushien (Jpn)
+ Kyuukyoku Harikiri Koushien (Japan)
1992
Taito
@@ -21312,7 +21312,7 @@ license:CC0
-
+
@@ -21374,7 +21374,7 @@ license:CC0
- Kyuukyoku Harikiri Stadium III (Jpn)
+ Kyuukyoku Harikiri Stadium III (Japan)
1991
Taito
@@ -21385,7 +21385,7 @@ license:CC0
-
+
@@ -21397,7 +21397,7 @@ license:CC0
- Kyuukyoku Harikiri Stadium - Heisei Gannen Ban (Jpn)
+ Kyuukyoku Harikiri Stadium - Heisei Gannen Ban (Japan)
1989
Taito
@@ -21408,7 +21408,7 @@ license:CC0
-
+
@@ -32467,7 +32467,7 @@ license:CC0
- SD Keiji - Blader (Jpn)
+ SD Keiji - Blader (Japan)
1991
Taito
@@ -32478,7 +32478,7 @@ license:CC0
-
+
diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx
index 21a5388deea..22a21883a55 100644
--- a/src/devices/bus/nes/nes_ines.hxx
+++ b/src/devices/bus/nes/nes_ines.hxx
@@ -114,7 +114,7 @@ static const nes_mmc mmc_list[] =
{ 79, AVE_NINA06 },
{ 80, TAITO_X1_005 },
{ 81, NTDEC_N715021 }, // 81 Super Gun
- { 82, TAITO_X1_017 },
+ // 82 Taito X1-017 mapper for old mis-ordered PRG dumps
{ 83, CONY_BOARD },
// 84 Pasofami hacked images?
{ 85, KONAMI_VRC7 },
@@ -529,7 +529,7 @@ static const nes_mmc mmc_list[] =
{ 549, KAISER_KS7016B }, // Meikyuu Jiin Dababa alt FDS conversion
{ 550, BMC_JY820845C },
{ 551, JNCOTA_KT1001 },
- // 552 TAITO_X1_017, this is a correction of mapper 82. We should drop 82 and only support the accurate dumps of 552?
+ { 552, TAITO_X1_017 },
{ 553, SACHEN_3013 }, // Dong Dong Nao 1
{ 554, KAISER_KS7010 }, // Akumajo Dracula FDS conversion
{ 555, STD_EVENT2 },
diff --git a/src/devices/bus/nes/taito.cpp b/src/devices/bus/nes/taito.cpp
index 997ab9d2be8..fa29065c2df 100644
--- a/src/devices/bus/nes/taito.cpp
+++ b/src/devices/bus/nes/taito.cpp
@@ -66,8 +66,8 @@ nes_x1_005_device::nes_x1_005_device(const machine_config &mconfig, const char *
{
}
-nes_x1_017_device::nes_x1_017_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nes_nrom_device(mconfig, NES_X1_017, tag, owner, clock), m_latch(0)
+nes_x1_017_device::nes_x1_017_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_nrom_device(mconfig, NES_X1_017, tag, owner, clock), m_latch(0), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), irq_timer(nullptr)
{
}
@@ -125,6 +125,13 @@ void nes_x1_005_device::pcb_reset()
void nes_x1_017_device::device_start()
{
common_start();
+ irq_timer = timer_alloc(TIMER_IRQ);
+ irq_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
+
+ save_item(NAME(m_irq_enable));
+ save_item(NAME(m_irq_count));
+ save_item(NAME(m_irq_count_latch));
+
save_item(NAME(m_latch));
save_item(NAME(m_reg));
save_item(NAME(m_mmc_vrom_bank));
@@ -137,14 +144,17 @@ void nes_x1_017_device::device_start()
void nes_x1_017_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);
+ m_irq_enable = 0;
+ m_irq_count = 0;
+ m_irq_count_latch = 0;
+
m_latch = 0;
- memset(m_reg, 0, sizeof(m_reg));
- memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
+ m_reg[0] = m_reg[1] = m_reg[2] = 0;
+ std::fill(std::begin(m_mmc_vrom_bank), std::end(m_mmc_vrom_bank), 0x00);
}
@@ -279,9 +289,6 @@ void nes_tc0190fmc_pal16r4_device::write_h(offs_t offset, uint8_t data)
Actually, Fudou Myouou Den uses a variant of the board with
CIRAM, making necessary two distinct mappers & pcb_id.
- Also, we miss to emulate the security check at 0x7ef8 / 0x7ef9
- and the 0x80 ram!
-
iNES: mappers 80 & 207
-------------------------------------------------*/
@@ -364,37 +371,42 @@ uint8_t nes_x1_005_device::read_m(offs_t offset)
Taito X1-017 board emulation
- We miss to emulate the security check at 0x6000-0x73ff
- and the ram!
-
Games: Kyuukyoku Harikiri Koushien, Kyuukyoku Harikiri
- Stadium, SD Keiji - Blader
+ Stadium 3, Kyuukyoku Harikiri - Heisei Gannenban,
+ SD Keiji - Blader
- iNES: mapper 82
+ NES 2.0: mapper 552 (old mapper 82 are mis-ordered bad dumps)
- In MESS: Supported.
+ In MAME: Supported.
+
+ TODO: KH Koushien seems to be working except it needs to
+ be reset once with a new NVRAM file. KH Heisei won't
+ load "Single Game" menu option but other game modes work.
-------------------------------------------------*/
+void nes_x1_017_device::device_timer(emu_timer &timer, device_timer_id id, int param)
+{
+ if (id == TIMER_IRQ)
+ {
+ if ((m_irq_enable & 0x05) == 1 && m_irq_count) // counting enabled?
+ m_irq_count--;
+ if (!m_irq_count && BIT(m_irq_enable, 1))
+ set_irq_line(ASSERT_LINE);
+ }
+}
+
void nes_x1_017_device::set_chr()
{
- if (m_latch)
- {
- chr2_4(m_mmc_vrom_bank[0] >> 1, CHRROM);
- chr2_6(m_mmc_vrom_bank[1] >> 1, CHRROM);
- }
- else
- {
- chr2_0(m_mmc_vrom_bank[0] >> 1, CHRROM);
- chr2_2(m_mmc_vrom_bank[1] >> 1, CHRROM);
- }
+ chr2_x(0 ^ m_latch, m_mmc_vrom_bank[0] >> 1, CHRROM);
+ chr2_x(2 ^ m_latch, m_mmc_vrom_bank[1] >> 1, CHRROM);
chr1_x(4 ^ m_latch, m_mmc_vrom_bank[2], CHRROM);
chr1_x(5 ^ m_latch, m_mmc_vrom_bank[3], CHRROM);
chr1_x(6 ^ m_latch, m_mmc_vrom_bank[4], CHRROM);
chr1_x(7 ^ m_latch, m_mmc_vrom_bank[5], CHRROM);
}
-void nes_x1_017_device::write_m(offs_t offset, uint8_t data)
+void nes_x1_017_device::write_m(offs_t offset, u8 data)
{
LOG_MMC(("x1017 write_m, offset: %04x, data: %02x\n", offset, data));
@@ -406,19 +418,13 @@ void nes_x1_017_device::write_m(offs_t offset, uint8_t data)
case 0x1ef3:
case 0x1ef4:
case 0x1ef5:
- if (m_mmc_vrom_bank[offset & 0x07] != data)
- {
- m_mmc_vrom_bank[offset & 0x07] = data;
- set_chr();
- }
+ m_mmc_vrom_bank[offset & 0x07] = data;
+ set_chr();
break;
case 0x1ef6:
set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
- if (m_latch != ((data & 0x02) << 1))
- {
- m_latch = ((data & 0x02) << 1);
- set_chr();
- }
+ m_latch = (data & 0x02) << 1;
+ set_chr();
break;
case 0x1ef7:
case 0x1ef8:
@@ -426,39 +432,54 @@ void nes_x1_017_device::write_m(offs_t offset, uint8_t data)
m_reg[(offset & 0x0f) - 7] = data;
break;
case 0x1efa:
- prg8_89(data >> 2);
- break;
case 0x1efb:
- prg8_ab(data >> 2);
- break;
case 0x1efc:
- prg8_cd(data >> 2);
+ prg8_x((offset & 0x0f) - 0xa, bitswap<6>(data, 0, 1, 2, 3, 4, 5));
break;
- default:
- logerror("x1017_m_w uncaught write, addr: %04x, value: %02x\n", offset + 0x6000, data);
+ case 0x1efd:
+ m_irq_count_latch = data;
+ break;
+ case 0x1efe:
+ m_irq_enable = data;
+ if (!BIT(m_irq_enable, 0))
+ m_irq_count = m_irq_count_latch ? (m_irq_count_latch + 2) * 16 : 17;
+ if (!BIT(m_irq_enable, 1))
+ set_irq_line(CLEAR_LINE);
+ break;
+ case 0x1eff:
+ set_irq_line(CLEAR_LINE);
+ m_irq_count = m_irq_count_latch ? (m_irq_count_latch + 1) * 16 : 1;
break;
}
// 2+2+1 KB of Internal RAM can be independently enabled/disabled!
- if (offset < 0x0800 && m_reg[0] == 0xca)
- m_x1_017_ram[0x0000 + (offset & 0x7ff)] = data;
- if (offset < 0x1000 && m_reg[1] == 0x69)
- m_x1_017_ram[0x0800 + (offset & 0x7ff)] = data;
- if (offset < 0x1400 && m_reg[2] == 0x84)
- m_x1_017_ram[0x1000 + (offset & 0x3ff)] = data;
+ if ((offset < 0x0800 && m_reg[0] == 0xca) ||
+ (offset < 0x1000 && m_reg[1] == 0x69) ||
+ (offset < 0x1400 && m_reg[2] == 0x84))
+ {
+ m_x1_017_ram[offset] = data;
+
+ // 1st byte in each 1K page latches most recent read/write from that page
+ m_x1_017_ram[offset & 0x1c00] = data;
+ }
}
-uint8_t nes_x1_017_device::read_m(offs_t offset)
+u8 nes_x1_017_device::read_m(offs_t offset)
{
LOG_MMC(("x1017 read_m, offset: %04x\n", offset));
// 2+2+1 KB of Internal RAM can be independently enabled/disabled!
- if (offset < 0x0800 && m_reg[0] == 0xca)
- return m_x1_017_ram[0x0000 + (offset & 0x7ff)];
- if (offset < 0x1000 && m_reg[1] == 0x69)
- return m_x1_017_ram[0x0800 + (offset & 0x7ff)];
- if (offset < 0x1400 && m_reg[2] == 0x84)
- return m_x1_017_ram[0x1000 + (offset & 0x3ff)];
+ if ((offset < 0x0800 && m_reg[0] == 0xca) ||
+ (offset < 0x1000 && m_reg[1] == 0x69) ||
+ (offset < 0x1400 && m_reg[2] == 0x84))
+ {
+ u8 ret = m_x1_017_ram[offset];
- return get_open_bus();
+ // 1st byte in each 1K page latches most recent read/write from that page
+ m_x1_017_ram[offset & 0x1c00] = ret;
+
+ return ret;
+ }
+
+ return 0; // no open bus behavior due to pull-down resistors
}
diff --git a/src/devices/bus/nes/taito.h b/src/devices/bus/nes/taito.h
index dc2e282a8fd..1957dff3456 100644
--- a/src/devices/bus/nes/taito.h
+++ b/src/devices/bus/nes/taito.h
@@ -79,24 +79,34 @@ class nes_x1_017_device : public nes_nrom_device
{
public:
// construction/destruction
- nes_x1_017_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ nes_x1_017_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read_m(offs_t offset) override;
- virtual void write_m(offs_t offset, uint8_t data) override;
+ virtual u8 read_ex(offs_t offset) override { return 0; } // no open bus
+ virtual u8 read_l(offs_t offset) override { return 0; } // no open bus
+ virtual u8 read_m(offs_t offset) override;
+ virtual void write_m(offs_t offset, u8 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) override;
private:
void set_chr();
- uint8_t m_latch;
- uint8_t m_reg[3]; //mapper ram protect
- uint8_t m_mmc_vrom_bank[6];
+ u8 m_latch;
+ u8 m_reg[3]; // mapper ram enable
+ u8 m_mmc_vrom_bank[6];
// Taito X1-017 chip contains 5K of internal ram, battery backed up
- uint8_t m_x1_017_ram[0x1400];
+ u8 m_x1_017_ram[0x1400];
+
+ u16 m_irq_count;
+ u8 m_irq_count_latch;
+ u8 m_irq_enable;
+
+ static constexpr device_timer_id TIMER_IRQ = 0;
+ emu_timer *irq_timer;
};
@@ -106,5 +116,4 @@ DECLARE_DEVICE_TYPE(NES_TC0190FMC_PAL16R4, nes_tc0190fmc_pal16r4_device)
DECLARE_DEVICE_TYPE(NES_X1_005, nes_x1_005_device)
DECLARE_DEVICE_TYPE(NES_X1_017, nes_x1_017_device)
-
#endif // MAME_BUS_NES_TAITO_H