summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2015-02-07 23:28:45 +0100
committer hap <happppp@users.noreply.github.com>2015-02-07 23:28:45 +0100
commitf80763b734f4e4f45adb245f61663e98c855752b (patch)
treeb81e214d5ee6e2146f9d0217edf7563ff1530473
parent6f23cd927d45322d43977b7ca1eade71bffb5955 (diff)
added ucom4 straightforward opcodes
-rw-r--r--src/emu/cpu/amis2000/amis2000.h2
-rw-r--r--src/emu/cpu/amis2000/amis2000op.inc14
-rw-r--r--src/emu/cpu/ucom4/ucom4.c1
-rw-r--r--src/emu/cpu/ucom4/ucom4.h9
-rw-r--r--src/emu/cpu/ucom4/ucom4op.inc156
5 files changed, 122 insertions, 60 deletions
diff --git a/src/emu/cpu/amis2000/amis2000.h b/src/emu/cpu/amis2000/amis2000.h
index 18c3b5d43a3..4e0c9ff521c 100644
--- a/src/emu/cpu/amis2000/amis2000.h
+++ b/src/emu/cpu/amis2000/amis2000.h
@@ -75,7 +75,7 @@ protected:
UINT8 m_callstack_bits; // number of program counter bits held in callstack
UINT16 m_callstack_mask;
UINT8 m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400
- UINT16 m_callstack[5]; // max 5
+ UINT16 m_callstack[5+1]; // max 5
UINT16 m_pc; // 13-bit program counter
UINT8 m_ppr; // prepared page register (PP 1)
diff --git a/src/emu/cpu/amis2000/amis2000op.inc b/src/emu/cpu/amis2000/amis2000op.inc
index e8b0f233727..d211f5dac38 100644
--- a/src/emu/cpu/amis2000/amis2000op.inc
+++ b/src/emu/cpu/amis2000/amis2000op.inc
@@ -2,13 +2,13 @@
// internal helpers
-UINT8 amis2000_device::ram_r()
+inline UINT8 amis2000_device::ram_r()
{
UINT16 address = m_bu << 4 | m_bl;
return m_data->read_byte(address) & 0xf;
}
-void amis2000_device::ram_w(UINT8 data)
+inline void amis2000_device::ram_w(UINT8 data)
{
UINT16 address = m_bu << 4 | m_bl;
m_data->write_byte(address, data & 0xf);
@@ -17,7 +17,7 @@ void amis2000_device::ram_w(UINT8 data)
void amis2000_device::pop_callstack()
{
m_pc = (m_pc & ~m_callstack_mask) | (m_callstack[0] & m_callstack_mask);
- for (int i = 0; i < m_callstack_depth-1; i++)
+ for (int i = 0; i < m_callstack_depth; i++)
{
m_callstack[i] = m_callstack[i+1];
m_callstack[i+1] = 0;
@@ -27,9 +27,7 @@ void amis2000_device::pop_callstack()
void amis2000_device::push_callstack()
{
for (int i = m_callstack_depth-1; i >= 1; i--)
- {
m_callstack[i] = m_callstack[i-1];
- }
m_callstack[0] = m_pc & m_callstack_mask;
}
@@ -407,13 +405,13 @@ void amis2000_device::op_sos()
void amis2000_device::op_tf1()
{
// TF1: skip next on flag 1
- m_skip = (m_f & 0x01) ? true : false;
+ m_skip = ((m_f & 0x01) != 0);
}
void amis2000_device::op_tf2()
{
// TF2: skip next on flag 2
- m_skip = (m_f & 0x02) ? true : false;
+ m_skip = ((m_f & 0x02) != 0);
}
@@ -433,7 +431,7 @@ void amis2000_device::op_adis()
// ADIS X: add X to ACC, skip next on not carry
UINT8 param = m_op & 0x0f;
m_acc += param;
- m_skip = !(m_acc >> 4 & 1);
+ m_skip = !(m_acc & 0x10);
m_acc &= 0xf;
}
diff --git a/src/emu/cpu/ucom4/ucom4.c b/src/emu/cpu/ucom4/ucom4.c
index ab1e436c372..4868dc7d9c2 100644
--- a/src/emu/cpu/ucom4/ucom4.c
+++ b/src/emu/cpu/ucom4/ucom4.c
@@ -114,6 +114,7 @@ void ucom4_cpu_device::device_start()
m_data = &space(AS_DATA);
m_prgmask = (1 << m_prgwidth) - 1;
m_datamask = (1 << m_datawidth) - 1;
+ m_dph_mask = m_datamask >> 4;
m_read_a.resolve_safe(0);
m_read_b.resolve_safe(0);
diff --git a/src/emu/cpu/ucom4/ucom4.h b/src/emu/cpu/ucom4/ucom4.h
index 86042e4c682..aef9e9cbff9 100644
--- a/src/emu/cpu/ucom4/ucom4.h
+++ b/src/emu/cpu/ucom4/ucom4.h
@@ -119,7 +119,7 @@ protected:
int m_datamask;
int m_family; // MCU family (43/44/45)
int m_stack_levels; // number of callstack levels
- UINT16 m_stack[3]; // max 3
+ UINT16 m_stack[3+1]; // max 3
UINT8 m_op;
UINT8 m_prev_op; // previous opcode
UINT8 m_arg; // opcode argument for 2-byte opcodes
@@ -129,7 +129,8 @@ protected:
UINT16 m_pc; // program counter
UINT8 m_acc; // 4-bit accumulator
UINT8 m_dpl; // 4-bit data pointer low (RAM x)
- UINT8 m_dph; // 1/2/3-bit data pointer high (RAM y)
+ 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
@@ -151,6 +152,10 @@ protected:
devcb_write8 m_write_i;
// opcode handlers
+ UINT8 ram_r();
+ void ram_w(UINT8 data);
+ void pop_stack();
+ void push_stack();
void op_illegal();
bool check_op_43();
diff --git a/src/emu/cpu/ucom4/ucom4op.inc b/src/emu/cpu/ucom4/ucom4op.inc
index 0ae6c88ce9b..2e316de4d7b 100644
--- a/src/emu/cpu/ucom4/ucom4op.inc
+++ b/src/emu/cpu/ucom4/ucom4op.inc
@@ -2,6 +2,35 @@
// internal helpers
+inline UINT8 ucom4_cpu_device::ram_r()
+{
+ UINT16 address = m_dph << 4 | m_dpl;
+ return m_data->read_byte(address & m_datamask) & 0xf;
+}
+
+inline void ucom4_cpu_device::ram_w(UINT8 data)
+{
+ UINT16 address = m_dph << 4 | m_dpl;
+ m_data->write_byte(address & m_datamask, data & 0xf);
+}
+
+void ucom4_cpu_device::pop_stack()
+{
+ m_pc = m_stack[0] & m_prgmask;
+ for (int i = 0; i < m_stack_levels; i++)
+ {
+ m_stack[i] = m_stack[i+1];
+ m_stack[i+1] = 0;
+ }
+}
+
+void ucom4_cpu_device::push_stack()
+{
+ for (int i = m_stack_levels-1; i >= 1; i--)
+ m_stack[i] = m_stack[i-1];
+ m_stack[0] = m_pc;
+}
+
void ucom4_cpu_device::op_illegal()
{
logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_pc);
@@ -16,7 +45,7 @@ void ucom4_cpu_device::op_illegal()
void ucom4_cpu_device::op_li()
{
// LI X: Load ACC with X
- // note: only execute the first one in a sequence of LAI
+ // note: only execute the first one in a sequence of LI
if ((m_prev_op & 0xf0) != (m_op & 0xf0))
m_acc = m_op & 0x0f;
}
@@ -24,19 +53,22 @@ void ucom4_cpu_device::op_li()
void ucom4_cpu_device::op_lm()
{
// LM X: Load ACC with RAM, xor DPh with X
- op_illegal();
+ m_acc = ram_r();
+ m_dph ^= (m_op & 0x03);
}
void ucom4_cpu_device::op_ldi()
{
// LDI X: Load DP with X
- op_illegal();
+ m_dph = m_arg >> 4 & 0xf;
+ m_dpl = m_arg & 0x0f;
}
void ucom4_cpu_device::op_ldz()
{
// LDZ X: Load DPh with 0, Load DPl with X
- op_illegal();
+ m_dph = 0;
+ m_dpl = m_op & 0x0f;
}
@@ -45,7 +77,7 @@ void ucom4_cpu_device::op_ldz()
void ucom4_cpu_device::op_s()
{
// S: Store ACC into RAM
- op_illegal();
+ ram_w(m_acc);
}
@@ -54,13 +86,13 @@ void ucom4_cpu_device::op_s()
void ucom4_cpu_device::op_tal()
{
// TAL: Transfer ACC to DPl
- op_illegal();
+ m_dpl = m_acc;
}
void ucom4_cpu_device::op_tla()
{
- // TLA: Transfer
- op_illegal();
+ // TLA: Transfer DPl to ACC
+ m_acc = m_dpl;
}
@@ -69,19 +101,26 @@ void ucom4_cpu_device::op_tla()
void ucom4_cpu_device::op_xm()
{
// XM X: Exchange ACC with RAM, xor DPh with X
- op_illegal();
+ UINT8 old_acc = m_acc;
+ m_acc = ram_r();
+ ram_w(old_acc);
+ m_dph ^= (m_op & 0x03);
}
void ucom4_cpu_device::op_xmi()
{
// XMI X: Exchange ACC with RAM, xor DPh with X, Increment DPl, skip next on carry
- op_illegal();
+ op_xm();
+ m_dpl = (m_dpl + 1) & 0xf;
+ m_skip = (m_dpl == 0);
}
void ucom4_cpu_device::op_xmd()
{
// XMD X: Exchange ACC with RAM, xor DPh with X, Decrement DPl, skip next on carry
- op_illegal();
+ op_xm();
+ m_dpl = (m_dpl - 1) & 0xf;
+ m_skip = (m_dpl == 0xf);
}
@@ -89,32 +128,34 @@ void ucom4_cpu_device::op_xmd()
void ucom4_cpu_device::op_ad()
{
- // AD: Add RAM to Acc, skip next on carry
- op_illegal();
+ // AD: Add RAM to ACC, skip next on carry
+ m_acc += ram_r();
+ m_skip = ((m_acc & 0x10) != 0);
+ m_acc &= 0xf;
}
void ucom4_cpu_device::op_adc()
{
- // ADC: Add RAM and carry to Acc, store Carry F/F
+ // ADC: Add RAM and carry to ACC, store Carry F/F
op_illegal();
}
void ucom4_cpu_device::op_ads()
{
- // ADS: Add RAM and carry to Acc, store Carry F/F, skip next on carry
+ // ADS: Add RAM and carry to ACC, store Carry F/F, skip next on carry
op_illegal();
}
void ucom4_cpu_device::op_daa()
{
// DAA: Add 6 to ACC to adjust decimal for BCD Addition
- op_illegal();
+ m_acc = (m_acc + 6) & 0xf;
}
void ucom4_cpu_device::op_das()
{
// DAS: Add 10 to ACC to adjust decimal for BCD Subtraction
- op_illegal();
+ m_acc = (m_acc + 10) & 0xf;
}
@@ -123,7 +164,7 @@ void ucom4_cpu_device::op_das()
void ucom4_cpu_device::op_exl()
{
// EXL: Xor ACC with RAM
- op_illegal();
+ m_acc ^= ram_r();
}
@@ -132,13 +173,13 @@ void ucom4_cpu_device::op_exl()
void ucom4_cpu_device::op_cma()
{
// CMA: Complement ACC
- op_illegal();
+ m_acc ^= 0xf;
}
void ucom4_cpu_device::op_cia()
{
// CIA: Complement ACC, Increment ACC
- op_illegal();
+ m_acc = ((m_acc ^ 0xf) + 1) & 0xf;
}
@@ -147,19 +188,19 @@ void ucom4_cpu_device::op_cia()
void ucom4_cpu_device::op_clc()
{
// CLC: Reset Carry F/F
- op_illegal();
+ m_carry_f = 0;
}
void ucom4_cpu_device::op_stc()
{
// STC: Set Carry F/F
- op_illegal();
+ m_carry_f = 1;
}
void ucom4_cpu_device::op_tc()
{
// TC: skip next on Carry F/F
- op_illegal();
+ m_skip = (m_carry_f != 0);
}
@@ -168,25 +209,29 @@ void ucom4_cpu_device::op_tc()
void ucom4_cpu_device::op_inc()
{
// INC: Increment ACC, skip next on carry
- op_illegal();
+ m_acc = (m_acc + 1) & 0xf;
+ m_skip = (m_acc == 0);
}
void ucom4_cpu_device::op_dec()
{
// DEC: Decrement ACC, skip next on carry
- op_illegal();
+ m_acc = (m_acc - 1) & 0xf;
+ m_skip = (m_acc == 0xf);
}
void ucom4_cpu_device::op_ind()
{
// IND: Increment DPl, skip next on carry
- op_illegal();
+ m_dpl = (m_dpl + 1) & 0xf;
+ m_skip = (m_dpl == 0);
}
void ucom4_cpu_device::op_ded()
{
// DED: Decrement DPl, skip next on carry
- op_illegal();
+ m_dpl = (m_dpl - 1) & 0xf;
+ m_skip = (m_dpl == 0xf);
}
@@ -195,24 +240,26 @@ void ucom4_cpu_device::op_ded()
void ucom4_cpu_device::op_rmb()
{
// RMB B: Reset a single bit of RAM
- op_illegal();
+ ram_w(ram_r() & ~(1 << (m_op & 0x03)));
}
void ucom4_cpu_device::op_smb()
{
// SMB B: Set a single bit of RAM
- op_illegal();
+ ram_w(ram_r() | (1 << (m_op & 0x03)));
}
void ucom4_cpu_device::op_reb()
{
// REB B: Reset a single bit of output port E
+ m_icount--;
op_illegal();
}
void ucom4_cpu_device::op_seb()
{
// SEB B: Set a single bit of output port E
+ m_icount--;
op_illegal();
}
@@ -234,37 +281,41 @@ void ucom4_cpu_device::op_spb()
void ucom4_cpu_device::op_jmpcal()
{
// JMP A: Jump to Address / CAL A: Call Address
- op_illegal();
+ if (m_op & 0x08)
+ push_stack();
+ m_pc = (m_op & 0x07) << 8 | m_arg;
}
void ucom4_cpu_device::op_jcp()
{
// JCP A: Jump to Address in current page
- op_illegal();
+ m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
}
void ucom4_cpu_device::op_jpa()
{
- // JPA: Jump to (ACC)
- op_illegal();
+ // JPA: Jump to (ACC) in current page
+ m_pc = (m_pc & ~0x3f) | (m_acc << 2);
}
void ucom4_cpu_device::op_czp()
{
- // CZP A: Call (Address)
- op_illegal();
+ // CZP A: Call Address (short)
+ push_stack();
+ m_pc = (m_op & 0x0f) << 2;
}
void ucom4_cpu_device::op_rt()
{
// RT: Return from subroutine
- op_illegal();
+ m_icount--;
+ pop_stack();
}
void ucom4_cpu_device::op_rts()
{
// RTS: Return from subroutine, skip next
- op_rt();
+ pop_stack();
m_skip = true;
}
@@ -274,37 +325,44 @@ void ucom4_cpu_device::op_rts()
void ucom4_cpu_device::op_ci()
{
// CI X: skip next on ACC equals X
- op_illegal();
+ m_skip = (m_acc == (m_arg & 0x0f));
+
+ if ((m_arg & 0xf0) != 0xc0)
+ logerror("%s CI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_pc);
}
void ucom4_cpu_device::op_cm()
{
// CM: skip next on ACC equals RAM
- op_illegal();
+ m_skip = (m_acc == ram_r());
}
void ucom4_cpu_device::op_cmb()
{
// CMB B: skip next on bit(ACC) equals bit(RAM)
- op_illegal();
+ UINT8 mask = 1 << (m_op & 0x03);
+ m_skip = ((m_acc & mask) == (ram_r() & mask));
}
void ucom4_cpu_device::op_tab()
{
// TAB B: skip next on bit(ACC)
- op_illegal();
+ m_skip = ((m_acc & (1 << (m_op & 0x03))) != 0);
}
void ucom4_cpu_device::op_cli()
{
// CLI X: skip next on DPl equals X
- op_illegal();
+ m_skip = (m_dpl == (m_arg & 0x0f));
+
+ if ((m_arg & 0xf0) != 0xe0)
+ logerror("%s CLI opcode unexpected upper arg $%02X at $%03X\n", tag(), m_arg & 0xf0, m_pc);
}
void ucom4_cpu_device::op_tmb()
{
// TMB B: skip next on bit(RAM)
- op_illegal();
+ m_skip = ((ram_r() & (1 << (m_op & 0x03))) != 0);
}
void ucom4_cpu_device::op_tpa()
@@ -333,31 +391,31 @@ void ucom4_cpu_device::op_tit()
void ucom4_cpu_device::op_ia()
{
- // IA: x
+ // IA: Input port A to ACC
op_illegal();
}
void ucom4_cpu_device::op_ip()
{
- // IP: x
+ // IP: Input port (DPl) to ACC
op_illegal();
}
void ucom4_cpu_device::op_oe()
{
- // OE: x
- op_illegal();
+ // OE: Output ACC to port E
+ m_write_e(0, m_acc, 0xff);
}
void ucom4_cpu_device::op_op()
{
- // OP: x
+ // OP: Output ACC to port (DPl)
op_illegal();
}
void ucom4_cpu_device::op_ocd()
{
- // OCD X: x
+ // OCD X: Output X to ports C and D
op_illegal();
}