diff options
Diffstat (limited to 'src/mess/machine/nes_kaiser.c')
-rw-r--r-- | src/mess/machine/nes_kaiser.c | 501 |
1 files changed, 501 insertions, 0 deletions
diff --git a/src/mess/machine/nes_kaiser.c b/src/mess/machine/nes_kaiser.c new file mode 100644 index 00000000000..75c870749c7 --- /dev/null +++ b/src/mess/machine/nes_kaiser.c @@ -0,0 +1,501 @@ +/*********************************************************************************************************** + + + NES/Famicom cartridge emulation for Kaiser PCBs + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + + + Here we emulate the following Kaiser bootleg PCBs + + * Kaiser KS202 + * Kaiser KS7012 + * Kaiser KS7013B + * Kaiser KS7017 + * Kaiser KS7022 + * Kaiser KS7032 + * Kaiser KS7058 + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "machine/nes_kaiser.h" + +#include "cpu/m6502/m6502.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 +//------------------------------------------------- + +const device_type NES_KS7058 = &device_creator<nes_ks7058_device>; +const device_type NES_KS7022 = &device_creator<nes_ks7022_device>; +const device_type NES_KS7032 = &device_creator<nes_ks7032_device>; +const device_type NES_KS202 = &device_creator<nes_ks202_device>; +const device_type NES_KS7017 = &device_creator<nes_ks7017_device>; +const device_type NES_KS7012 = &device_creator<nes_ks7012_device>; +const device_type NES_KS7013B = &device_creator<nes_ks7013b_device>; + + +nes_ks7058_device::nes_ks7058_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7058, "NES Cart Kaiser KS-7058 PCB", tag, owner, clock, "nes_ks7058", __FILE__) +{ +} + +nes_ks7022_device::nes_ks7022_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7022, "NES Cart Kaiser KS-7022 PCB", tag, owner, clock, "nes_ks7022", __FILE__) +{ +} + +nes_ks7032_device::nes_ks7032_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : nes_nrom_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + +nes_ks7032_device::nes_ks7032_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7032, "NES Cart Kaiser KS-7032 PCB", tag, owner, clock, "nes_ks7032", __FILE__) +{ +} + +nes_ks202_device::nes_ks202_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_ks7032_device(mconfig, NES_KS202, "NES Cart Kaiser KS-202 PCB", tag, owner, clock, "nes_ks202", __FILE__) +{ +} + +nes_ks7017_device::nes_ks7017_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7017, "NES Cart Kaiser KS-7017 PCB", tag, owner, clock, "nes_ks7017", __FILE__) +{ +} + +nes_ks7012_device::nes_ks7012_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7012, "NES Cart Kaiser KS-7012 PCB", tag, owner, clock, "nes_ks7012", __FILE__) +{ +} + +nes_ks7013b_device::nes_ks7013b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_KS7013B, "NES Cart Kaiser KS-7013B PCB", tag, owner, clock, "nes_ks7013b", __FILE__) +{ +} + + + + +void nes_ks7058_device::device_start() +{ + common_start(); +} + +void nes_ks7058_device::pcb_reset() +{ + m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + prg32(0); + chr8(0, m_chr_source); +} + +void nes_ks7022_device::device_start() +{ + common_start(); + save_item(NAME(m_latch)); +} + +void nes_ks7022_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_latch = 0; +} + +void nes_ks7032_device::device_start() +{ + common_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_count)); + save_item(NAME(m_reg)); +} + +void nes_ks7032_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_latch = 0; + m_irq_enable = 0; + m_irq_count = 0; + memset(m_reg, 0, sizeof(m_reg)); + prg_update(); +} + +void nes_ks7017_device::device_start() +{ + common_start(); + save_item(NAME(m_latch)); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_count)); + save_item(NAME(m_irq_status)); +} + +void nes_ks7017_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_latch = 0; + m_irq_enable = 0; + m_irq_count = 0; + m_irq_status = 0; +} + +void nes_ks7012_device::device_start() +{ + common_start(); +} + +void nes_ks7012_device::pcb_reset() +{ + m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + prg32(0xff); + chr8(0, m_chr_source); +} + +void nes_ks7013b_device::device_start() +{ + common_start(); +} + +void nes_ks7013b_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); +} + + + + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + + Kaiser Board KS7058 + + Games: Tui Do Woo Ma Jeung + + Writes to 0xf000-0xffff set 4k chr banks. Namely, if + offset&0x80 is 0 the lower 4k are set, if it is 1 the + upper 4k are set. + + iNES: mapper 171 + + In MESS: Supported. + + -------------------------------------------------*/ + +WRITE8_MEMBER(nes_ks7058_device::write_h) +{ + LOG_MMC(("ks7058 write_h, offset: %04x, data: %02x\n", offset, data)); + + switch (offset & 0x7080) + { + case 0x7000: + chr4_0(data, CHRROM); + break; + case 0x7080: + chr4_4(data, CHRROM); + break; + } +} + +/*------------------------------------------------- + + Kaiser Board KS7022 + + Games: 15 in 1 + + iNES: mapper 175 + + In MESS: Supported? + + -------------------------------------------------*/ + +WRITE8_MEMBER(nes_ks7022_device::write_h) +{ + LOG_MMC(("ks7022 write_h, offset: %04x, data: %02x\n", offset, data)); + + if (offset == 0) + set_nt_mirroring(BIT(data, 2) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); + + if (offset == 0x2000) + m_latch = data & 0x0f; +} + +READ8_MEMBER(nes_ks7022_device::read_h) +{ + LOG_MMC(("ks7022 read_h, offset: %04x\n", offset)); + + if (offset == 0x7ffc) + { + chr8(m_latch, CHRROM); + prg16_89ab(m_latch); + prg16_cdef(m_latch); + } + + return hi_access_rom(offset); +} + +/*------------------------------------------------- + + Kaiser Board KS7032 + + Games: A few FDS conversions like Bubble Bobble + or SMB2 + + iNES: + + TODO: available dumps do not seem to use WRAM... + yet m_reg[4] should switch WRAM bank... investigate! + + In MESS: Supported? + + -------------------------------------------------*/ + +void nes_ks7032_device::prg_update() +{ + prg8_89(m_reg[1]); + prg8_ab(m_reg[2]); + prg8_cd(m_reg[3]); +} + +void nes_ks7032_device::hblank_irq(int scanline, int vblank, int blanked) +{ + if (m_irq_enable) + { + if (m_irq_count >= (0xffff - 114)) + { + m_irq_enable = 0; + m_irq_count = 0; + machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); + } + else + m_irq_count += 114; + } +} + +WRITE8_MEMBER(nes_ks7032_device::ks7032_write) +{ + LOG_MMC(("ks7032_write, offset: %04x, data: %02x\n", offset, data)); + + switch (offset & 0x7000) + { + case 0x0000: + m_irq_count = (m_irq_count & 0xfff0) | (data & 0x0f); + break; + case 0x1000: + m_irq_count = (m_irq_count & 0xff0f) | ((data & 0x0f) << 4); + break; + case 0x2000: + m_irq_count = (m_irq_count & 0xf0ff) | ((data & 0x0f) << 8); + break; + case 0x3000: + m_irq_count = (m_irq_count & 0x0fff) | ((data & 0x0f) << 12); + break; + case 0x4000: + m_irq_enable = 1; + break; + case 0x6000: + m_latch = data & 0x07; + break; + case 0x7000: + m_reg[m_latch] = data; + prg_update(); + break; + } +} + +READ8_MEMBER(nes_ks7032_device::read_m) +{ + LOG_MMC(("ks7032 read_m, offset: %04x\n", offset)); + return m_prg[((m_reg[4] * 0x2000) + (offset & 0x1fff)) & (m_prg_size - 1)]; +} + +/*------------------------------------------------- + + Kaiser Board KS202 + + Games: Super Mario Bros. 3 (Pirate, Alt) + + iNES: + + In MESS: Supported? + + -------------------------------------------------*/ + + +WRITE8_MEMBER(nes_ks202_device::write_h) +{ + LOG_MMC(("ks202 write_h, offset: %04x, data: %02x\n", offset, data)); + + switch (offset & 0x7000) + { + case 0x7000: + m_reg[m_latch] = data; + prg_update(); + switch (offset & 0xc00) + { + case 0x800: + set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ); + break; + case 0xc00: + chr1_x(offset & 0x07, data, CHRROM); + break; + } + break; + default: + ks7032_write(space, offset, data, mem_mask); + break; + } +} + +READ8_MEMBER(nes_ks202_device::read_m) +{ + LOG_MMC(("ks202 read_m, offset: %04x\n", offset)); + return m_prgram[offset & 0x1fff]; +} + +/*------------------------------------------------- + + Kaiser Board KS7017 + + Games: Almana no Kiseki FDS conversion + + iNES: + + In MESS: Not working + + -------------------------------------------------*/ + +void nes_ks7017_device::hblank_irq(int scanline, int vblank, int blanked) +{ + if (m_irq_enable) + { + if (m_irq_count <= 114) + { + machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, HOLD_LINE); + m_irq_enable = 0; + m_irq_status |= 0x01; + } + else + m_irq_count -= 114; + } +} + +WRITE8_MEMBER(nes_ks7017_device::write_l) +{ + LOG_MMC(("ks7017 write_l, offset: %04x, data: %02x\n", offset, data)); + + offset += 0x100; + + if (offset >= 0xa00 && offset < 0xb00) + m_latch = ((offset >> 2) & 0x03) | ((offset >> 4) & 0x04); + + if (offset >= 0x1000 && offset < 0x1100) + prg16_89ab(m_latch); +} + +WRITE8_MEMBER(nes_ks7017_device::write_ex) +{ + LOG_MMC(("ks7017 write_ex, offset: %04x, data: %02x\n", offset, data)); + offset += 0x20; + + if (offset == 0x0020) /* 0x4020 */ + m_irq_count = (m_irq_count & 0xff00) | data; + + if (offset == 0x0021) /* 0x4021 */ + m_irq_count = (m_irq_count & 0x00ff) | (data << 8); + + if (offset == 0x0025) /* 0x4025 */ + set_nt_mirroring(BIT(data, 3) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); +} + +READ8_MEMBER(nes_ks7017_device::read_ex) +{ + LOG_MMC(("ks7017 read_ex, offset: %04x\n", offset)); + offset += 0x20; + + if (offset == 0x0030) /* 0x4030 */ + { + m_irq_status &= ~0x01; + return m_irq_status; + } + + return 0xff; +} + +/*------------------------------------------------- + + Kaiser Board KS7012 + + Games: Zanac FDS Conversion + + iNES: + + In MESS: Not working + + -------------------------------------------------*/ + +WRITE8_MEMBER(nes_ks7012_device::write_h) +{ + LOG_MMC(("ks7012 write_h, offset: %04x, data: %02x\n", offset, data)); + + if (offset == 0x60a0) + prg32(0); + if (offset == 0x6e36) + prg32(1); +} + + +/*------------------------------------------------- + + Kaiser Board KS7013B + + Games: Highway Star FDS Conversion + + iNES: + + In MESS: Supported. + + -------------------------------------------------*/ + +WRITE8_MEMBER(nes_ks7013b_device::write_m) +{ + LOG_MMC(("ks7013b write_l, offset: %04x, data: %02x\n", offset, data)); + prg16_89ab(data); +} + +WRITE8_MEMBER(nes_ks7013b_device::write_h) +{ + LOG_MMC(("ks7013b write_h, offset: %04x, data: %02x\n", offset, data)); + set_nt_mirroring((data & 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT); +} |