summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2016-02-07 14:09:48 +0100
committer hap <happppp@users.noreply.github.com>2016-02-07 14:09:48 +0100
commit462b96ab1d2c88adb73d1b39c0050095885625a4 (patch)
tree9daca5462527e846708bf82ae91a41b39c65f30e
parent4bcc966c7af18258e0f18e64d3ed4b9135940d3b (diff)
z80: put take_nmi in the execution loop: eg. z80 writes to another device NMI enable register
-rw-r--r--src/devices/cpu/z80/z80.cpp95
-rw-r--r--src/devices/cpu/z80/z80.h1
2 files changed, 43 insertions, 53 deletions
diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp
index a46edbec749..4f38a4e1866 100644
--- a/src/devices/cpu/z80/z80.cpp
+++ b/src/devices/cpu/z80/z80.cpp
@@ -3125,6 +3125,27 @@ OP(op,fe) { cp(arg());
OP(op,ff) { rst(0x38); } /* RST 7 */
+void z80_device::take_nmi()
+{
+ /* there isn't a valid previous program counter */
+ PRVPC = -1;
+
+ /* Check if processor was halted */
+ leave_halt();
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
+
+ m_iff1 = 0;
+ push(m_pc);
+ PCD = 0x0066;
+ WZ=PCD;
+ m_icount -= 11;
+ m_nmi_pending = FALSE;
+}
+
void z80_device::take_interrupt()
{
int irq_vector;
@@ -3207,6 +3228,11 @@ void z80_device::take_interrupt()
m_icount -= m_cc_ex[0xff];
}
WZ=PCD;
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
}
void nsc800_device::take_interrupt_nsc800()
@@ -3240,6 +3266,11 @@ void nsc800_device::take_interrupt_nsc800()
m_icount -= m_cc_op[0xff] + cc_ex[0xff];
WZ=PCD;
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
}
/****************************************************************************
@@ -3486,40 +3517,14 @@ void z80_device::execute_run()
return;
}
- /* check for NMIs on the way in; they can only be set externally */
- /* via timers, and can't be dynamically enabled, so it is safe */
- /* to just check here */
- if (m_nmi_pending)
- {
- LOG(("Z80 '%s' take NMI\n", tag()));
- PRVPC = -1; /* there isn't a valid previous program counter */
- leave_halt(); /* Check if processor was halted */
-
-#if HAS_LDAIR_QUIRK
- /* reset parity flag after LD A,I or LD A,R */
- if (m_after_ldair) F &= ~PF;
-#endif
- m_after_ldair = FALSE;
-
- m_iff1 = 0;
- push(m_pc);
- PCD = 0x0066;
- WZ=PCD;
- m_icount -= 11;
- m_nmi_pending = FALSE;
- }
-
do
{
- /* check for IRQs before each instruction */
- if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
- {
-#if HAS_LDAIR_QUIRK
- /* reset parity flag after LD A,I or LD A,R */
- if (m_after_ldair) F &= ~PF;
-#endif
+ // check for interrupts before each instruction
+ if (m_nmi_pending)
+ take_nmi();
+ else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
take_interrupt();
- }
+
m_after_ei = FALSE;
m_after_ldair = FALSE;
@@ -3543,34 +3548,18 @@ void nsc800_device::execute_run()
return;
}
- /* check for NMIs on the way in; they can only be set externally */
- /* via timers, and can't be dynamically enabled, so it is safe */
- /* to just check here */
- if (m_nmi_pending)
- {
- LOG(("Z80 '%s' take NMI\n", tag()));
- PRVPC = -1; /* there isn't a valid previous program counter */
- leave_halt(); /* Check if processor was halted */
-
- m_iff1 = 0;
- push(m_pc);
- PCD = 0x0066;
- WZ=PCD;
- m_icount -= 11;
- m_nmi_pending = FALSE;
- }
-
do
{
- /* check for NSC800 IRQs line RSTA, RSTB, RSTC */
- if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei)
+ // check for interrupts before each instruction
+ if (m_nmi_pending)
+ take_nmi();
+ else if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei)
take_interrupt_nsc800();
-
- /* check for IRQs before each instruction */
- if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
+ else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
take_interrupt();
m_after_ei = FALSE;
+ m_after_ldair = FALSE;
PRVPC = PCD;
debugger_instruction_hook(this, PCD);
diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h
index faed3eb832c..70c8b8f68ac 100644
--- a/src/devices/cpu/z80/z80.h
+++ b/src/devices/cpu/z80/z80.h
@@ -239,6 +239,7 @@ protected:
void ei();
void take_interrupt();
+ void take_nmi();
// address spaces
const address_space_config m_program_config;