From 8717aeab38f48fe2727b9f5ef8c31322b4f99eff Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 8 Feb 2015 01:16:23 +0100 Subject: added ucom4 i/o opcodes --- src/emu/cpu/ucom4/ucom4.c | 17 ++++++---- src/emu/cpu/ucom4/ucom4.h | 48 ++++++++++++++++++--------- src/emu/cpu/ucom4/ucom4op.inc | 77 +++++++++++++++++++++++++++++++++---------- 3 files changed, 104 insertions(+), 38 deletions(-) diff --git a/src/emu/cpu/ucom4/ucom4.c b/src/emu/cpu/ucom4/ucom4.c index 4868dc7d9c2..e56e175e85b 100644 --- a/src/emu/cpu/ucom4/ucom4.c +++ b/src/emu/cpu/ucom4/ucom4.c @@ -116,10 +116,10 @@ void ucom4_cpu_device::device_start() m_datamask = (1 << m_datawidth) - 1; m_dph_mask = m_datamask >> 4; - m_read_a.resolve_safe(0); - m_read_b.resolve_safe(0); - m_read_c.resolve_safe(0); - m_read_d.resolve_safe(0); + m_read_a.resolve_safe(0xf); + m_read_b.resolve_safe(0xf); + m_read_c.resolve_safe(0xf); + m_read_d.resolve_safe(0xf); m_write_c.resolve_safe(); m_write_d.resolve_safe(); @@ -131,9 +131,9 @@ void ucom4_cpu_device::device_start() // zerofill memset(m_stack, 0, sizeof(m_stack)); + memset(m_port_out, 0, sizeof(m_port_out)); m_op = 0; m_prev_op = 0; - m_arg = 0; m_skip = false; m_pc = 0; m_acc = 0; @@ -147,9 +147,9 @@ void ucom4_cpu_device::device_start() // register for savestates save_item(NAME(m_stack)); + save_item(NAME(m_port_out)); save_item(NAME(m_op)); save_item(NAME(m_prev_op)); - save_item(NAME(m_arg)); save_item(NAME(m_skip)); save_item(NAME(m_pc)); save_item(NAME(m_acc)); @@ -185,6 +185,10 @@ void ucom4_cpu_device::device_reset() m_pc = 0; m_op = 0; m_skip = false; + + // clear i/o + for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++) + output_w(i, 0xf); } @@ -215,6 +219,7 @@ void ucom4_cpu_device::execute_run() debugger_instruction_hook(this, m_pc); m_op = m_program->read_byte(m_pc); + m_bitmask = 1 << (m_op & 0x03); m_pc = (m_pc + 1) & m_prgmask; fetch_arg(); diff --git a/src/emu/cpu/ucom4/ucom4.h b/src/emu/cpu/ucom4/ucom4.h index aef9e9cbff9..ac791168e48 100644 --- a/src/emu/cpu/ucom4/ucom4.h +++ b/src/emu/cpu/ucom4/ucom4.h @@ -45,6 +45,20 @@ ucom4_cpu_device::set_write_i_callback(*device, DEVCB_##_devcb); +enum +{ + NEC_UCOM4_PORTA = 0, + NEC_UCOM4_PORTB, + NEC_UCOM4_PORTC, + NEC_UCOM4_PORTD, + NEC_UCOM4_PORTE, + NEC_UCOM4_PORTF, + NEC_UCOM4_PORTG, + NEC_UCOM4_PORTH, + NEC_UCOM4_PORTI +}; + + class ucom4_cpu_device : public cpu_device { @@ -117,25 +131,27 @@ protected: int m_datawidth; int m_prgmask; int m_datamask; - int m_family; // MCU family (43/44/45) - int m_stack_levels; // number of callstack levels - UINT16 m_stack[3+1]; // max 3 + int m_family; // MCU family (43/44/45) + int m_stack_levels; // number of callstack levels + UINT16 m_stack[3+1]; // max 3 + UINT8 m_port_out[0x10]; // last value written to output port UINT8 m_op; - UINT8 m_prev_op; // previous opcode - UINT8 m_arg; // opcode argument for 2-byte opcodes - bool m_skip; // skip next opcode + UINT8 m_prev_op; // previous opcode + UINT8 m_arg; // opcode argument for 2-byte opcodes + UINT8 m_bitmask; // opcode bit argument + bool m_skip; // skip next opcode int m_icount; - UINT16 m_pc; // program counter - 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) + UINT16 m_pc; // program counter + 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) UINT8 m_dph_mask; - UINT8 m_carry_f; // carry flag - UINT8 m_carry_s_f; // carry save flag - UINT8 m_timer_f; // timer out flag - UINT8 m_int_f; // interrupt flag - UINT8 m_inte_f; // interrupt enable flag + UINT8 m_carry_f; // carry flag + UINT8 m_carry_s_f; // carry save flag + UINT8 m_timer_f; // timer out flag + UINT8 m_int_f; // interrupt flag + UINT8 m_inte_f; // interrupt enable flag // i/o handlers devcb_read8 m_read_a; @@ -156,6 +172,8 @@ protected: void ram_w(UINT8 data); void pop_stack(); void push_stack(); + UINT8 input_r(int index); + void output_w(int index, UINT8 data); void op_illegal(); bool check_op_43(); diff --git a/src/emu/cpu/ucom4/ucom4op.inc b/src/emu/cpu/ucom4/ucom4op.inc index 2e316de4d7b..eacf0d08820 100644 --- a/src/emu/cpu/ucom4/ucom4op.inc +++ b/src/emu/cpu/ucom4/ucom4op.inc @@ -31,6 +31,49 @@ void ucom4_cpu_device::push_stack() m_stack[0] = m_pc; } +UINT8 ucom4_cpu_device::input_r(int index) +{ + index &= 0xf; + UINT8 inp = 0xf; + + switch (index) + { + case NEC_UCOM4_PORTA: inp = m_read_a(index, 0xff) & 0xf; break; + case NEC_UCOM4_PORTB: inp = m_read_b(index, 0xff) & 0xf; break; + case NEC_UCOM4_PORTC: inp = m_read_c(index, 0xff) & 0xf; break; + case NEC_UCOM4_PORTD: inp = m_read_d(index, 0xff) & 0xf; break; + + default: + logerror("%s read from unknown port %c at $%03X\n", tag(), 'A' + index, m_pc); + break; + } + + return inp; +} + +void ucom4_cpu_device::output_w(int index, UINT8 data) +{ + index &= 0xf; + data &= 0xf; + + switch (index) + { + case NEC_UCOM4_PORTC: m_write_c(index, data, 0xff); break; + case NEC_UCOM4_PORTD: m_write_d(index, data, 0xff); break; + case NEC_UCOM4_PORTE: m_write_e(index, data, 0xff); break; + case NEC_UCOM4_PORTF: m_write_f(index, data, 0xff); break; + case NEC_UCOM4_PORTG: m_write_g(index, data, 0xff); break; + case NEC_UCOM4_PORTH: m_write_h(index, data, 0xff); break; + 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); + break; + } + + m_port_out[index] = data; +} + void ucom4_cpu_device::op_illegal() { logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_pc); @@ -240,39 +283,39 @@ void ucom4_cpu_device::op_ded() void ucom4_cpu_device::op_rmb() { // RMB B: Reset a single bit of RAM - ram_w(ram_r() & ~(1 << (m_op & 0x03))); + ram_w(ram_r() & ~m_bitmask); } void ucom4_cpu_device::op_smb() { // SMB B: Set a single bit of RAM - ram_w(ram_r() | (1 << (m_op & 0x03))); + ram_w(ram_r() | m_bitmask); } void ucom4_cpu_device::op_reb() { // REB B: Reset a single bit of output port E m_icount--; - op_illegal(); + output_w(NEC_UCOM4_PORTE, m_port_out[NEC_UCOM4_PORTE] & ~m_bitmask); } void ucom4_cpu_device::op_seb() { // SEB B: Set a single bit of output port E m_icount--; - op_illegal(); + output_w(NEC_UCOM4_PORTE, m_port_out[NEC_UCOM4_PORTE] | m_bitmask); } void ucom4_cpu_device::op_rpb() { // RPB B: Reset a single bit of output port (DPl) - op_illegal(); + output_w(m_dpl, m_port_out[m_dpl] & ~m_bitmask); } void ucom4_cpu_device::op_spb() { // SPB B: Set a single bit of output port (DPl) - op_illegal(); + output_w(m_dpl, m_port_out[m_dpl] | m_bitmask); } @@ -340,14 +383,13 @@ void ucom4_cpu_device::op_cm() void ucom4_cpu_device::op_cmb() { // CMB B: skip next on bit(ACC) equals bit(RAM) - UINT8 mask = 1 << (m_op & 0x03); - m_skip = ((m_acc & mask) == (ram_r() & mask)); + m_skip = ((m_acc & m_bitmask) == (ram_r() & m_bitmask)); } void ucom4_cpu_device::op_tab() { // TAB B: skip next on bit(ACC) - m_skip = ((m_acc & (1 << (m_op & 0x03))) != 0); + m_skip = ((m_acc & m_bitmask) != 0); } void ucom4_cpu_device::op_cli() @@ -362,19 +404,19 @@ void ucom4_cpu_device::op_cli() void ucom4_cpu_device::op_tmb() { // TMB B: skip next on bit(RAM) - m_skip = ((ram_r() & (1 << (m_op & 0x03))) != 0); + m_skip = ((ram_r() & m_bitmask) != 0); } void ucom4_cpu_device::op_tpa() { // TPA B: skip next on bit(input port A) - op_illegal(); + m_skip = ((input_r(NEC_UCOM4_PORTA) & m_bitmask) != 0); } void ucom4_cpu_device::op_tpb() { // TPB B: skip next on bit(input port (DPl)) - op_illegal(); + m_skip = ((input_r(m_dpl) & m_bitmask) != 0); } @@ -392,31 +434,32 @@ void ucom4_cpu_device::op_tit() void ucom4_cpu_device::op_ia() { // IA: Input port A to ACC - op_illegal(); + m_acc = input_r(NEC_UCOM4_PORTA); } void ucom4_cpu_device::op_ip() { // IP: Input port (DPl) to ACC - op_illegal(); + m_acc = input_r(m_dpl); } void ucom4_cpu_device::op_oe() { // OE: Output ACC to port E - m_write_e(0, m_acc, 0xff); + output_w(NEC_UCOM4_PORTE, m_acc); } void ucom4_cpu_device::op_op() { // OP: Output ACC to port (DPl) - op_illegal(); + output_w(m_dpl, m_acc); } void ucom4_cpu_device::op_ocd() { // OCD X: Output X to ports C and D - op_illegal(); + output_w(NEC_UCOM4_PORTD, m_arg >> 4); + output_w(NEC_UCOM4_PORTC, m_arg & 0xf); } -- cgit v1.2.3