exit execute loop if it ran out of icount after an interrupt

This commit is contained in:
hap 2015-05-11 23:01:51 +02:00
parent 3a298f294a
commit 88c04136c8
4 changed files with 44 additions and 24 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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()