summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/m6502/st2xxx.cpp34
-rw-r--r--src/devices/cpu/m6502/st2xxx.h2
2 files changed, 26 insertions, 10 deletions
diff --git a/src/devices/cpu/m6502/st2xxx.cpp b/src/devices/cpu/m6502/st2xxx.cpp
index bc73afc7750..d0428332878 100644
--- a/src/devices/cpu/m6502/st2xxx.cpp
+++ b/src/devices/cpu/m6502/st2xxx.cpp
@@ -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)
+ {
+ 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)
{
- // 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;
+ 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);
diff --git a/src/devices/cpu/m6502/st2xxx.h b/src/devices/cpu/m6502/st2xxx.h
index 90f7c4d53c9..811c2008d49 100644
--- a/src/devices/cpu/m6502/st2xxx.h
+++ b/src/devices/cpu/m6502/st2xxx.h
@@ -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;