bus/nes: Simplified NES-EVENT board. (#9122)

- IRQ timer now counts up and no longer latches DIP setting when initialized, i.e. DIP switches are always live.
- Removed deprecated hold_irq_line().
This commit is contained in:
0kmg 2022-01-11 14:54:40 -09:00 committed by GitHub
parent 015338d2f8
commit 6e31337b23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 87 deletions

View File

@ -27196,6 +27196,7 @@ license:CC0
<description>Nintendo World Championships 1990 (USA)</description>
<year>1990</year>
<publisher>Nintendo</publisher>
<info name="usage" value="To play, press start on controller 2."/>
<part name="cart" interface="nes_cart">
<feature name="slot" value="nes_event" />
<feature name="pcb" value="NES-EVENT" />

View File

@ -33,7 +33,7 @@
DEFINE_DEVICE_TYPE(NES_EVENT, nes_event_device, "nes_event", "NES Cart Event 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)
@ -47,15 +47,11 @@ nes_event_device::nes_event_device(const machine_config &mconfig, const char *ta
void nes_event_device::device_start()
{
common_start();
nes_sxrom_device::device_start();
event_timer = timer_alloc(TIMER_EVENT);
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,16 +61,11 @@ 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;
@ -92,7 +83,7 @@ void nes_event_device::pcb_reset()
Games: Nintento World Championships
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,87 +100,41 @@ 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)
{
switch (reg)
{
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();
break;
case 3:
set_prg();
break;
}
}
//-------------------------------------------------
// Dipswitch
@ -230,12 +175,11 @@ ioport_constructor nes_event_device::device_input_ports() const
void nes_event_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id == TIMER_EVENT)
if (id == TIMER_EVENT && 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();
}
}

View File

@ -14,20 +14,16 @@ class nes_event_device : public nes_sxrom_device
{
public:
// construction/destruction
nes_event_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ioport_constructor device_input_ports() const override;
nes_event_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void pcb_reset() override;
protected:
static constexpr device_timer_id TIMER_EVENT = 0;
// device-level overrides
virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual ioport_constructor device_input_ports() const override;
virtual void update_regs(int reg) override;
virtual void set_prg() override;
virtual void set_chr() override;
@ -35,10 +31,10 @@ protected:
int m_nwc_init;
static constexpr device_timer_id TIMER_EVENT = 0;
emu_timer *event_timer;
attotime timer_freq;
uint32_t m_timer_count;
u32 m_timer_count;
int m_timer_on, m_timer_enabled;
};

View File

@ -184,7 +184,7 @@ void nes_sxrom_device::set_chr(int chr_base, int chr_mask)
chr8((chr_base | (m_reg[1] & chr_mask)) >> 1, m_chr_source);
}
// this allows for easier implementation of the NES-EVENT board used for Nintento World Championships
// this allows for easier implementation of MMC1 subclasses
void nes_sxrom_device::update_regs(int reg)
{
switch (reg)