summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes/taito.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nes/taito.cpp')
-rw-r--r--src/devices/bus/nes/taito.cpp322
1 files changed, 154 insertions, 168 deletions
diff --git a/src/devices/bus/nes/taito.cpp b/src/devices/bus/nes/taito.cpp
index 28c37b6109c..d27b8fb2695 100644
--- a/src/devices/bus/nes/taito.cpp
+++ b/src/devices/bus/nes/taito.cpp
@@ -20,20 +20,19 @@
***********************************************************************************************************/
-
#include "emu.h"
#include "taito.h"
#include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE
+#define LOG_UNHANDLED (1U << 1)
#ifdef NES_PCB_DEBUG
-#define VERBOSE 1
+#define VERBOSE (LOG_UNHANDLED | LOG_GENERAL)
#else
-#define VERBOSE 0
+#define VERBOSE (LOG_UNHANDLED)
#endif
-
-#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
+#include "logmacro.h"
//-------------------------------------------------
@@ -46,41 +45,35 @@ DEFINE_DEVICE_TYPE(NES_X1_005, nes_x1_005_device, "nes_x1_
DEFINE_DEVICE_TYPE(NES_X1_017, nes_x1_017_device, "nes_x1_017", "NES Cart Taito X1-017 PCB")
-nes_tc0190fmc_device::nes_tc0190fmc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+nes_tc0190fmc_device::nes_tc0190fmc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: nes_nrom_device(mconfig, type, tag, owner, clock)
{
}
-nes_tc0190fmc_device::nes_tc0190fmc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_tc0190fmc_device::nes_tc0190fmc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_tc0190fmc_device(mconfig, NES_TC0190FMC, tag, owner, clock)
{
}
-nes_tc0190fmc_pal16r4_device::nes_tc0190fmc_pal16r4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_tc0190fmc_pal16r4_device::nes_tc0190fmc_pal16r4_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_tc0190fmc_device(mconfig, NES_TC0190FMC_PAL16R4, tag, owner, clock), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0)
{
}
-nes_x1_005_device::nes_x1_005_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+nes_x1_005_device::nes_x1_005_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: nes_nrom_device(mconfig, NES_X1_005, tag, owner, clock), m_latch(0)
{
}
-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)
{
}
-void nes_tc0190fmc_device::device_start()
-{
- common_start();
-}
-
void nes_tc0190fmc_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);
@@ -88,7 +81,7 @@ void nes_tc0190fmc_device::pcb_reset()
void nes_tc0190fmc_pal16r4_device::device_start()
{
- common_start();
+ nes_tc0190fmc_device::device_start();
save_item(NAME(m_irq_enable));
save_item(NAME(m_irq_count));
save_item(NAME(m_irq_count_latch));
@@ -96,10 +89,7 @@ void nes_tc0190fmc_pal16r4_device::device_start()
void nes_tc0190fmc_pal16r4_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);
+ nes_tc0190fmc_device::pcb_reset();
m_irq_enable = 0;
m_irq_count = 0;
@@ -119,7 +109,6 @@ void nes_x1_005_device::device_start()
void nes_x1_005_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);
@@ -130,6 +119,13 @@ void nes_x1_005_device::pcb_reset()
void nes_x1_017_device::device_start()
{
common_start();
+ irq_timer = timer_alloc(FUNC(nes_x1_017_device::irq_timer_tick), this);
+ 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));
@@ -142,14 +138,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);
}
@@ -168,15 +167,15 @@ void nes_x1_017_device::pcb_reset()
iNES: mapper 33
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_tc0190fmc_device::tc0190fmc_write(offs_t offset, uint8_t data)
+void nes_tc0190fmc_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("tc0190fmc_write, offset: %04x, data: %02x\n", offset, data));
+ LOG("tc0190fmc write_h, offset: %04x, data: %02x\n", offset, data);
- switch (offset & 0x7003)
+ switch (offset & 0x6003)
{
case 0x0000:
set_nt_mirroring(BIT(data, 6) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
@@ -186,22 +185,14 @@ void nes_tc0190fmc_device::tc0190fmc_write(offs_t offset, uint8_t data)
prg8_ab(data);
break;
case 0x0002:
- chr2_0(data, CHRROM);
- break;
case 0x0003:
- chr2_2(data, CHRROM);
+ chr2_x((offset & 1) << 1, data, CHRROM);
break;
case 0x2000:
- chr1_4(data, CHRROM);
- break;
case 0x2001:
- chr1_5(data, CHRROM);
- break;
case 0x2002:
- chr1_6(data, CHRROM);
- break;
case 0x2003:
- chr1_7(data, CHRROM);
+ chr1_x((offset & 0x03) | 4, data, CHRROM);
break;
}
}
@@ -221,30 +212,30 @@ void nes_tc0190fmc_device::tc0190fmc_write(offs_t offset, uint8_t data)
iNES: mapper 48
- In MESS: Supported.
+ In MAME: Supported.
-------------------------------------------------*/
-void nes_tc0190fmc_pal16r4_device::hblank_irq( int scanline, int vblank, int blanked )
+void nes_tc0190fmc_pal16r4_device::hblank_irq(int scanline, bool vblank, bool blanked)
{
if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE)
{
- int prior_count = m_irq_count;
- if (m_irq_count == 0)
- m_irq_count = m_irq_count_latch;
- else
+ if (m_irq_count)
+ {
m_irq_count--;
-
- if (m_irq_enable && !blanked && (m_irq_count == 0) && prior_count)
- set_irq_line(ASSERT_LINE);
+ if (m_irq_enable && !blanked && !m_irq_count)
+ set_irq_line(ASSERT_LINE);
+ }
+ else
+ m_irq_count = m_irq_count_latch;
}
}
-void nes_tc0190fmc_pal16r4_device::write_h(offs_t offset, uint8_t data)
+void nes_tc0190fmc_pal16r4_device::write_h(offs_t offset, u8 data)
{
- LOG_MMC(("tc0190fmc pal16r4 write_h, offset: %04x, data: %02x\n", offset, data));
+ LOG("tc0190fmc pal16r4 write_h, offset: %04x, data: %02x\n", offset, data);
- switch (offset & 0x7003)
+ switch (offset & 0x6003)
{
case 0x0000:
prg8_89(data);
@@ -256,10 +247,10 @@ void nes_tc0190fmc_pal16r4_device::write_h(offs_t offset, uint8_t data)
case 0x2001:
case 0x2002:
case 0x2003:
- tc0190fmc_write(offset, data);
+ nes_tc0190fmc_device::write_h(offset, data);
break;
case 0x4000:
- m_irq_count_latch = (0x100 - data) & 0xff;
+ m_irq_count_latch = ~data;
break;
case 0x4001:
m_irq_count = m_irq_count_latch;
@@ -284,124 +275,110 @@ 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
-------------------------------------------------*/
-void nes_x1_005_device::write_m(offs_t offset, uint8_t data)
+void nes_x1_005_device::write_m(offs_t offset, u8 data)
{
- LOG_MMC(("x1_005 write_m, offset: %04x, data: %02x\n", offset, data));
+ LOG("x1_005 write_m, offset: %04x, data: %02x\n", offset, data);
- switch (offset)
+ if ((offset & 0x1f70) == 0x1e70) // A7 is not connected
{
- case 0x1ef0:
- chr2_0((data & 0x7f) >> 1, CHRROM);
- if (m_x1_005_alt_mirroring)
- {
- set_nt_page(0, CIRAM, (data & 0x80) ? 1 : 0, 1);
- set_nt_page(1, CIRAM, (data & 0x80) ? 1 : 0, 1);
- }
- break;
- case 0x1ef1:
- chr2_2((data & 0x7f) >> 1, CHRROM);
- if (m_x1_005_alt_mirroring)
- {
- set_nt_page(2, CIRAM, (data & 0x80) ? 1 : 0, 1);
- set_nt_page(3, CIRAM, (data & 0x80) ? 1 : 0, 1);
- }
- break;
- case 0x1ef2:
- chr1_4(data, CHRROM);
- break;
- case 0x1ef3:
- chr1_5(data, CHRROM);
- break;
- case 0x1ef4:
- chr1_6(data, CHRROM);
- break;
- case 0x1ef5:
- chr1_7(data, CHRROM);
- break;
- case 0x1ef6:
- case 0x1ef7:
- if (!m_x1_005_alt_mirroring)
- set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
- break;
- case 0x1ef8:
- case 0x1ef9:
- m_latch = data;
- break;
- case 0x1efa:
- case 0x1efb:
- prg8_89(data);
- break;
- case 0x1efc:
- case 0x1efd:
- prg8_ab(data);
- break;
- case 0x1efe:
- case 0x1eff:
- prg8_cd(data);
- break;
- default:
- logerror("mapper80_m_w uncaught addr: %04x, value: %02x\n", offset + 0x6000, data);
- break;
+ u8 reg = offset & 0x0f;
+
+ switch (reg)
+ {
+ case 0x0:
+ case 0x1:
+ reg <<= 1;
+ chr2_x(reg, BIT(data, 1, 6), CHRROM);
+ if (m_x1_005_alt_mirroring)
+ {
+ set_nt_page(reg + 0, CIRAM, BIT(data, 7), 1);
+ set_nt_page(reg + 1, CIRAM, BIT(data, 7), 1);
+ }
+ break;
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ chr1_x(reg + 2, data, CHRROM);
+ break;
+ case 0x6:
+ case 0x7:
+ if (!m_x1_005_alt_mirroring)
+ set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
+ break;
+ case 0x8:
+ case 0x9:
+ m_latch = data;
+ break;
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ case 0xd:
+ case 0xe:
+ case 0xf:
+ prg8_x((reg - 0x0a) >> 1, data);
+ break;
+ }
}
-
- if (offset >= 0x1f00 && m_latch == 0xa3)
+ else if (offset >= 0x1f00 && m_latch == 0xa3)
m_x1_005_ram[offset & 0x7f] = data;
+ else
+ LOGMASKED(LOG_UNHANDLED, "Taito X1-005 uncaught addr: %04x, value: %02x\n", offset + 0x6000, data);
}
-uint8_t nes_x1_005_device::read_m(offs_t offset)
+u8 nes_x1_005_device::read_m(offs_t offset)
{
- LOG_MMC(("x1_005 read_m, offset: %04x\n", offset));
+ LOG("x1_005 read_m, offset: %04x\n", offset);
if (offset >= 0x1f00 && m_latch == 0xa3)
return m_x1_005_ram[offset & 0x7f];
- return get_open_bus(); // open bus
+ return get_open_bus();
}
/*-------------------------------------------------
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
+
+ NES 2.0: mapper 552 (old mapper 82 are mis-ordered bad dumps)
- iNES: mapper 82
+ In MAME: Supported.
- In MESS: 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.
-------------------------------------------------*/
+TIMER_CALLBACK_MEMBER(nes_x1_017_device::irq_timer_tick)
+{
+ 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));
+ LOG("x1017 write_m, offset: %04x, data: %02x\n", offset, data);
switch (offset)
{
@@ -411,19 +388,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:
@@ -431,39 +402,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) - 0x0a, bitswap<6>(data, 0, 1, 2, 3, 4, 5));
+ break;
+ 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;
- default:
- logerror("x1017_m_w uncaught write, addr: %04x, value: %02x\n", offset + 0x6000, data);
+ 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));
+ LOG("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)];
-
- return get_open_bus(); // open bus
+ 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];
+
+ // 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
}