mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
st2xxx: Fix regression by preventing IRQ level from changing between vector pulls
This commit is contained in:
parent
2b1dec62d8
commit
fa321cc7ce
@ -65,6 +65,7 @@ st2xxx_device::st2xxx_device(const machine_config &mconfig, device_type type, co
|
||||
, m_misc(0)
|
||||
, m_ireq(0)
|
||||
, m_iena(0)
|
||||
, m_irq_level(0xff)
|
||||
, m_lssa(0)
|
||||
, m_lvpw(0)
|
||||
, m_lxmax(0)
|
||||
@ -187,6 +188,7 @@ void st2xxx_device::save_common_registers()
|
||||
save_item(NAME(m_misc));
|
||||
save_item(NAME(m_ireq));
|
||||
save_item(NAME(m_iena));
|
||||
save_item(NAME(m_irq_level));
|
||||
if (st2xxx_lctr_mask() != 0)
|
||||
{
|
||||
save_item(NAME(m_lssa));
|
||||
@ -282,20 +284,34 @@ void st2xxx_device::device_reset()
|
||||
m_bctr = 0;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::active_irq_level() const
|
||||
{
|
||||
// IREQH interrupts have priority over IREQL interrupts
|
||||
u16 ireq_active = swapendian_int16(m_ireq & m_iena);
|
||||
if (ireq_active != 0)
|
||||
return 31 - (8 ^ count_leading_zeros_32(ireq_active & -ireq_active));
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::read_vector(u16 adr)
|
||||
{
|
||||
if (adr >= 0xfffe)
|
||||
{
|
||||
u16 ireq_active = m_ireq & m_iena;
|
||||
if (ireq_active != 0 && irq_taken)
|
||||
if (adr == 0xfffe)
|
||||
{
|
||||
// IREQH interrupts have priority over IREQL interrupts
|
||||
ireq_active = swapendian_int16(ireq_active);
|
||||
int level = 31 - int(8 ^ count_leading_zeros_32(ireq_active & -ireq_active));
|
||||
adr -= (level + 3) << 1;
|
||||
set_irq_service(true);
|
||||
|
||||
// Make sure this doesn't change in between vector pull cycles
|
||||
m_irq_level = irq_taken ? active_irq_level() : 0xff;
|
||||
}
|
||||
|
||||
if (m_irq_level != 0xff)
|
||||
{
|
||||
adr -= (m_irq_level + 3) << 1;
|
||||
|
||||
LOGMASKED(LOG_IRQ, "Acknowledging %s interrupt (PC = $%04X, IREQ = $%04X, IENA = $%04X, vector pull from $%04X)\n",
|
||||
st2xxx_irq_name(level),
|
||||
st2xxx_irq_name(m_irq_level),
|
||||
PPC,
|
||||
m_ireq,
|
||||
m_iena,
|
||||
@ -303,11 +319,9 @@ u8 st2xxx_device::read_vector(u16 adr)
|
||||
|
||||
if (BIT(adr, 0))
|
||||
{
|
||||
m_ireq &= ~(1 << level);
|
||||
m_ireq &= ~(1 << m_irq_level);
|
||||
update_irq_state();
|
||||
}
|
||||
else
|
||||
set_irq_service(true);
|
||||
}
|
||||
}
|
||||
return downcast<mi_st2xxx &>(*mintf).read_vector(adr);
|
||||
|
@ -135,6 +135,7 @@ protected:
|
||||
|
||||
void set_irq_service(bool state) { downcast<mi_st2xxx &>(*mintf).irq_service = state; }
|
||||
void update_irq_state() { irq_state = (m_ireq & m_iena) != 0; }
|
||||
u8 active_irq_level() const;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(bt_interrupt);
|
||||
TIMER_CALLBACK_MEMBER(lcd_interrupt);
|
||||
@ -268,6 +269,7 @@ protected:
|
||||
|
||||
u16 m_ireq;
|
||||
u16 m_iena;
|
||||
u8 m_irq_level;
|
||||
|
||||
u16 m_lssa;
|
||||
u8 m_lvpw;
|
||||
|
Loading…
Reference in New Issue
Block a user