added interrupt handling

This commit is contained in:
hap 2015-02-16 01:32:18 +01:00
parent 50d39b43e1
commit 18279c1b03
2 changed files with 42 additions and 4 deletions

View File

@ -10,7 +10,6 @@
I've also looked at asterick's JavaScript D553 emulator for verification, with permission.
TODO:
- add external interrupt
- what happens with uCOM-43 opcodes on an uCOM-44/45 MCU?
- what's the data after the ROM data for? (eg. 2000-2047, official ROM size is 2000)
@ -153,6 +152,7 @@ void ucom4_cpu_device::device_start()
m_timer_f = 0;
m_int_f = 0;
m_inte_f = 0;
m_int_line = CLEAR_LINE;
// register for savestates
save_item(NAME(m_stack));
@ -168,7 +168,7 @@ void ucom4_cpu_device::device_start()
save_item(NAME(m_carry_s_f));
save_item(NAME(m_timer_f));
save_item(NAME(m_int_f));
save_item(NAME(m_inte_f));
save_item(NAME(m_int_line));
// register state for debugger
state_add(UCOM4_PC, "PC", m_pc).formatstr("%04X");
@ -195,7 +195,12 @@ void ucom4_cpu_device::device_reset()
m_skip = false;
m_timer->adjust(attotime::never);
// clear interrupt
m_int_line = CLEAR_LINE;
m_int_f = 0;
m_inte_f = (m_family == NEC_UCOM43) ? 0 : 1;
// clear i/o
for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++)
output_w(i, 0xf);
@ -207,6 +212,23 @@ void ucom4_cpu_device::device_reset()
// execute
//-------------------------------------------------
void ucom4_cpu_device::execute_set_input(int line, int state)
{
switch (line)
{
case 0:
// edge triggered
if (m_int_line == CLEAR_LINE && state)
m_int_f = 1;
m_int_line = state;
break;
default:
break;
}
}
inline void ucom4_cpu_device::increment_pc()
{
// upper bits (field register) don't auto-increment
@ -233,6 +255,19 @@ void ucom4_cpu_device::execute_run()
// 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)
{
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);
}
// fetch next opcode
debugger_instruction_hook(this, m_pc);
m_op = m_program->read_byte(m_pc);
m_bitmask = 1 << (m_op & 0x03);
@ -245,6 +280,7 @@ void ucom4_cpu_device::execute_run()
m_op = 0; // nop
}
// handle opcode
switch (m_op & 0xf0)
{
case 0x80: op_ldz(); break;

View File

@ -110,8 +110,9 @@ protected:
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 2; }
virtual UINT32 execute_input_lines() const { return 1; }
virtual void execute_set_input(int line, int state);
virtual void execute_run();
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return(spacenum == AS_PROGRAM) ? &m_program_config :((spacenum == AS_DATA) ? &m_data_config : NULL); }
@ -153,6 +154,7 @@ protected:
UINT8 m_timer_f; // timer out flag
UINT8 m_int_f; // interrupt flag
UINT8 m_inte_f; // interrupt enable flag
int m_int_line; // interrupt pin state
// i/o handlers
devcb_read8 m_read_a;