mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
added interrupt handling
This commit is contained in:
parent
50d39b43e1
commit
18279c1b03
@ -10,7 +10,6 @@
|
|||||||
I've also looked at asterick's JavaScript D553 emulator for verification, with permission.
|
I've also looked at asterick's JavaScript D553 emulator for verification, with permission.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- add external interrupt
|
|
||||||
- what happens with uCOM-43 opcodes on an uCOM-44/45 MCU?
|
- 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)
|
- 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_timer_f = 0;
|
||||||
m_int_f = 0;
|
m_int_f = 0;
|
||||||
m_inte_f = 0;
|
m_inte_f = 0;
|
||||||
|
m_int_line = CLEAR_LINE;
|
||||||
|
|
||||||
// register for savestates
|
// register for savestates
|
||||||
save_item(NAME(m_stack));
|
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_carry_s_f));
|
||||||
save_item(NAME(m_timer_f));
|
save_item(NAME(m_timer_f));
|
||||||
save_item(NAME(m_int_f));
|
save_item(NAME(m_int_f));
|
||||||
save_item(NAME(m_inte_f));
|
save_item(NAME(m_int_line));
|
||||||
|
|
||||||
// register state for debugger
|
// register state for debugger
|
||||||
state_add(UCOM4_PC, "PC", m_pc).formatstr("%04X");
|
state_add(UCOM4_PC, "PC", m_pc).formatstr("%04X");
|
||||||
@ -196,6 +196,11 @@ void ucom4_cpu_device::device_reset()
|
|||||||
|
|
||||||
m_timer->adjust(attotime::never);
|
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
|
// clear i/o
|
||||||
for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++)
|
for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++)
|
||||||
output_w(i, 0xf);
|
output_w(i, 0xf);
|
||||||
@ -207,6 +212,23 @@ void ucom4_cpu_device::device_reset()
|
|||||||
// execute
|
// 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()
|
inline void ucom4_cpu_device::increment_pc()
|
||||||
{
|
{
|
||||||
// upper bits (field register) don't auto-increment
|
// upper bits (field register) don't auto-increment
|
||||||
@ -233,6 +255,19 @@ void ucom4_cpu_device::execute_run()
|
|||||||
// remember previous opcode
|
// remember previous opcode
|
||||||
m_prev_op = m_op;
|
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);
|
debugger_instruction_hook(this, m_pc);
|
||||||
m_op = m_program->read_byte(m_pc);
|
m_op = m_program->read_byte(m_pc);
|
||||||
m_bitmask = 1 << (m_op & 0x03);
|
m_bitmask = 1 << (m_op & 0x03);
|
||||||
@ -245,6 +280,7 @@ void ucom4_cpu_device::execute_run()
|
|||||||
m_op = 0; // nop
|
m_op = 0; // nop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle opcode
|
||||||
switch (m_op & 0xf0)
|
switch (m_op & 0xf0)
|
||||||
{
|
{
|
||||||
case 0x80: op_ldz(); break;
|
case 0x80: op_ldz(); break;
|
||||||
|
@ -110,6 +110,7 @@ protected:
|
|||||||
virtual UINT32 execute_min_cycles() const { return 1; }
|
virtual UINT32 execute_min_cycles() const { return 1; }
|
||||||
virtual UINT32 execute_max_cycles() const { return 2; }
|
virtual UINT32 execute_max_cycles() const { return 2; }
|
||||||
virtual UINT32 execute_input_lines() const { return 1; }
|
virtual UINT32 execute_input_lines() const { return 1; }
|
||||||
|
virtual void execute_set_input(int line, int state);
|
||||||
virtual void execute_run();
|
virtual void execute_run();
|
||||||
|
|
||||||
// device_memory_interface overrides
|
// device_memory_interface overrides
|
||||||
@ -153,6 +154,7 @@ protected:
|
|||||||
UINT8 m_timer_f; // timer out flag
|
UINT8 m_timer_f; // timer out flag
|
||||||
UINT8 m_int_f; // interrupt flag
|
UINT8 m_int_f; // interrupt flag
|
||||||
UINT8 m_inte_f; // interrupt enable flag
|
UINT8 m_inte_f; // interrupt enable flag
|
||||||
|
int m_int_line; // interrupt pin state
|
||||||
|
|
||||||
// i/o handlers
|
// i/o handlers
|
||||||
devcb_read8 m_read_a;
|
devcb_read8 m_read_a;
|
||||||
|
Loading…
Reference in New Issue
Block a user