summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes/event.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nes/event.cpp')
-rw-r--r--src/devices/bus/nes/event.cpp244
1 files changed, 160 insertions, 84 deletions
diff --git a/src/devices/bus/nes/event.cpp b/src/devices/bus/nes/event.cpp
index a2205e3d0d4..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,11 +113,11 @@ 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
@@ -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)
+{
+ 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)
{
- switch (reg)
+ 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++;
+}