mirror of
https://github.com/holub/mame
synced 2025-07-07 02:50:50 +03:00
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:
parent
015338d2f8
commit
6e31337b23
@ -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" />
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user