added timer

This commit is contained in:
hap 2015-02-12 21:20:05 +01:00
parent e488210011
commit ac999d097b
3 changed files with 24 additions and 6 deletions

View File

@ -10,6 +10,7 @@
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)
@ -122,6 +123,8 @@ void ucom4_cpu_device::device_start()
m_datamask = (1 << m_datawidth) - 1; m_datamask = (1 << m_datawidth) - 1;
m_dph_mask = m_datamask >> 4; m_dph_mask = m_datamask >> 4;
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ucom4_cpu_device::simple_timer_cb), this));
m_read_a.resolve_safe(0xf); m_read_a.resolve_safe(0xf);
m_read_b.resolve_safe(0xf); m_read_b.resolve_safe(0xf);
m_read_c.resolve_safe(0xf); m_read_c.resolve_safe(0xf);
@ -187,11 +190,12 @@ void ucom4_cpu_device::device_start()
void ucom4_cpu_device::device_reset() void ucom4_cpu_device::device_reset()
{ {
m_inte_f = 1;
m_pc = 0; m_pc = 0;
m_op = 0; m_op = 0;
m_skip = false; m_skip = false;
m_timer->adjust(attotime::never);
// 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);

View File

@ -141,6 +141,7 @@ protected:
UINT8 m_bitmask; // opcode bit argument UINT8 m_bitmask; // opcode bit argument
bool m_skip; // skip next opcode bool m_skip; // skip next opcode
int m_icount; int m_icount;
emu_timer *m_timer;
UINT16 m_pc; // program counter UINT16 m_pc; // program counter
UINT8 m_acc; // 4-bit accumulator UINT8 m_acc; // 4-bit accumulator
@ -179,6 +180,7 @@ protected:
void output_w(int index, UINT8 data); void output_w(int index, UINT8 data);
bool check_op_43(); bool check_op_43();
TIMER_CALLBACK_MEMBER( simple_timer_cb );
UINT8 ucom43_reg_r(int index); UINT8 ucom43_reg_r(int index);
void ucom43_reg_w(int index, UINT8 data); void ucom43_reg_w(int index, UINT8 data);

View File

@ -429,7 +429,8 @@ void ucom4_cpu_device::op_tpb()
void ucom4_cpu_device::op_tit() void ucom4_cpu_device::op_tit()
{ {
// TIT: skip next on Interrupt F/F, reset Interrupt F/F // TIT: skip next on Interrupt F/F, reset Interrupt F/F
op_illegal(); m_skip = (m_int_f != 0);
m_int_f = 0;
} }
@ -489,6 +490,11 @@ inline bool ucom4_cpu_device::check_op_43()
return (m_family == NEC_UCOM43); return (m_family == NEC_UCOM43);
} }
TIMER_CALLBACK_MEMBER( ucom4_cpu_device::simple_timer_cb )
{
m_timer_f = 1;
}
// extra registers reside in RAM // extra registers reside in RAM
enum enum
{ {
@ -512,6 +518,7 @@ inline void ucom4_cpu_device::ucom43_reg_w(int index, UINT8 data)
} }
// Transfer // Transfer
void ucom4_cpu_device::op_taw() void ucom4_cpu_device::op_taw()
@ -712,7 +719,12 @@ void ucom4_cpu_device::op_stm()
if (!check_op_43()) return; if (!check_op_43()) return;
// STM X: Reset Timer F/F, Start Timer with X // STM X: Reset Timer F/F, Start Timer with X
op_illegal(); m_timer_f = 0;
// on the default clockrate of 400kHz, the minimum time interval is
// 630usec and the maximum interval is 40320usec(630*64)
attotime base = attotime::from_hz(unscaled_clock() / 4 / 63);
m_timer->adjust(base * ((m_arg & 0x3f) + 1));
if ((m_arg & 0xc0) != 0x80) 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_pc);
@ -723,7 +735,7 @@ void ucom4_cpu_device::op_ttm()
if (!check_op_43()) return; if (!check_op_43()) return;
// TTM: skip next on Timer F/F // TTM: skip next on Timer F/F
op_illegal(); m_skip = (m_timer_f != 0);
} }
@ -734,7 +746,7 @@ void ucom4_cpu_device::op_ei()
if (!check_op_43()) return; if (!check_op_43()) return;
// EI: Set Interrupt Enable F/F // EI: Set Interrupt Enable F/F
op_illegal(); m_inte_f = 1;
} }
void ucom4_cpu_device::op_di() void ucom4_cpu_device::op_di()
@ -742,5 +754,5 @@ void ucom4_cpu_device::op_di()
if (!check_op_43()) return; if (!check_op_43()) return;
// DI: Reset Interrupt Enable F/F // DI: Reset Interrupt Enable F/F
op_illegal(); m_inte_f = 0;
} }