summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/ucom4/ucom4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/ucom4/ucom4.c')
-rw-r--r--src/emu/cpu/ucom4/ucom4.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/emu/cpu/ucom4/ucom4.c b/src/emu/cpu/ucom4/ucom4.c
index abc5d017b34..e7f25a26661 100644
--- a/src/emu/cpu/ucom4/ucom4.c
+++ b/src/emu/cpu/ucom4/ucom4.c
@@ -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;