summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ricardo Barreira <rbarreira@gmail.com>2017-11-20 23:07:21 +0000
committer Ricardo Barreira <rbarreira@gmail.com>2017-11-20 23:07:21 +0000
commitc5099540fd54ab4c824f5bc5266492196a69135f (patch)
treecd2d71908eb4441527f3757f3a85c2eb654a3853
parent47c1dda4eb97c3fe097e51f700f06ce85488fd49 (diff)
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.
-rw-r--r--src/devices/cpu/hcd62121/hcd62121.cpp604
-rw-r--r--src/devices/cpu/hcd62121/hcd62121.h6
-rw-r--r--src/devices/cpu/hcd62121/hcd62121d.cpp78
-rw-r--r--src/mame/drivers/cfx9850.cpp20
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")