diff options
Diffstat (limited to 'src/devices/bus/nes/event.cpp')
-rw-r--r-- | src/devices/bus/nes/event.cpp | 246 |
1 files changed, 161 insertions, 85 deletions
diff --git a/src/devices/bus/nes/event.cpp b/src/devices/bus/nes/event.cpp index 41ebc976308..46be863f5ac 100644 --- a/src/devices/bus/nes/event.cpp +++ b/src/devices/bus/nes/event.cpp @@ -1,14 +1,15 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli +// copyright-holders:Fabio Priuli,kmg /*********************************************************************************************************** - NES/Famicom cartridge emulation for Nintendo NES-EVENT PCB + NES/Famicom cartridge emulation for Nintendo NES-EVENT PCBs Here we emulate the following PCBs * Nintendo NES-EVENT [mapper 105] + * Nintendo NES-EVENT2 [mapper 555] ***********************************************************************************************************/ @@ -16,24 +17,25 @@ #include "emu.h" #include "event.h" +#define LOG_HIFREQ (1U << 1) #ifdef NES_PCB_DEBUG -#define VERBOSE 1 +#define VERBOSE (LOG_GENERAL) #else -#define VERBOSE 0 +#define VERBOSE (0) #endif - -#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0) +#include "logmacro.h" //------------------------------------------------- // constructor //------------------------------------------------- -DEFINE_DEVICE_TYPE(NES_EVENT, nes_event_device, "nes_event", "NES Cart Event PCB") +DEFINE_DEVICE_TYPE(NES_EVENT, nes_event_device, "nes_event", "NES Cart EVENT PCB") +DEFINE_DEVICE_TYPE(NES_EVENT2, nes_event2_device, "nes_event2", "NES Cart EVENT2 PCB") -nes_event_device::nes_event_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_event_device::nes_event_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_sxrom_device(mconfig, NES_EVENT, tag, owner, clock) , m_dsw(*this, "DIPSW") , m_nwc_init(0) @@ -44,18 +46,24 @@ nes_event_device::nes_event_device(const machine_config &mconfig, const char *ta { } +nes_event2_device::nes_event2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_tqrom_device(mconfig, NES_EVENT2, tag, owner, clock) + , m_dsw(*this, "DIPSW") + , m_tqrom_mode(false) + , event_timer(nullptr) + , m_timer_count(0) + , m_timer_enabled(0) +{ +} + void nes_event_device::device_start() { - common_start(); - event_timer = timer_alloc(TIMER_EVENT); + nes_sxrom_device::device_start(); + + event_timer = timer_alloc(FUNC(nes_event_device::event_tick), this); event_timer->adjust(attotime::never); - timer_freq = clocks_to_attotime(1); - save_item(NAME(m_latch)); - save_item(NAME(m_count)); - save_item(NAME(m_reg)); - save_item(NAME(m_reg_write_enable)); save_item(NAME(m_nwc_init)); save_item(NAME(m_timer_count)); @@ -65,21 +73,38 @@ void nes_event_device::device_start() void nes_event_device::pcb_reset() { - m_latch = 0; - m_count = 0; - m_reg[0] = 0x0f; - m_reg[1] = m_reg[2] = m_reg[3] = 0; - m_reg_write_enable = 1; + nes_sxrom_device::pcb_reset(); + prg32(0); + m_nwc_init = 2; - set_nt_mirroring(PPU_MIRROR_HORZ); - chr8(0, CHRRAM); - prg32(0); m_timer_count = 0; m_timer_enabled = 0; m_timer_on = 0; } +void nes_event2_device::device_start() +{ + mmc3_start(); + + event_timer = timer_alloc(FUNC(nes_event2_device::event_tick), this); + event_timer->adjust(attotime::zero, 0, clocks_to_attotime(1)); + + save_item(NAME(m_tqrom_mode)); + + save_item(NAME(m_timer_count)); + save_item(NAME(m_timer_enabled)); +} + +void nes_event2_device::pcb_reset() +{ + m_tqrom_mode = false; + mmc3_common_initialize(0x07, 0x7f, 0); + + m_timer_count = 0; + m_timer_enabled = 0; +} + /*------------------------------------------------- @@ -88,16 +113,16 @@ void nes_event_device::pcb_reset() /*------------------------------------------------- - Event PCB + EVENT PCB - Games: Nintento World Championships + Games: Nintento World Championships 1990 - MMC-1 variant with repurposed register at $a000 and a + MMC1 variant with repurposed register at $a000 and a lot of discrete components iNES: mapper 105 - In MESS: Supported. + In MAME: Supported. -------------------------------------------------*/ @@ -109,88 +134,129 @@ void nes_event_device::set_chr() void nes_event_device::set_prg() { // printf("enter with %d and reg1 0x%x - reg3 0x%x\n", m_nwc_init, m_reg[1], m_reg[3]); - // reg[1] is different from base MMC-1! + // reg[1] is different from base MMC1! // bit 0 is ignored, bit1/bit3 are used for PRG switch, bit4 is used for the timer - uint8_t temp = (m_reg[1] >> 1) & 7; - // initially PRG is fixed, until bit4 of reg1 is set to 1 and then to 0 switch (m_nwc_init) { case 2: - if (m_reg[1] & 0x10) m_nwc_init--; + if (BIT(m_reg[1], 4)) m_nwc_init--; return; case 1: - if (~m_reg[1] & 0x10) m_nwc_init--; + if (!BIT(m_reg[1], 4)) m_nwc_init--; return; } - if (temp < 4) - prg32(temp); + // PRG mode 1 works similarly to base MMC1, but only acts on the higher 128KB (2nd PRG ROM) + if (BIT(m_reg[1], 3)) + nes_sxrom_device::set_prg(0x08, 0x07); else - { - // else PRG works similarly to base MMC-1, but only acts on the higher 128KB (2nd PRG ROM) - switch (m_reg[0] & 0x0c) - { - case 0x00: - case 0x04: - prg32(0x04 | ((m_reg[3] >> 1) & 0x03)); - break; - case 0x08: - prg16_89ab(0x08 | 0x00); - prg16_cdef(0x08 | (m_reg[3] & 0x07)); - break; - case 0x0c: - prg16_89ab(0x08 | (m_reg[3] & 0x07)); - prg16_cdef(0x08 | 0x07); - break; - } - } + prg32(BIT(m_reg[1], 1, 2)); // after the init procedure above, bit4 of m_reg[1] is used to init IRQ, by setting and then clearing the bit // however, there are (bankswitch related?) writes with bit4 cleared before the one 'enabling' the timer, so // we need the additional m_timer_enabled variable, to avoid starting the timer before its time... - if (m_reg[1] & 0x10) + if (BIT(m_reg[1], 4)) { + m_timer_count = 0; m_timer_enabled = 1; set_irq_line(CLEAR_LINE); } - else + else if (!m_timer_on && m_timer_enabled) { - if (!m_timer_on && m_timer_enabled) - { - m_timer_count = 0x20000000 | ((m_dsw->read() & 0x0f) << 25); - event_timer->adjust(attotime::zero, 0, timer_freq); - m_timer_on = 1; - } + event_timer->adjust(attotime::zero, 0, clocks_to_attotime(1)); + m_timer_on = 1; } } -void nes_event_device::update_regs(int reg) +/*------------------------------------------------- + + EVENT2 PCB + + Games: Nintento Campus Challenge 1991 + + Similar to the previous EVENT PCB, but based around + the MMC3. Onboard 8K VRAM and 8K WRAM support Pinbot + and SMB3, respectively, and an additional 2K WRAM at + $5000 is used by the control routine. The board also + featured an RJ11, used to transmit player names and + scores to a display at the staged events. + + The present emulation is based on what is known via + the reproduction board by RetroZone. That board is + missing the RJ11, two DIP switches, and...? + + NES 2.0: mapper 555 + + In MAME: Supported. + + -------------------------------------------------*/ + +u8 nes_event2_device::read_l(offs_t offset) +{ + LOGMASKED(LOG_HIFREQ, "event2 read_l, offset: %04x\n", offset); + offset += 0x100; + if (offset >= 0x1800) + return (m_timer_count >= (0x10 | m_dsw->read()) << 25) ? 0x80 : 0; + else if (offset < 0x1000 || m_prgram.empty()) + return get_open_bus(); + else + return m_prgram[(0x2000 + (offset & 0x7ff)) % m_prgram.size()]; +} + +u8 nes_event2_device::read_m(offs_t offset) { - switch (reg) + LOGMASKED(LOG_HIFREQ, "event2 read_m, offset: %04x\n", offset); + if (m_prgram.empty()) + return get_open_bus(); + else + return m_prgram[offset % m_prgram.size()]; +} + +void nes_event2_device::write_l(offs_t offset, u8 data) +{ + LOG("event2 write_l, offset: %04x, data: %02x\n", offset, data); + + offset += 0x100; + switch (offset & 0x1c00) { - case 0: - switch (m_reg[0] & 0x03) - { - case 0: set_nt_mirroring(PPU_MIRROR_LOW); break; - case 1: set_nt_mirroring(PPU_MIRROR_HIGH); break; - case 2: set_nt_mirroring(PPU_MIRROR_VERT); break; - case 3: set_nt_mirroring(PPU_MIRROR_HORZ); break; - } - set_prg(); - break; - case 1: - set_prg(); - break; - case 2: - set_chr(); + case 0x1000: + case 0x1400: + m_prgram[(0x2000 + (offset & 0x7ff)) % m_prgram.size()] = data; break; - case 3: - set_prg(); + case 0x1800: + m_tqrom_mode = (data & 0x06) == 0x02; + + m_prg_base = (data & 0x04) << 3; + m_prg_mask = (data & 0x03) << 3 | 0x07; + set_prg(m_prg_base, m_prg_mask); + + m_chr_base = m_prg_base << 2; + set_chr(m_chr_source, m_chr_base, m_chr_mask); + + m_timer_enabled = BIT(data, 3); + if (!m_timer_enabled) + m_timer_count = 0; break; } } +void nes_event2_device::write_m(offs_t offset, u8 data) +{ + LOGMASKED(LOG_HIFREQ, "event2 write_m, offset: %04x, data: %02x\n", offset, data); + if (!m_prgram.empty()) + m_prgram[offset % m_prgram.size()] = data; +} + +void nes_event2_device::chr_cb(int start, int bank, int source) +{ + if (m_tqrom_mode) + nes_tqrom_device::chr_cb(start, bank, source); + else + nes_txrom_device::chr_cb(start, bank, source); +} + + //------------------------------------------------- // Dipswitch //------------------------------------------------- @@ -223,20 +289,30 @@ ioport_constructor nes_event_device::device_input_ports() const return INPUT_PORTS_NAME( nwc_dsw ); } +ioport_constructor nes_event2_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nwc_dsw ); +} + //------------------------------------------------- -// device_timer - handler timer events +// event_tick - tick the event timer //------------------------------------------------- -void nes_event_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(nes_event_device::event_tick) { - if (id == TIMER_EVENT) + if (m_timer_on) { - m_timer_count--; - if (!m_timer_count) + if (++m_timer_count >= (0x10 | m_dsw->read()) << 25) { - hold_irq_line(); + set_irq_line(ASSERT_LINE); event_timer->reset(); } } } + +TIMER_CALLBACK_MEMBER(nes_event2_device::event_tick) +{ + if (m_timer_enabled) + m_timer_count++; +} |