summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2015-05-11 23:01:51 +0200
committer hap <happppp@users.noreply.github.com>2015-05-11 23:01:51 +0200
commit88c04136c83e43d6e441704f7ad1e78dc898738a (patch)
tree1db875bb35d0fff727cfb3cfe6bfc6678e12a670
parent3a298f294a8f93b97f3581ab7cb0c69515156c9e (diff)
exit execute loop if it ran out of icount after an interrupt
-rw-r--r--src/emu/cpu/hmcs40/hmcs40.c7
-rw-r--r--src/emu/cpu/ucom4/ucom4.c45
-rw-r--r--src/emu/cpu/ucom4/ucom4.h2
-rw-r--r--src/emu/cpu/ucom4/ucom4op.inc14
4 files changed, 44 insertions, 24 deletions
diff --git a/src/emu/cpu/hmcs40/hmcs40.c b/src/emu/cpu/hmcs40/hmcs40.c
index b40e1299e06..005a7c03b83 100644
--- a/src/emu/cpu/hmcs40/hmcs40.c
+++ b/src/emu/cpu/hmcs40/hmcs40.c
@@ -553,15 +553,17 @@ void hmcs40_cpu_device::execute_run()
{
while (m_icount > 0)
{
- m_icount--;
-
// LPU is handled 1 cycle later
if ((m_prev_op & 0x3e0) == 0x340)
m_pc = ((m_page << 6) | (m_pc & 0x3f)) & m_pcmask;
// check/handle interrupt, but not in the middle of a long jump
if (m_ie && (m_iri || m_irt) && (m_op & 0x3e0) != 0x340)
+ {
do_interrupt();
+ if (m_icount <= 0)
+ break;
+ }
// remember previous state
m_prev_op = m_op;
@@ -569,6 +571,7 @@ void hmcs40_cpu_device::execute_run()
// fetch next opcode
debugger_instruction_hook(this, m_pc);
+ m_icount--;
m_op = m_program->read_word(m_pc << 1) & 0x3ff;
m_i = BITSWAP8(m_op,7,6,5,4,0,1,2,3) & 0xf; // reversed bit-order for 4-bit immediate param (except for XAMR, REDD, SEDD)
increment_pc();
diff --git a/src/emu/cpu/ucom4/ucom4.c b/src/emu/cpu/ucom4/ucom4.c
index f8fbf383cb2..11d1513ed03 100644
--- a/src/emu/cpu/ucom4/ucom4.c
+++ b/src/emu/cpu/ucom4/ucom4.c
@@ -144,6 +144,7 @@ void ucom4_cpu_device::device_start()
m_prev_op = 0;
m_skip = false;
m_pc = 0;
+ m_prev_pc = 0;
m_acc = 0;
m_dpl = 0;
m_dph = 0;
@@ -161,6 +162,7 @@ void ucom4_cpu_device::device_start()
save_item(NAME(m_prev_op));
save_item(NAME(m_skip));
save_item(NAME(m_pc));
+ save_item(NAME(m_prev_pc));
save_item(NAME(m_acc));
save_item(NAME(m_dpl));
save_item(NAME(m_dph));
@@ -209,7 +211,7 @@ void ucom4_cpu_device::device_reset()
//-------------------------------------------------
-// execute
+// interrupt
//-------------------------------------------------
void ucom4_cpu_device::execute_set_input(int line, int state)
@@ -229,6 +231,23 @@ void ucom4_cpu_device::execute_set_input(int line, int state)
}
}
+void ucom4_cpu_device::do_interrupt()
+{
+ m_icount--;
+ push_stack();
+ m_pc = 0xf << 2;
+ m_int_f = 0;
+ m_inte_f = (m_family == NEC_UCOM43) ? 0 : 1;
+
+ standard_irq_callback(0);
+}
+
+
+
+//-------------------------------------------------
+// execute
+//-------------------------------------------------
+
inline void ucom4_cpu_device::increment_pc()
{
// upper bits (field register) don't auto-increment
@@ -250,25 +269,21 @@ void ucom4_cpu_device::execute_run()
{
while (m_icount > 0)
{
- m_icount--;
-
- // remember previous opcode
- m_prev_op = m_op;
-
- // handle interrupt - it not accepted during LI($9x) or EI($31), or while skipping
- if (m_int_f && m_inte_f && (m_prev_op & 0xf0) != 0x90 && m_prev_op != 0x31 && !m_skip)
+ // handle interrupt, but not during LI($9x) or EI($31) or while skipping
+ if (m_int_f && m_inte_f && (m_op & 0xf0) != 0x90 && m_op != 0x31 && !m_skip)
{
- m_icount--;
- push_stack();
- m_pc = 0xf << 2;
- m_int_f = 0;
- m_inte_f = (m_family == NEC_UCOM43) ? 0 : 1;
-
- standard_irq_callback(0);
+ do_interrupt();
+ if (m_icount <= 0)
+ break;
}
+ // remember previous state
+ m_prev_op = m_op;
+ m_prev_pc = m_pc;
+
// fetch next opcode
debugger_instruction_hook(this, m_pc);
+ m_icount--;
m_op = m_program->read_byte(m_pc);
m_bitmask = 1 << (m_op & 0x03);
increment_pc();
diff --git a/src/emu/cpu/ucom4/ucom4.h b/src/emu/cpu/ucom4/ucom4.h
index 5e2bff9a62c..a0f3353c5e5 100644
--- a/src/emu/cpu/ucom4/ucom4.h
+++ b/src/emu/cpu/ucom4/ucom4.h
@@ -175,6 +175,7 @@ protected:
emu_timer *m_timer;
UINT16 m_pc; // program counter
+ UINT16 m_prev_pc;
UINT8 m_acc; // 4-bit accumulator
UINT8 m_dpl; // 4-bit data pointer low (RAM x)
UINT8 m_dph; // 4-bit(?) data pointer high (RAM y)
@@ -203,6 +204,7 @@ protected:
// misc internal helpers
void increment_pc();
void fetch_arg();
+ void do_interrupt();
UINT8 ram_r();
void ram_w(UINT8 data);
diff --git a/src/emu/cpu/ucom4/ucom4op.inc b/src/emu/cpu/ucom4/ucom4op.inc
index 4ef1db23923..d5819369278 100644
--- a/src/emu/cpu/ucom4/ucom4op.inc
+++ b/src/emu/cpu/ucom4/ucom4op.inc
@@ -41,7 +41,7 @@ UINT8 ucom4_cpu_device::input_r(int index)
case NEC_UCOM4_PORTD: inp = m_read_d(index, 0xff); break;
default:
- logerror("%s read from unknown port %c at $%03X\n", tag(), 'A' + index, m_pc);
+ logerror("%s read from unknown port %c at $%03X\n", tag(), 'A' + index, m_prev_pc);
break;
}
@@ -64,7 +64,7 @@ void ucom4_cpu_device::output_w(int index, UINT8 data)
case NEC_UCOM4_PORTI: m_write_i(index, data & 7, 0xff); break;
default:
- logerror("%s write to unknown port %c = $%X at $%03X\n", tag(), 'A' + index, data & 0xf, m_pc);
+ logerror("%s write to unknown port %c = $%X at $%03X\n", tag(), 'A' + index, data & 0xf, m_prev_pc);
break;
}
@@ -73,7 +73,7 @@ void ucom4_cpu_device::output_w(int index, UINT8 data)
void ucom4_cpu_device::op_illegal()
{
- logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_pc);
+ logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_prev_pc);
}
@@ -372,7 +372,7 @@ void ucom4_cpu_device::op_ci()
m_skip = (m_acc == (m_arg & 0x0f));
if ((m_arg & 0xf0) != 0xc0)
- logerror("%s CI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_pc);
+ logerror("%s CI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_prev_pc);
}
void ucom4_cpu_device::op_cm()
@@ -399,7 +399,7 @@ void ucom4_cpu_device::op_cli()
m_skip = (m_dpl == (m_arg & 0x0f));
if ((m_arg & 0xf0) != 0xe0)
- logerror("%s CLI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_pc);
+ logerror("%s CLI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_prev_pc);
}
void ucom4_cpu_device::op_tmb()
@@ -482,7 +482,7 @@ inline bool ucom4_cpu_device::check_op_43()
{
// these opcodes are officially only supported on uCOM-43
if (m_family != NEC_UCOM43)
- logerror("%s using uCOM-43 opcode $%02X at $%03X\n", tag(), m_op, m_pc);
+ logerror("%s using uCOM-43 opcode $%02X at $%03X\n", tag(), m_op, m_prev_pc);
return (m_family == NEC_UCOM43);
}
@@ -724,7 +724,7 @@ void ucom4_cpu_device::op_stm()
m_timer->adjust(base * ((m_arg & 0x3f) + 1));
if ((m_arg & 0xc0) != 0x80)
- logerror("%s STM opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xc0, m_pc);
+ logerror("%s STM opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xc0, m_prev_pc);
}
void ucom4_cpu_device::op_ttm()