From c5099540fd54ab4c824f5bc5266492196a69135f Mon Sep 17 00:00:00 2001 From: Ricardo Barreira Date: Mon, 20 Nov 2017 23:07:21 +0000 Subject: Fixes to hcd62121 CPU emulation based on experiments with the actual hardware (using a CFX-9850G). With these fixes, the CFX-9850G is emulated just accurately enough for most of the RUN mode to work well. Further reverse-engineering is ongoing. --- src/devices/cpu/hcd62121/hcd62121.cpp | 604 ++++++++++++++++++++------------- src/devices/cpu/hcd62121/hcd62121.h | 6 +- src/devices/cpu/hcd62121/hcd62121d.cpp | 78 +++-- src/mame/drivers/cfx9850.cpp | 20 +- 4 files changed, 432 insertions(+), 276 deletions(-) diff --git a/src/devices/cpu/hcd62121/hcd62121.cpp b/src/devices/cpu/hcd62121/hcd62121.cpp index 92f3deaac88..34f3bb4ff1b 100644 --- a/src/devices/cpu/hcd62121/hcd62121.cpp +++ b/src/devices/cpu/hcd62121/hcd62121.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Wilbert Pol +// copyright-holders:Wilbert Pol, Ricardo Barreira /********************************************************************** Hitachi hcd62121 cpu core emulation. @@ -7,9 +7,12 @@ The Hitachi hcd62121 is the custom cpu which was used in the Casio CFX-9850 (and maybe some other things too). -This CPU core is based on the information provided by Martin Poupe. +This CPU core is mainly based on the information provided by Martin Poupe. Martin Poupe's site can be found at http://martin.poupe.org/casio/ +Other contributors to reverse-engineering this CPU include Petr Pfeifer +who hacked the hardware, Uwe Ryssel, Brad O'Dell and Ricardo Barreira. + TODO: - instruction timings - unknown instructions @@ -38,11 +41,11 @@ enum }; +constexpr u8 FLAG_CL = 0x10; constexpr u8 FLAG_Z = 0x08; -constexpr u8 FLAG_C = 0x02; -constexpr u8 FLAG_ZL = 0x04; -constexpr u8 FLAG_CL = 0x01; -constexpr u8 FLAG_ZH = 0x10; +constexpr u8 FLAG_C = 0x04; +constexpr u8 FLAG_ZL = 0x02; +constexpr u8 FLAG_ZH = 0x01; DEFINE_DEVICE_TYPE(HCD62121, hcd62121_cpu_device, "hcd62121_cpu_device", "Hitachi HCD62121") @@ -110,12 +113,12 @@ void hcd62121_cpu_device::read_reg(int size, u8 op1) if (op1 & 0x80) { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 - i) & 0x7f]; + m_temp1[i] = m_reg[(op1 - i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } else { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 + i) & 0x7f]; + m_temp1[i] = m_reg[(op1 + i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } } @@ -134,8 +137,7 @@ void hcd62121_cpu_device::write_reg(int size, u8 op1) } } - -void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logical) +void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { for (int i = 0; i < size; i++) m_temp1[i] = m_reg[(op1 + i) & 0x7f]; @@ -145,7 +147,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = op_is_logical ? op2 : 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { @@ -154,7 +156,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } - if (!(op1 & 0x80) && !(op2 & 0x80)) + if (!(op1 & 0x80)) { /* We need to swap parameters */ for (int i = 0; i < size; i++) @@ -167,24 +169,24 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic } -void hcd62121_cpu_device::write_regreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::write_regreg(int size, u8 arg1, u8 arg2) { - if ((op1 & 0x80) || (op2 & 0x80)) + if ((arg1 & 0x80)) { - /* store in reg1 */ + /* store in arg1 */ for (int i = 0; i < size; i++) - m_reg[(op1 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg1 + i) & 0x7f] = m_temp1[i]; } else { - /* store in reg2 */ + /* store in arg2 */ for (int i = 0; i < size; i++) - m_reg[(op2 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg2 + i) & 0x7f] = m_temp1[i]; } } -void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { u16 ad = m_reg[(0x40 | op1) & 0x7f ] | (m_reg[(0x40 | (op1 + 1)) & 0x7f] << 8); @@ -197,12 +199,14 @@ void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) if (op1 & 0x80) { + /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { + /* Second operand is a register */ for (int i = 0; i < size; i++) m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } @@ -282,11 +286,11 @@ bool hcd62121_cpu_device::check_cond(u8 op) case 0x03: /* Z set */ return (m_f & FLAG_Z); - case 0x04: /* Z or C set */ - return (m_f & (FLAG_Z | FLAG_C)); + case 0x04: /* ZH not set */ + return (!(m_f & FLAG_ZH)); - case 0x05: /* CL set */ - return (m_f & FLAG_CL); + case 0x05: /* ZL not set */ + return (!(m_f & FLAG_ZL)); case 0x06: /* C clear */ return (!(m_f & FLAG_C)); @@ -575,169 +579,215 @@ inline void hcd62121_cpu_device::set_cl_flag(bool is_cl) inline void hcd62121_cpu_device::op_msk(int size) { - bool mskres = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { - if ((m_temp1[i] & m_temp2[i]) != m_temp2[i]) - mskres = false; + if ((m_temp1[i] & m_temp2[i] & 0xf0) != (m_temp2[i] & 0xf0)) + zero_high = false; + if ((m_temp1[i] & m_temp2[i] & 0x0f) != (m_temp2[i] & 0x0f)) + zero_low = false; } - set_zero_flag(!mskres); -} - - -inline void hcd62121_cpu_device::op_imsk(int size) -{ - bool mskres = true; - bool set_zero = false; - - for (int i = 0; i < size; i++) - { - if ((m_temp1[i] & ~m_temp2[i]) != ~m_temp2[i]) - mskres = false; - if (m_temp1[i] | m_temp2[i]) - set_zero = true; - } + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); - set_zero_flag(set_zero); - set_carry_flag(!mskres); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_and(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] & m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_or(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] | m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_xor(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] ^ m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_add(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 15); - for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] + m_temp2[i] + carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 0x0f); + } + u16 res = m_temp1[i] + m_temp2[i] + carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = (res & 0xff00) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } // BCD ADD inline void hcd62121_cpu_device::op_addb(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 9); + set_cl_flag((m_temp1[size-1] & 0x0f) + (m_temp2[size-1] & 0x0f) > 9); for (int i = 0; i < size; i++) { - u16 res = (m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry; + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 + num2 + carry; + carry = (result > 99); + if (result > 99) + result -= 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; + } - if (res > 9) - { - res += 6; - } - res += (m_temp1[i] & 0xf0) + (m_temp2[i] & 0xf0); - if (res > 0x9f) - { - res += 0x60; - } - m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag(carry); +} - carry = (res & 0xff00) ? 1 : 0; + +// BCD SUBTRACT +inline void hcd62121_cpu_device::op_subb(int size) +{ + bool zero_high = true; + bool zero_low = true; + u8 carry = 0; + + set_cl_flag((m_temp1[size-1] & 0x0f) < (m_temp2[size-1] & 0x0f)); + + for (int i = 0; i < size; i++) + { + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 - num2 - carry; + carry = (result < 0); + if (result < 0) + result += 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } inline void hcd62121_cpu_device::op_sub(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; set_cl_flag((m_temp1[0] & 0x0f) < (m_temp2[0] & 0x0f)); for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] - m_temp2[i] - carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0); + } + u16 res = m_temp1[i] - m_temp2[i] - carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = ( res & 0xff00 ) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } @@ -774,48 +824,36 @@ void hcd62121_cpu_device::execute_run() // actual instruction timings unknown m_icount -= 4; - switch (op) { - case 0x00: /* rorb/rolb r1,4 */ - case 0x01: /* rorw/rolw r1,4 */ - case 0x02: /* rorq/rolq r1,4 */ - case 0x03: /* rort/rolt r1,4 */ - /* Nibble rotate */ + case 0x00: /* shrb/shlb r1,8 */ // Yes, this just sets a register to 0! + case 0x01: /* shrw/shlw r1,8 */ + case 0x02: /* shrq/shlq r1,8 */ + case 0x03: /* shrt/shlt r1,8 */ { int size = datasize(op); u8 reg1 = read_op(); - u8 d1 = 0, d2 = 0; - read_reg(size, reg1); - - if (reg1 & 0x80) - { - // rotate right - d2 = (m_temp1[size-1] & 0x0f) << 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x0f) << 4; - m_temp1[i] = (m_temp1[i] >> 4) | d2; - d2 = d1; + // TODO - read_reg should support reading this + if (reg1 & 0x80) { + read_reg(size, (reg1 & 0x7f) - size + 1); + for (int i=0; i < size - 1; i++) { + m_temp1[i] = m_temp1[i + 1]; } + m_temp1[size-1] = 0; + write_reg(size, (reg1 & 0x7f) - size + 1); } else { - // rotate left - d2 = (m_temp1[size-1] & 0xf0) >> 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0xf0) >> 4; - m_temp1[i] = (m_temp1[i] << 4) | d2; - d2 = d1; + read_reg(size, reg1); + for (int i = size-1; i > 0; i--) { + m_temp1[i] = m_temp1[i - 1]; } + m_temp1[0] = 0; + write_reg(size, reg1); } - - write_reg(size, reg1); } break; - case 0x04: /* mskb r1,r2 */ case 0x05: /* mskw r1,r2 */ case 0x06: /* mskq r1,r2 */ @@ -825,7 +863,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_msk(size); } @@ -877,7 +915,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_and(size); } @@ -892,7 +930,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_xor(size); @@ -933,10 +971,10 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x1C: /* imskb r1,r2 */ - case 0x1D: /* imskw r1,r2 */ - case 0x1E: /* imskq r1,r2 */ - case 0x1F: /* imskt r1,r2 */ + case 0x1C: /* cmpaddb r1,r2 */ + case 0x1D: /* cmpaddw r1,r2 */ + case 0x1E: /* cmpaddq r1,r2 */ + case 0x1F: /* cmpaddt r1,r2 */ { int size = datasize(op); u8 reg1 = read_op(); @@ -944,46 +982,42 @@ void hcd62121_cpu_device::execute_run() read_regreg(size, reg1, reg2, false); - op_imsk(size); + op_add(size); } break; - case 0x20: /* rorb/rolb r1 */ - case 0x21: /* rorw/rolw r1 */ - case 0x22: /* rorq/rolq r1 */ - case 0x23: /* rort/rolt r1 */ - /* Single bit rotate */ + case 0x20: /* shrb r1,1 */ + case 0x21: /* shrw r1,1 */ + case 0x22: /* shrq r1,1 */ + case 0x23: /* shrt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) + d2 = 0; + set_cl_flag ((m_temp1[0] & (1U<<4)) != 0U); + for (int i = 0; i < size; i++) { - // rotate right - d2 = (m_temp1[size-1] & 0x01) << 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else - { - // rotate left - d2 = (m_temp1[size-1] & 0x80) >> 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x01) << 7; + m_temp1[i] = (m_temp1[i] >> 1) | d2; + d2 = d1; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -996,7 +1030,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_or(size); @@ -1004,40 +1038,37 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x28: /* shrb/shlb r1 */ - case 0x29: /* shrw/shlw r1 */ - case 0x2A: /* shrq/shlq r1 */ - case 0x2B: /* shrt/shlt r1 */ - /* Single bit shift */ + case 0x28: /* shlb r1,1 */ + case 0x29: /* shlw r1,1 */ + case 0x2A: /* shlq r1,1 */ + case 0x2B: /* shlt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) - { - // shift right - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else + set_cl_flag ((m_temp1[0] & (1U<<3)) != 0U); + for (int i = 0; i < size; i++) { - // shift left - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x80) >> 7; + m_temp1[i] = (m_temp1[i] << 1) | d2; + d2 = d1; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -1058,6 +1089,23 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x30: /* subbb r1,r2 */ + case 0x31: /* subbw r1,r2 */ + case 0x32: /* subbq r1,r2 */ + case 0x33: /* subbt r1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_regreg(size, reg1, reg2, false); + + op_subb(size); + + write_regreg(size, reg1, reg2); + } + break; + case 0x34: /* subb r1,r2 */ case 0x35: /* subw r1,r2 */ case 0x36: /* subq r1,r2 */ @@ -1118,7 +1166,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); } @@ -1133,7 +1181,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_sub(size); } @@ -1148,7 +1196,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) m_temp1[i] = m_temp2[i]; @@ -1157,6 +1205,21 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x5C: /* cmpaddb ir1,r2 */ + case 0x5D: /* cmpaddw ir1,r2 */ + case 0x5E: /* cmpaddq ir1,r2 */ + case 0x5F: /* cmpaddt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_add(size); + } + break; + case 0x64: /* orb ir1,r2 */ case 0x65: /* orb ir1,r2 */ case 0x66: /* orb ir1,r2 */ @@ -1166,7 +1229,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_or(size); @@ -1183,7 +1246,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); @@ -1191,6 +1254,40 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x74: /* subb ir1,r2 */ + case 0x75: /* subw ir1,r2 */ + case 0x76: /* subq ir1,r2 */ + case 0x77: /* subt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_sub(size); + + write_iregreg(size, reg1, reg2); + } + break; + + case 0x78: /* adbb ir1,r2 */ + case 0x79: /* adbw ir1,r2 */ + case 0x7A: /* adbq ir1,r2 */ + case 0x7B: /* adbt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_addb(size); + + write_iregreg(size, reg1, reg2); + } + break; + case 0x7C: /* addb ir1,r2 */ case 0x7D: /* addw ir1,r2 */ case 0x7E: /* addq ir1,r2 */ @@ -1200,7 +1297,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_add(size); @@ -1209,7 +1306,11 @@ void hcd62121_cpu_device::execute_run() break; case 0x88: /* jump _a16 */ - m_ip = (read_op() << 8) | read_op(); + { + u8 a1 = read_op(); + u8 a2 = read_op(); + m_ip = (a1 << 8) | a2; + } break; case 0x89: /* jumpf cs:a16 */ @@ -1234,8 +1335,30 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x8C: /* unk_8C */ - case 0x8D: /* unk_8D */ + case 0x8C: /* bstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp--; + m_lar--; + } + } + break; + + case 0x8D: /* fstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp++; + m_lar++; + } + } + break; + case 0x8E: /* unk_8E */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; @@ -1244,8 +1367,8 @@ void hcd62121_cpu_device::execute_run() case 0x91: /* retzl */ case 0x92: /* retc */ case 0x93: /* retz */ - case 0x94: /* retzc */ - case 0x95: /* retcl */ + case 0x94: /* retnzh */ + case 0x95: /* retnzl */ case 0x96: /* retnc */ case 0x97: /* retnz */ if (check_cond(op)) @@ -1274,8 +1397,8 @@ void hcd62121_cpu_device::execute_run() case 0xA1: /* jmpzl a16 */ case 0xA2: /* jmpc a16 */ case 0xA3: /* jmpz a16 */ - case 0xA4: /* jmpzc a16 */ - case 0xA5: /* jmpcl a16 */ + case 0xA4: /* jmpnzh a16 */ + case 0xA5: /* jmpnzl a16 */ case 0xA6: /* jmpnc a16 */ case 0xA7: /* jmpnz a16 */ { @@ -1291,8 +1414,8 @@ void hcd62121_cpu_device::execute_run() case 0xA9: /* callzl a16 */ case 0xAA: /* callc a16 */ case 0xAB: /* callz a16 */ - case 0xAC: /* callzc a16 */ - case 0xAD: /* callcl a16 */ + case 0xAC: /* callnzh a16 */ + case 0xAD: /* callnzl a16 */ case 0xAE: /* callnc a16 */ case 0xAF: /* callnz a16 */ { @@ -1335,7 +1458,7 @@ void hcd62121_cpu_device::execute_run() read_op(); break; - case 0xBB: /* jmpcl? a16 */ + case 0xBB: /* jmpcl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1346,12 +1469,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xBC: /* unk_BC reg/i8 */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); - break; - - case 0xBF: /* jmpncl? a16 */ + case 0xBF: /* jmpncl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1362,14 +1480,17 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xC0: /* movb reg,i8 */ + case 0xC0: /* movb reg,i8 */ // TODO - test case 0xC1: /* movw reg,i16 */ - case 0xC2: /* movw reg,i64 */ - case 0xC3: /* movw reg,i80 */ + case 0xC2: /* movw reg,i64 */ // TODO - test + case 0xC3: /* movw reg,i80 */ // TODO - test { int size = datasize(op); u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + for (int i = 0; i < size; i++) { m_reg[(reg + i) & 0x7f] = read_op(); @@ -1383,12 +1504,12 @@ void hcd62121_cpu_device::execute_run() case 0xC7: /* movt (lar),r1 / r1,(lar) */ { int size = datasize(op); - u8 reg1 = read_op(); - u8 reg2 = read_op(); + u8 arg1 = read_op(); + u8 arg2 = read_op(); int pre_inc = 0; int post_inc = 1; - switch (reg1 & 0x60) + switch (arg1 & 0x60) { case 0x00: pre_inc = 0; @@ -1408,23 +1529,29 @@ void hcd62121_cpu_device::execute_run() break; } - if ((reg1 & 0x80) || (reg2 & 0x80)) + if ((arg1 & 0x80) || (arg2 & 0x80)) { - /* (lar) <- r1 */ + /* (lar) <- r2 (immediate or register) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(reg2 + i) & 0x7f]); + if (arg1 & 0x80) { + m_program->write_byte((m_dseg << 16) | m_lar, arg2); + } + else + { + m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(arg2 + i) & 0x7f]); + } m_lar += post_inc; } } else { - /* r1 <- (lar) */ + /* r2 <- (lar) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_reg[(reg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); + m_reg[(arg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); m_lar += post_inc; } } @@ -1440,7 +1567,11 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + if (reg1 & 0x80) { + fatalerror("%02x:%04x: unimplemented swap with immediate encountered\n", m_cseg, m_ip-1); + } + + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) { @@ -1451,6 +1582,7 @@ void hcd62121_cpu_device::execute_run() write_iregreg(size, reg1, reg2); write_iregreg2(size, reg1, reg2); + // TODO - are flags affected? } break; @@ -1492,11 +1624,11 @@ void hcd62121_cpu_device::execute_run() break; case 0xD8: /* movb f,reg */ - m_f = m_reg[read_op() & 0x7f]; + m_f = m_reg[read_op() & 0x7f] & 0x3f; break; case 0xD9: /* movb f,i8 */ - m_f = read_op(); + m_f = read_op() & 0x3f; break; case 0xDC: /* movb ds,reg */ @@ -1515,6 +1647,10 @@ void hcd62121_cpu_device::execute_run() } break; + case 0xDF: /* movw lar,i8 */ + m_lar = read_op(); + break; + case 0xE0: /* in0 reg */ { logerror("%06x: in0 read\n", (m_cseg << 16) | m_ip); @@ -1532,16 +1668,21 @@ void hcd62121_cpu_device::execute_run() m_reg[read_op() & 0x7f] = m_ki_cb(); break; - case 0xE6: /* movb reg,PORT */ - m_reg[read_op() & 0x7f] = m_port; + case 0xE3: /* movb reg,dsize */ + m_reg[read_op() & 0x7f] = m_dsize; break; - case 0xE3: /* unk_e3 reg/i8 (in?) */ - case 0xE4: /* unk_e4 reg/i8 (in?) */ - case 0xE5: /* unk_e5 reg/i8 (in?) */ - case 0xE7: /* unk_e7 reg/i8 (in?) */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); + case 0xE4: /* movb reg,f */ + { + u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + m_reg[reg & 0x7f] = m_f; + } + break; + + case 0xE6: /* movb reg,PORT */ + m_reg[read_op() & 0x7f] = m_port; break; case 0xE8: /* movw r1,lar */ @@ -1553,7 +1694,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xEB: /* movw reg,ss */ + case 0xEB: /* movw reg,sp */ { u8 reg1 = read_op(); @@ -1589,6 +1730,9 @@ void hcd62121_cpu_device::execute_run() case 0xFC: /* unk_FC - disable interrupts/stop timer?? */ case 0xFD: /* unk_FD */ case 0xFE: /* unk_FE - wait for/start timer */ + if (op == 0xFE) + m_icount -= 75000; // TODO: temporary value that makes emulation speed acceptable + logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; diff --git a/src/devices/cpu/hcd62121/hcd62121.h b/src/devices/cpu/hcd62121/hcd62121.h index ff43a2ac1dc..13956e97d3b 100644 --- a/src/devices/cpu/hcd62121/hcd62121.h +++ b/src/devices/cpu/hcd62121/hcd62121.h @@ -70,9 +70,9 @@ private: u8 datasize(u8 op); void read_reg(int size, u8 op1); void write_reg(int size, u8 op1); - void read_regreg(int size, u8 op1, u8 op2, bool op_is_logical); + void read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_regreg(int size, u8 op1, u8 op2); - void read_iregreg(int size, u8 op1, u8 op2); + void read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_iregreg(int size, u8 op1, u8 op2); void write_iregreg2(int size, u8 op1, u8 op2); bool check_cond(u8 op); @@ -82,12 +82,12 @@ private: void set_zh_flag(bool is_zh); void set_cl_flag(bool is_cl); void op_msk(int size); - void op_imsk(int size); void op_and(int size); void op_or(int size); void op_xor(int size); void op_add(int size); void op_addb(int size); + void op_subb(int size); void op_sub(int size); void op_pushw(u16 source); u16 op_popw(); diff --git a/src/devices/cpu/hcd62121/hcd62121d.cpp b/src/devices/cpu/hcd62121/hcd62121d.cpp index b6598127a55..5e76b090782 100644 --- a/src/devices/cpu/hcd62121/hcd62121d.cpp +++ b/src/devices/cpu/hcd62121/hcd62121d.cpp @@ -31,8 +31,9 @@ enum ARG_KLO, /* KO1 - KO8 output lines */ ARG_KHI, /* KO9 - KO14(?) output lines */ ARG_KI, /* K input lines */ - ARG_RS, /* rotate/shift */ - ARG_RS4 /* nibble rotate/shift */ + ARG_S1, /* shift by 1 */ + ARG_S4, /* shift by 4 */ + ARG_S8, /* shift by 8 */ }; struct hcd62121_dasm @@ -46,12 +47,12 @@ struct hcd62121_dasm static const hcd62121_dasm hcd62121_ops[256] = { /* 0x00 */ - { "ro?b", ARG_REG, ARG_RS4 }, { "ro?w", ARG_REG, ARG_RS4 }, - { "ro?q", ARG_REG, ARG_RS4 }, { "ro?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S8 }, { "sh?w", ARG_REG, ARG_S8 }, + { "sh?q", ARG_REG, ARG_S8 }, { "sh?t", ARG_REG, ARG_S8 }, { "mskb", ARG_REGREG, ARG_NONE }, { "mskw", ARG_REGREG, ARG_NONE }, { "mskq", ARG_REGREG, ARG_NONE }, { "mskt", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS4 }, { "sh?w", ARG_REG, ARG_RS4 }, - { "sh?q", ARG_REG, ARG_RS4 }, { "sh?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S4 }, { "sh?w", ARG_REG, ARG_S4 }, + { "sh?q", ARG_REG, ARG_S4 }, { "sh?t", ARG_REG, ARG_S4 }, { "tstb", ARG_REGREG, ARG_NONE }, { "tstw", ARG_REGREG, ARG_NONE }, { "tstq", ARG_REGREG, ARG_NONE }, { "tstt", ARG_REGREG, ARG_NONE }, @@ -62,16 +63,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_REGREG, ARG_NONE }, { "cmpt", ARG_REGREG, ARG_NONE }, { "movb", ARG_REGREG, ARG_NONE }, { "movw", ARG_REGREG, ARG_NONE }, { "movq", ARG_REGREG, ARG_NONE }, { "movt", ARG_REGREG, ARG_NONE }, - { "imskb", ARG_REGREG, ARG_NONE }, { "imskw", ARG_REGREG, ARG_NONE }, - { "imskq", ARG_REGREG, ARG_NONE }, { "imskt", ARG_REGREG, ARG_NONE }, + { "cmpaddb", ARG_REGREG, ARG_NONE }, { "cmpaddw", ARG_REGREG, ARG_NONE }, + { "cmpaddq", ARG_REGREG, ARG_NONE }, { "cmpaddt", ARG_REGREG, ARG_NONE }, /* 0x20 */ - { "ro?b", ARG_REG, ARG_RS }, { "ro?w", ARG_REG, ARG_RS }, - { "ro?q", ARG_REG, ARG_RS }, { "ro?t", ARG_REG, ARG_RS }, + { "shrb", ARG_REG, ARG_S1 }, { "shrw", ARG_REG, ARG_S1 }, + { "shrq", ARG_REG, ARG_S1 }, { "shrt", ARG_REG, ARG_S1 }, { "orb", ARG_REGREG, ARG_NONE }, { "orw", ARG_REGREG, ARG_NONE }, { "orq", ARG_REGREG, ARG_NONE }, { "ort", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS }, { "sh?w", ARG_REG, ARG_RS }, - { "sh?q", ARG_REG, ARG_RS }, { "sh?t", ARG_REG, ARG_RS }, + { "shlb", ARG_REG, ARG_S1 }, { "shlw", ARG_REG, ARG_S1 }, + { "shlq", ARG_REG, ARG_S1 }, { "shlt", ARG_REG, ARG_S1 }, { "andb", ARG_REGREG, ARG_NONE }, { "andw", ARG_REGREG, ARG_NONE }, { "andq", ARG_REGREG, ARG_NONE }, { "andt", ARG_REGREG, ARG_NONE }, @@ -86,12 +87,12 @@ static const hcd62121_dasm hcd62121_ops[256] = { "addq", ARG_REGREG, ARG_NONE }, { "addt", ARG_REGREG, ARG_NONE }, /* 0x40 */ - { "ro?b", ARG_IRG, ARG_RS4 }, { "ro?w", ARG_IRG, ARG_RS4 }, - { "ro?q", ARG_IRG, ARG_RS4 }, { "ro?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S8 }, { "sh?w", ARG_IRG, ARG_S8 }, + { "sh?q", ARG_IRG, ARG_S8 }, { "sh?t", ARG_IRG, ARG_S8 }, { "mskb", ARG_IRGREG, ARG_NONE }, { "mskw", ARG_IRGREG, ARG_NONE }, { "mskq", ARG_IRGREG, ARG_NONE }, { "mskt", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS4 }, { "sh?w", ARG_IRG, ARG_RS4 }, - { "sh?q", ARG_IRG, ARG_RS4 }, { "sh?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S4 }, { "sh?w", ARG_IRG, ARG_S4 }, + { "sh?q", ARG_IRG, ARG_S4 }, { "sh?t", ARG_IRG, ARG_S4 }, { "tstb", ARG_IRGREG, ARG_NONE }, { "tstw", ARG_IRGREG, ARG_NONE }, { "tstq", ARG_IRGREG, ARG_NONE }, { "tstt", ARG_IRGREG, ARG_NONE }, @@ -102,16 +103,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_IRGREG, ARG_NONE }, { "cmpt", ARG_IRGREG, ARG_NONE }, { "movb", ARG_IRGREG, ARG_NONE }, { "movw", ARG_IRGREG, ARG_NONE }, { "movq", ARG_IRGREG, ARG_NONE }, { "movt", ARG_IRGREG, ARG_NONE }, - { "imskb", ARG_IRGREG, ARG_NONE }, { "imskw", ARG_IRGREG, ARG_NONE }, - { "imskq", ARG_IRGREG, ARG_NONE }, { "imskt", ARG_IRGREG, ARG_NONE }, + { "cmpaddb", ARG_IRGREG, ARG_NONE }, { "cmpaddw", ARG_IRGREG, ARG_NONE }, + { "cmpaddq", ARG_IRGREG, ARG_NONE }, { "cmpaddt", ARG_IRGREG, ARG_NONE }, /* 0x60 */ - { "ro?b", ARG_IRG, ARG_RS }, { "ro?w", ARG_IRG, ARG_RS }, - { "ro?q", ARG_IRG, ARG_RS }, { "ro?t", ARG_IRG, ARG_RS }, + { "shrb", ARG_IRG, ARG_S1 }, { "shrw", ARG_IRG, ARG_S1 }, + { "shrq", ARG_IRG, ARG_S1 }, { "shrt", ARG_IRG, ARG_S1 }, { "orb", ARG_IRGREG, ARG_NONE }, { "orw", ARG_IRGREG, ARG_NONE }, { "orq", ARG_IRGREG, ARG_NONE }, { "ort", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS }, { "sh?w", ARG_IRG, ARG_RS }, - { "sh?q", ARG_IRG, ARG_RS }, { "sh?t", ARG_IRG, ARG_RS }, + { "shlb", ARG_IRG, ARG_S1 }, { "shlw", ARG_IRG, ARG_S1 }, + { "shlq", ARG_IRG, ARG_S1 }, { "shlt", ARG_IRG, ARG_S1 }, { "andb", ARG_IRGREG, ARG_NONE }, { "andw", ARG_IRGREG, ARG_NONE }, { "andq", ARG_IRGREG, ARG_NONE }, { "andt", ARG_IRGREG, ARG_NONE }, @@ -132,13 +133,13 @@ static const hcd62121_dasm hcd62121_ops[256] = { "un86?", ARG_NONE, ARG_NONE }, { "un87?", ARG_NONE, ARG_NONE }, { "jump", ARG_A16, ARG_NONE }, { "jump", ARG_A24, ARG_NONE }, { "call", ARG_A16, ARG_NONE }, { "un8b?", ARG_NONE, ARG_NONE }, - { "un8C?", ARG_NONE, ARG_NONE }, { "un8D?", ARG_NONE, ARG_NONE }, + { "bstack_to_dmem", ARG_NONE, ARG_NONE }, { "fstack_to_dmem", ARG_NONE, ARG_NONE }, { "un8E?", ARG_NONE, ARG_NONE }, { "un8F?", ARG_NONE, ARG_NONE }, /* 0x90 */ { "retzh", ARG_NONE, ARG_NONE }, { "retzl", ARG_NONE, ARG_NONE }, { "retc", ARG_NONE, ARG_NONE }, { "retz", ARG_NONE, ARG_NONE }, - { "retzc", ARG_NONE, ARG_NONE }, { "retcl", ARG_NONE, ARG_NONE }, + { "retnzh", ARG_NONE, ARG_NONE }, { "retnzl", ARG_NONE, ARG_NONE }, { "retnc", ARG_NONE, ARG_NONE }, { "retnz", ARG_NONE, ARG_NONE }, { "jump", ARG_IRG, ARG_NONE }, { "un99?", ARG_NONE, ARG_NONE }, { "un9A?", ARG_NONE, ARG_NONE }, { "un9b?", ARG_NONE, ARG_NONE }, @@ -148,11 +149,11 @@ static const hcd62121_dasm hcd62121_ops[256] = /* 0xa0 */ { "jmpzh", ARG_A16, ARG_NONE }, { "jmpzl", ARG_A16, ARG_NONE }, { "jmpc", ARG_A16, ARG_NONE }, { "jmpz", ARG_A16, ARG_NONE }, - { "jmpzc", ARG_A16, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, + { "jmpnzh", ARG_A16, ARG_NONE }, { "jmpnzl", ARG_A16, ARG_NONE }, { "jmpnc", ARG_A16, ARG_NONE }, { "jmpnz", ARG_A16, ARG_NONE }, { "callzh", ARG_A16, ARG_NONE }, { "callzl", ARG_A16, ARG_NONE }, { "callc", ARG_A16, ARG_NONE }, { "callz", ARG_A16, ARG_NONE }, - { "callzc", ARG_A16, ARG_NONE }, { "callcl", ARG_A16, ARG_NONE }, + { "callnzh", ARG_A16, ARG_NONE }, { "callnzl", ARG_A16, ARG_NONE }, { "callnc", ARG_A16, ARG_NONE }, { "callnz", ARG_A16, ARG_NONE }, /* 0xb0 */ @@ -161,9 +162,9 @@ static const hcd62121_dasm hcd62121_ops[256] = { "out", ARG_KHI, ARG_REG }, { "out", ARG_KHI, ARG_I8 }, { "out", ARG_KLO, ARG_REG }, { "out", ARG_KLO, ARG_I8 }, { "unB8?", ARG_NONE, ARG_NONE }, { "unB9?", ARG_I8, ARG_NONE }, - { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl?", ARG_A16, ARG_NONE }, + { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, { "unBC?", ARG_I8, ARG_NONE }, { "unBD?", ARG_NONE, ARG_NONE }, - { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl?", ARG_A16, ARG_NONE }, + { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl", ARG_A16, ARG_NONE }, /* 0xc0 */ { "movb", ARG_REG, ARG_I8 }, { "movw", ARG_REG, ARG_I16 }, @@ -183,7 +184,7 @@ static const hcd62121_dasm hcd62121_ops[256] = { "movb", ARG_F, ARG_REG }, { "movb", ARG_F, ARG_I8 }, { "unDA?", ARG_NONE, ARG_NONE }, { "unDb?", ARG_NONE, ARG_NONE }, { "movb", ARG_DS, ARG_REG }, { "movb", ARG_DS, ARG_I8 }, - { "movw", ARG_LAR, ARG_REG }, { "movw?", ARG_LAR, ARG_I8 }, + { "movw", ARG_LAR, ARG_REG }, { "movb", ARG_LAR, ARG_I8 }, /* 0xe0 */ { "in0", ARG_REG, ARG_NONE }, { "movb", ARG_REG, ARG_OPT }, @@ -220,7 +221,7 @@ CPU_DISASSEMBLE(hcd62121) inst = &hcd62121_ops[op]; /* Special cases for shift and rotate instructions */ - if (inst->arg2 == ARG_RS || inst->arg2 == ARG_RS4) + if (inst->arg2 == ARG_S4 || inst->arg2 == ARG_S8) util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (oprom[pos] & 0x80) ? 'r' : 'l', inst->str[3]); else util::stream_format(stream, "%-8s", inst->str); @@ -324,8 +325,16 @@ CPU_DISASSEMBLE(hcd62121) op2 = oprom[pos++]; if ((op1 & 0x80) || (op2 & 0x80)) { - /* (lar),reg */ - util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + if (op1 & 0x80) + { + /* (lar),imm */ + util::stream_format(stream, "(%slar%s), %02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2); + } + else + { + /* (lar),reg */ + util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + } } else { @@ -441,9 +450,12 @@ CPU_DISASSEMBLE(hcd62121) case ARG_KI: util::stream_format(stream, ",KI"); break; - case ARG_RS4: + case ARG_S4: util::stream_format(stream, ",4"); break; + case ARG_S8: + util::stream_format(stream, ",8"); + break; default: break; } diff --git a/src/mame/drivers/cfx9850.cpp b/src/mame/drivers/cfx9850.cpp index 945f2df348b..f94172d285b 100644 --- a/src/mame/drivers/cfx9850.cpp +++ b/src/mame/drivers/cfx9850.cpp @@ -158,7 +158,7 @@ static INPUT_PORTS_START(cfx9850) PORT_START("KO2") /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXE Enter") PORT_CODE(KEYCODE_ENTER) - /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(-) Ares") PORT_CODE(KEYCODE_MINUS) + /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(-) Ans") PORT_CODE(KEYCODE_MINUS) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXP Pi") PORT_CODE(KEYCODE_EQUALS) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(". SPACE") PORT_CODE(KEYCODE_SPACE) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 Z") PORT_CODE(KEYCODE_Z) @@ -181,37 +181,37 @@ static INPUT_PORTS_START(cfx9850) PORT_BIT(0x83, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO5") - /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL DG") PORT_CODE(KEYCODE_BACKSPACE) + /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL INS") PORT_CODE(KEYCODE_BACKSPACE) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 O") PORT_CODE(KEYCODE_O) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 N") PORT_CODE(KEYCODE_N) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 M") PORT_CODE(KEYCODE_M) PORT_BIT(0x87, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO6") - /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB L") PORT_CODE(KEYCODE_L) + /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-> L") PORT_CODE(KEYCODE_L) /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(", K") PORT_CODE(KEYCODE_K) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(") x^-1 J") PORT_CODE(KEYCODE_J) - /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("( .. I") PORT_CODE(KEYCODE_I) - /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F<=>0 H") PORT_CODE(KEYCODE_H) + /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("( x^(1/3) I") PORT_CODE(KEYCODE_I) + /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F<=>D H") PORT_CODE(KEYCODE_H) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("a b/c G") PORT_CODE(KEYCODE_G) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO7") /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("tan tan^-1 F") PORT_CODE(KEYCODE_F) - /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("cos cas^-1 E") PORT_CODE(KEYCODE_E) + /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("cos cos^-1 E") PORT_CODE(KEYCODE_E) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("sin sin^-1 D") PORT_CODE(KEYCODE_D) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ln e^x C") PORT_CODE(KEYCODE_C) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("log 10^x B") PORT_CODE(KEYCODE_B) - /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x,d,t A") PORT_CODE(KEYCODE_A) + /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x,theta,t A") PORT_CODE(KEYCODE_A) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO8") /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXIT QUIT") PORT_CODE(KEYCODE_STOP) - /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/\\ .. ..") PORT_CODE(KEYCODE_COMMA) - /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x^2 sqrt ..") PORT_CODE(KEYCODE_SLASH) - /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALPHA ..-LOCK") PORT_CODE(KEYCODE_CAPSLOCK) + /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("^ root theta") PORT_CODE(KEYCODE_COMMA) + /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x^2 sqrt ro") PORT_CODE(KEYCODE_SLASH) + /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALPHA ALPHA-LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO9") -- cgit v1.2.3