diff options
Diffstat (limited to 'src/devices/bus/nes/taito.cpp')
-rw-r--r-- | src/devices/bus/nes/taito.cpp | 322 |
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 } |