summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2015-02-08 01:16:23 +0100
committer hap <happppp@users.noreply.github.com>2015-02-08 01:16:23 +0100
commit8717aeab38f48fe2727b9f5ef8c31322b4f99eff (patch)
treed88e10ec59921e28c19ab29501a33187a4a8b958
parentf80763b734f4e4f45adb245f61663e98c855752b (diff)
added ucom4 i/o opcodes
-rw-r--r--src/emu/cpu/ucom4/ucom4.c17
-rw-r--r--src/emu/cpu/ucom4/ucom4.h48
-rw-r--r--src/emu/cpu/ucom4/ucom4op.inc77
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);
}