summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/xa
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/xa')
-rw-r--r--src/devices/cpu/xa/xa.cpp2592
-rw-r--r--src/devices/cpu/xa/xa.h926
-rw-r--r--src/devices/cpu/xa/xa_ops.cpp1893
-rw-r--r--src/devices/cpu/xa/xadasm.cpp164
-rw-r--r--src/devices/cpu/xa/xadasm.h6
5 files changed, 5474 insertions, 107 deletions
diff --git a/src/devices/cpu/xa/xa.cpp b/src/devices/cpu/xa/xa.cpp
index ab1ccf34dfb..e02344e4ac1 100644
--- a/src/devices/cpu/xa/xa.cpp
+++ b/src/devices/cpu/xa/xa.cpp
@@ -14,40 +14,262 @@
#include "xa.h"
#include "xadasm.h"
-DEFINE_DEVICE_TYPE(XA, xa_cpu_device, "xa", "Philips 80c51 XA")
-DEFINE_DEVICE_TYPE(MX10EXA, mx10exa_cpu_device, "mx10exa", "Philips MX10EXA")
-
-
+#define LOG_DEBUG (1U << 1)
+#define VERBOSE (0)
+#include "logmacro.h"
+DEFINE_DEVICE_TYPE(XA, xa_cpu, "xa", "Philips 80c51 XA")
+DEFINE_DEVICE_TYPE(MX10EXA, mx10exa_cpu_device, "mx10exa", "Philips MX10EXA")
-xa_cpu_device::xa_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor prg_map)
+xa_cpu::xa_cpu(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor prg_map, address_map_constructor dat_map)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_program_config("data", ENDIANNESS_LITTLE, 16, 24, 0, prg_map)
+ , m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0, prg_map)
+ , m_data_config("data", ENDIANNESS_LITTLE, 16, 24, 0, dat_map)
+ , m_sfr_config("sfr", ENDIANNESS_LITTLE, 8, 11, 0, address_map_constructor(FUNC(xa_cpu::sfr_map), this))
, m_pc(0)
, m_program(nullptr)
+ , m_data(nullptr)
+ , m_sfr(nullptr)
, m_icount(0)
+ , m_port_in_cb(*this, 0xff)
+ , m_port_out_cb(*this)
{
+ add_names(default_names);
}
-xa_cpu_device::xa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : xa_cpu_device(mconfig, XA, tag, owner, clock, address_map_constructor(FUNC(xa_cpu_device::internal_map), this))
+xa_cpu::xa_cpu(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : xa_cpu(mconfig, XA, tag, owner, clock, address_map_constructor(FUNC(xa_cpu::internal_map), this), address_map_constructor(FUNC(xa_cpu::internal_data_map), this))
{
}
mx10exa_cpu_device::mx10exa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : xa_cpu_device(mconfig, MX10EXA, tag, owner, clock, address_map_constructor(FUNC(mx10exa_cpu_device::mx10exa_internal_map), this))
+ : xa_cpu(mconfig, MX10EXA, tag, owner, clock, address_map_constructor(FUNC(mx10exa_cpu_device::mx10exa_internal_map), this), address_map_constructor(FUNC(mx10exa_cpu_device::mx10exa_internal_data_map), this))
{
}
-std::unique_ptr<util::disasm_interface> xa_cpu_device::create_disassembler()
+std::unique_ptr<util::disasm_interface> xa_cpu::create_disassembler()
{
return std::make_unique<xa_dasm>();
}
/*****************************************************************************/
-void xa_cpu_device::internal_map(address_map &map)
+u8 xa_cpu::sfr_port_r(offs_t offset)
+{
+ return m_port_in_cb[offset]();
+}
+
+void xa_cpu::sfr_port_w(offs_t offset, u8 data)
+{
+ m_port_out_cb[offset](data);
+}
+
+u8 xa_cpu::sfr_PxCFGA_r(offs_t offset)
+{
+ return m_PxCFGA[offset];
+}
+
+void xa_cpu::sfr_PxCFGA_w(offs_t offset, u8 data)
+{
+ LOGMASKED(LOG_DEBUG, "P%d CFGA - Port Configuration A write %02x\n", offset, data);
+ m_PxCFGA[offset] = data;
+}
+
+u8 xa_cpu::sfr_PxCFGB_r(offs_t offset)
+{
+ return m_PxCFGB[offset];
+}
+
+void xa_cpu::sfr_PxCFGB_w(offs_t offset, u8 data)
+{
+ LOGMASKED(LOG_DEBUG, "P%d CFGB - Port Configuration B write %02x\n", offset, data);
+ m_PxCFGB[offset] = data;
+}
+
+
+
+void xa_cpu::set_pc_in_current_page(u16 addr)
+{
+ m_pc = addr;
+}
+
+u8 xa_cpu::sfr_WDCON_r()
+{
+ return m_WDCON;
+}
+
+// PSWL C AC - - - V N Z
+u8 xa_cpu::sfr_PSWL_r()
+{
+ u8 ret = m_PSWL & 0x38;
+ if (get_z_flag()) ret |= 0x01;
+ if (get_n_flag()) ret |= 0x02;
+ if (get_v_flag()) ret |= 0x04;
+ if (get_ac_flag()) ret |= 0x40;
+ if (get_c_flag()) ret |= 0x80;
+ LOGMASKED(LOG_DEBUG, "read %02x from PSWL\n", ret);
+ return ret;
+}
+
+void xa_cpu::sfr_PSWL_w(u8 data)
+{
+ LOGMASKED(LOG_DEBUG, "write %02x to PSWL\n", data);
+ m_PSWL = data;
+ if (data & 0x01) set_z_flag(); else clear_z_flag();
+ if (data & 0x02) set_n_flag(); else clear_n_flag();
+ if (data & 0x04) set_v_flag(); else clear_v_flag();
+ if (data & 0x40) set_ac_flag(); else clear_ac_flag();
+ if (data & 0x80) set_c_flag(); else clear_c_flag();
+}
+
+u8 xa_cpu::sfr_PSWH_r()
+{
+ u8 ret = m_PSWH;
+ LOGMASKED(LOG_DEBUG, "read %02x from PSWH\n", ret);
+ return m_PSWH;
+}
+
+void xa_cpu::sfr_PSWH_w(u8 data)
+{
+ // PSWH SM TM RS1 RS0 IM3 IM2 IM1 IM0
+ LOGMASKED(LOG_DEBUG, "write %02x to PSWH\n", data);
+ m_PSWH = data;
+
+ if (m_PSWH & 0x80)
+ m_usermode = false;
+ else
+ m_usermode = true;
+
+ m_regbank = (m_PSWH & 0x30) >> 4;
+
+}
+
+void xa_cpu::sfr_PSW51_w(u8 data)
+{
+ // PSW51 C AC F0 RS1 RS0 OV F1 P
+
+}
+
+u8 xa_cpu::sfr_IEL_r()
+{
+ return m_IEL;
+}
+
+void xa_cpu::sfr_IEL_w(u8 data)
+{
+ m_IEL = data;
+ LOGMASKED(LOG_DEBUG, "write to m_IEL %02x\n", data);
+}
+
+void xa_cpu::sfr_SCR_w(u8 data)
+{
+ /* System Configuration Register (SCR)
+
+ ---- PPCZ
+
+ PP = PT0/1: Peripheral timer multiplier
+ C = CM: 80c51 Compatibility Mode (registers appear in data memory, indirect addressing behavior changed)
+ Z = Page Zero / Small Memory mode (only 16-bits of address are pushed / pulled from stack, faster timing on those ops)
+
+ */
+
+ LOGMASKED(LOG_DEBUG, "write %02x to SCR\n", data);
+ m_SCR = data;
+ m_pagezeromode = (data & 1);
+}
+
+void xa_cpu::sfr_WFEED1_w(u8 data)
+{
+ LOGMASKED(LOG_DEBUG, "write %02x to WFEED1\n", data);
+}
+
+void xa_cpu::sfr_WFEED2_w(u8 data)
+{
+ LOGMASKED(LOG_DEBUG, "write %02x to WFEED2\n", data);
+}
+
+/*****************************************************************************/
+
+void xa_cpu::data_map(address_map &map)
+{
+}
+
+void xa_cpu::sfr_map(address_map &map)
+{
+ map(0x000, 0x000).rw(FUNC(xa_cpu::sfr_PSWL_r), FUNC(xa_cpu::sfr_PSWL_w));
+ map(0x001, 0x001).rw(FUNC(xa_cpu::sfr_PSWH_r), FUNC(xa_cpu::sfr_PSWH_w));
+ map(0x002, 0x002).w(FUNC(xa_cpu::sfr_PSW51_w));
+
+ //0x003, "SSEL"
+ //0x004, "PCON"
+ //0x010, "TCON"
+ //0x011, "TSTAT"
+ //0x018, "T2CON"
+ //0x019, "T2MOD"
+
+ map(0x01f, 0x01f).r(FUNC(xa_cpu::sfr_WDCON_r));
+
+ //0x020, "S0CON"
+ //0x021, "S0STAT"
+ //0x024, "S1CON"
+ //0x025, "S1STAT"
+
+ map(0x026, 0x026).rw(FUNC(xa_cpu::sfr_IEL_r), FUNC(xa_cpu::sfr_IEL_w));
+
+ //0x027, "IEH"
+ //0x02A, "SWR"
+
+ map(0x030, 0x033).rw(FUNC(xa_cpu::sfr_port_r), FUNC(xa_cpu::sfr_port_w));
+
+ map(0x040, 0x040).w(FUNC(xa_cpu::sfr_SCR_w));
+
+ //0x041, "DS"
+ //0x042, "ES"
+ //0x043, "CS"
+
+ //0x050, "TL0"
+ //0x051, "TH0"
+ //0x052, "TL1"
+ //0x053, "TH1"
+ //0x054, "RTL0"
+ //0x055, "RTH0"
+ //0x056, "RTL1"
+ //0x057, "RTH1"
+ //0x058, "TL2"
+ //0x059, "TH2"
+ //0x05A, "T2CAPL"
+ //0x05B, "T2CAPH"
+ //0x05C, "TMOD"
+
+ map(0x05d, 0x05d).w(FUNC(xa_cpu::sfr_WFEED1_w));
+ map(0x05e, 0x05e).w(FUNC(xa_cpu::sfr_WFEED2_w));
+
+ //0x05F, "WDL"
+ //0x060, "S0BUF"
+ //0x061, "S0ADDR"
+ //0x062, "S0ADEN"
+ //0x064, "S1BUF"
+ //0x065, "S1ADDR"
+ //0x066, "S1ADEN"
+ //0x068, "BTRL"
+ //0x069, "BTRH"
+ //0x06A, "BCR"
+
+ map(0x070, 0x073).rw(FUNC(xa_cpu::sfr_PxCFGA_r), FUNC(xa_cpu::sfr_PxCFGA_w));
+
+ //0x07A, "SWE"
+ //0x0A0, "IPA0"
+ //0x0A1, "IPA1"
+ //0x0A2, "IPA2"
+ //0x0A3, "IPA3"
+ //0x0A4, "IPA4"
+ //0x0A5, "IPA5"
+
+ map(0x0f0, 0x0f3).rw(FUNC(xa_cpu::sfr_PxCFGB_r), FUNC(xa_cpu::sfr_PxCFGB_w));
+}
+
+void xa_cpu::internal_map(address_map &map)
{
}
@@ -56,41 +278,2373 @@ void mx10exa_cpu_device::mx10exa_internal_map(address_map &map)
map(0x000000, 0x00ffff).rom();
}
+void xa_cpu::internal_data_map(address_map &map)
+{
+}
+
+void mx10exa_cpu_device::mx10exa_internal_data_map(address_map &map)
+{
+ map(0x000000, 0x0007ff).ram();
+}
+
+
-device_memory_interface::space_config_vector xa_cpu_device::memory_space_config() const
+device_memory_interface::space_config_vector xa_cpu::memory_space_config() const
{
return space_config_vector {
- std::make_pair(AS_PROGRAM, &m_program_config)
+ std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config),
+ std::make_pair(AS_IO, &m_sfr_config)
};
}
+/*****************************************************************************/
+
+const xa_cpu::op_func xa_cpu::s_instruction[256] =
+{
+// group 0
+&xa_cpu::e_nop, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_push_rlist,
+&xa_cpu::e_bitgroup, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_add, &xa_cpu::e_push_rlist,
+// group 1
+&xa_cpu::e_illegal, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_pushu_rlist,
+&xa_cpu::e_illegal, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_addc, &xa_cpu::e_pushu_rlist,
+// group 2
+&xa_cpu::e_illegal, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_pop_rlist,
+&xa_cpu::e_illegal, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_sub, &xa_cpu::e_pop_rlist,
+// group 3
+&xa_cpu::e_illegal, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_popu_rlist,
+&xa_cpu::e_illegal, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_subb, &xa_cpu::e_popu_rlist,
+// group 4
+&xa_cpu::e_lea_offset8, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_push_rlist,
+&xa_cpu::e_lea_offset16, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_cmp, &xa_cpu::e_push_rlist,
+// group 5
+&xa_cpu::e_xch_type1, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_pushu_rlist,
+&xa_cpu::e_xch_type1, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_and, &xa_cpu::e_pushu_rlist,
+// group 6
+&xa_cpu::e_xch_type2, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_pop_rlist,
+&xa_cpu::e_xch_type2, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_or, &xa_cpu::e_pop_rlist,
+// group 7
+&xa_cpu::e_illegal, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_popu_rlist,
+&xa_cpu::e_illegal, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_xor, &xa_cpu::e_popu_rlist,
+// group 8
+&xa_cpu::e_movc_rd_rsinc,&xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_pushpop_djnz_subgroup,
+&xa_cpu::e_movc_rd_rsinc,&xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_mov, &xa_cpu::e_pushpop_djnz_subgroup,
+// group 9
+&xa_cpu::e_g9_subgroup, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_jb_mov_subgroup,
+&xa_cpu::e_g9_subgroup, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_alu, &xa_cpu::e_jb_mov_subgroup,
+// group a
+&xa_cpu::e_movdir, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_movx_subgroup,
+&xa_cpu::e_movdir, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_adds, &xa_cpu::e_movx_subgroup,
+// group b
+&xa_cpu::e_rr, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_rrc,
+&xa_cpu::e_rr, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_movs, &xa_cpu::e_rrc,
+// group c
+&xa_cpu::e_lsr_fc, &xa_cpu::e_asl_c, &xa_cpu::e_asr_c, &xa_cpu::e_norm, &xa_cpu::e_lsr_fc, &xa_cpu::e_asl_c, &xa_cpu::e_asr_c, &xa_cpu::e_norm,
+&xa_cpu::e_lsr_fc, &xa_cpu::e_asl_c, &xa_cpu::e_asr_c, &xa_cpu::e_norm, &xa_cpu::e_lsr_fc, &xa_cpu::e_asl_c, &xa_cpu::e_asr_c, &xa_cpu::e_norm,
+// group d
+&xa_cpu::e_lsr_fj, &xa_cpu::e_asl_j, &xa_cpu::e_asr_j, &xa_cpu::e_rl, &xa_cpu::e_lsr_fj, &xa_cpu::e_asl_j, &xa_cpu::e_asr_j, &xa_cpu::e_rlc,
+&xa_cpu::e_lsr_fj, &xa_cpu::e_asl_j, &xa_cpu::e_asr_j, &xa_cpu::e_rl, &xa_cpu::e_lsr_fj, &xa_cpu::e_asl_j, &xa_cpu::e_asr_j, &xa_cpu::e_rlc,
+// group e
+&xa_cpu::e_mulu_b, &xa_cpu::e_divu_b, &xa_cpu::e_djnz_cjne, &xa_cpu::e_cjne_d8, &xa_cpu::e_mulu_w, &xa_cpu::e_divu_w, &xa_cpu::e_mul_w, &xa_cpu::e_div_w,
+&xa_cpu::e_div_data8, &xa_cpu::e_div_d16, &xa_cpu::e_djnz_cjne, &xa_cpu::e_cjne_d16, &xa_cpu::e_jz_rel8, &xa_cpu::e_divu_d, &xa_cpu::e_jnz_rel8, &xa_cpu::e_div_d,
+// group f
+&xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch,
+&xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_branch, &xa_cpu::e_bkpt,
+};
+
+// SFR names
+const xa_cpu::mem_info xa_cpu::default_names[] = {
+ // the following are bit addressable
+ { 0x400, "PSWL" },
+ { 0x401, "PSWH" },
+ { 0x402, "PSW51" },
+ { 0x403, "SSEL" },
+ { 0x404, "PCON" },
+ { 0x410, "TCON" },
+ { 0x411, "TSTAT" },
+ { 0x418, "T2CON" },
+ { 0x419, "T2MOD" },
+ { 0x41F, "WDCON" },
+ { 0x420, "S0CON" },
+ { 0x421, "S0STAT" },
+ { 0x424, "S1CON" },
+ { 0x425, "S1STAT" },
+ { 0x426, "IEL" },
+ { 0x427, "IEH" },
+ { 0x42A, "SWR" },
+ { 0x430, "P0" },
+ { 0x431, "P1" },
+ { 0x432, "P2" },
+ { 0x433, "P3" },
+ { 0x440, "SCR" },
+ { 0x441, "DS" },
+ { 0x442, "ES" },
+ { 0x443, "CS" },
+ { 0x450, "TL0" },
+ { 0x451, "TH0" },
+ { 0x452, "TL1" },
+ { 0x453, "TH1" },
+ { 0x454, "RTL0" },
+ { 0x455, "RTH0" },
+ { 0x456, "RTL1" },
+ { 0x457, "RTH1" },
+ { 0x458, "TL2" },
+ { 0x459, "TH2" },
+ { 0x45A, "T2CAPL" },
+ { 0x45B, "T2CAPH" },
+ { 0x45C, "TMOD" },
+ { 0x45D, "WFEED1" },
+ { 0x45E, "WFEED2" },
+ { 0x45F, "WDL" },
+ { 0x460, "S0BUF" },
+ { 0x461, "S0ADDR" },
+ { 0x462, "S0ADEN" },
+ { 0x464, "S1BUF" },
+ { 0x465, "S1ADDR" },
+ { 0x466, "S1ADEN" },
+ { 0x468, "BTRL" },
+ { 0x469, "BTRH" },
+ { 0x46A, "BCR" },
+ { 0x470, "P0CFGA" },
+ { 0x471, "P1CFGA" },
+ { 0x472, "P2CFGA" },
+ { 0x473, "P3CFGA" },
+ { 0x47A, "SWE" },
+ { 0x4A0, "IPA0" },
+ { 0x4A1, "IPA1" },
+ { 0x4A2, "IPA2" },
+ { 0x4A3, "IPA3" },
+ { 0x4A4, "IPA4" },
+ { 0x4A5, "IPA5" },
+ { 0x4F0, "P0CFGB" },
+ { 0x4F1, "P1CFGB" },
+ { 0x4F2, "P2CFGB" },
+ { 0x4F3, "P3CFGB" },
+ { -1 }
+};
+
+void xa_cpu::add_names(const mem_info *info)
+{
+ for(unsigned int i=0; info[i].addr >= 0; i++)
+ m_names[info[i].addr] = info[i].name;
+}
+
+u16 xa_cpu::expand_rel16(u16 rel16)
+{
+ int address = m_pc + ((s16)rel16) * 2;
+ address &= ~1; // must be word aligned
+ return address;
+}
+
+u16 xa_cpu::expand_rel8(u8 rel8)
+{
+ int address = m_pc + ((s8)rel8) * 2;
+ address &= ~1; // must be word aligned
+ return address;
+}
+
+
+void xa_cpu::do_nz_flags_16(u16 data)
+{
+ if (data & 0x8000)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ if (data == 0x0000)
+ set_z_flag();
+ else
+ clear_z_flag();
+}
+
+
+void xa_cpu::do_nz_flags_8(u8 data)
+{
+ if (data & 0x80)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ if (data == 0x00)
+ set_z_flag();
+ else
+ clear_z_flag();
+}
+
+void xa_cpu::push_word_to_user_stack(u16 data)
+{
+ // should use the segment register as well!
+ m_USP -= 2;
+ m_data->write_word(m_USP, data);
+}
+
+void xa_cpu::push_word_to_system_stack(u16 data)
+{
+ m_SSP -= 2;
+ m_data->write_word(m_SSP, data);
+}
+
+void xa_cpu::push_word_to_stack(u16 data)
+{
+ if (m_usermode)
+ {
+ push_word_to_user_stack(data);
+ }
+ else
+ {
+ push_word_to_system_stack(data);
+ }
+}
+
+u16 xa_cpu::pull_word_from_user_stack()
+{
+ // should use the segment register as well!
+ u16 data = m_data->read_word(m_USP);
+ m_USP += 2;
+ return data;
+}
+
+u16 xa_cpu::pull_word_from_system_stack()
+{
+ u16 data = m_data->read_word(m_SSP);
+ m_SSP += 2;
+ return data;
+}
+
+
+u16 xa_cpu::pull_word_from_stack()
+{
+ if (m_usermode)
+ {
+ return pull_word_from_user_stack();
+ }
+ else
+ {
+ return pull_word_from_system_stack();
+ }
+}
+
+void xa_cpu::push_byte_to_user_stack(u8 data)
+{
+ // should use the segment register as well!
+ m_USP -= 2;
+ m_data->write_byte(m_USP, data);
+}
+
+void xa_cpu::push_byte_to_system_stack(u8 data)
+{
+ m_SSP -= 2;
+ m_data->write_byte(m_SSP, data);
+}
+
+void xa_cpu::push_byte_to_stack(u16 data)
+{
+ if (m_usermode)
+ {
+ push_byte_to_user_stack(data);
+ }
+ else
+ {
+ push_byte_to_system_stack(data);
+ }
+}
+
+u8 xa_cpu::pull_byte_from_user_stack()
+{
+ // should use the segment register as well!
+ u8 data = m_data->read_byte(m_USP);
+ m_USP += 2;
+ return data;
+}
+
+u8 xa_cpu::pull_byte_from_system_stack()
+{
+ u8 data = m_data->read_byte(m_SSP);
+ m_SSP += 2;
+ return data;
+}
+
+u8 xa_cpu::pull_byte_from_stack()
+{
+ if (m_usermode)
+ {
+ return pull_byte_from_user_stack();
+ }
+ else
+ {
+ return pull_byte_from_system_stack();
+ }
+}
+
+
+u8 xa_cpu::gr8(int reg)
+{
+ int high = reg & 1;
+
+ reg >>= 1;
+
+ if (reg < 4)
+ {
+ // banked regs
+ int regbank = m_regbank;
+
+ if (high)
+ return (m_regs[(regbank * 4) + reg] & 0xff00) >> 8;
+ else
+ return (m_regs[(regbank * 4) + reg] & 0x00ff) >> 0;
+ }
+ else
+ {
+ if (reg == 7)
+ {
+ fatalerror("gr8 on register R7\n");
+ return 0;
+ }
+
+ reg -= 4;
+ if (high)
+ return (m_regs[(4 * 4) + reg] & 0xff00) >> 8;
+ else
+ return (m_regs[(4 * 4) + reg] & 0x00ff) >> 0;
+ }
+}
+
+void xa_cpu::sr8(int reg, u8 data)
+{
+ int high = reg & 1;
+
+ reg >>= 1;
+
+ if (reg < 4)
+ {
+ // banked regs
+ int regbank = m_regbank;
+
+ if (high)
+ m_regs[(regbank * 4) + reg] = (m_regs[(regbank * 4) + reg] & 0x00ff) | (data << 8);
+ else
+ m_regs[(regbank * 4) + reg] = (m_regs[(regbank * 4) + reg] & 0xff00) | (data << 0);
+ }
+ else
+ {
+ if (reg == 7)
+ {
+ fatalerror("sr8 on register R7\n");
+ }
+
+ reg -= 4;
+ if (high)
+ m_regs[(4 * 4) + reg] = (m_regs[(4 * 4) + reg] & 0x00ff) | (data << 8);
+ else
+ m_regs[(4 * 4) + reg] = (m_regs[(4 * 4) + reg] & 0xff00) | (data << 0);
+ }
+}
+
+
+void xa_cpu::sr16(int reg, u16 data)
+{
+ if (reg < 4)
+ {
+ // banked regs
+ int regbank = m_regbank;
+ m_regs[(regbank * 4) + reg] = data;
+
+ }
+ else if (reg < 8)
+ {
+ if (reg == 7)
+ {
+ // R7 is the stack pointer, which switches between USP and SSP depending on mode
+ if (m_usermode)
+ m_USP = data;
+ else
+ m_SSP = data;
+
+ return;
+ }
+
+ // do we need to calculate parity bit (in PSW51) on all R4 writes (as R4 as backwards compatibility with accumulator)
+ // or only when the backwards compatible instructions are used? (for now, simply ignore it)
+ reg -= 4;
+ m_regs[(4 * 4) + reg] = data;
+ }
+ else
+ {
+ fatalerror("sr16 with reg %d val = %04x\n", reg, data);
+ }
+}
+
+u16 xa_cpu::gr16(int reg)
+{
+ if (reg < 4)
+ {
+ // banked regs
+ int regbank = m_regbank;
+ return m_regs[(regbank * 4) + reg];
+
+ }
+ else if (reg < 8)
+ {
+ if (reg == 7)
+ {
+ // R7 is the stack pointer, which switches between USP and SSP depending on mode
+ if (m_usermode)
+ return m_USP;
+ else
+ return m_SSP;
+ }
+
+ // do we need to calculate parity bit (in PSW51) on all R4 writes (as R4 as backwards compatibility with accumulator)
+ // or only when the backwards compatible instructions are used? (for now, simply ignore it)
+ reg -= 4;
+ return m_regs[(4 * 4) + reg];
+ }
+ else
+ {
+ fatalerror("gr16 with reg %d\n", reg);
+ return 0;
+ }
+}
+
+void xa_cpu::wdat8(int address, u8 data)
+{
+ m_data->write_byte(address, data);
+}
+
+void xa_cpu::wdat16(int address, u16 data)
+{
+ if (address & 1)
+ fatalerror("unaligned in wdat16\n");
+
+ m_data->write_word(address, data);
+}
+
+
+u8 xa_cpu::rdat8(int address)
+{
+ return m_data->read_byte(address);
+}
+
+u16 xa_cpu::rdat16(int address)
+{
+ if (address & 1)
+ fatalerror("unaligned in rdat16\n");
+
+ return m_data->read_word(address);
+}
+
+
+
+void xa_cpu::write_direct16(u16 addr, u16 data)
+{
+ if (addr < 0x400)
+ {
+ if (addr & 1)
+ fatalerror("write_direct16 (odd address) %04x %04x\n", addr, data);
+
+ m_data->write_word(addr, data);
+ }
+ else
+ {
+ fatalerror("write_direct16 (SFR) %04x %04x\n", addr, data);
+ }
+}
+
+void xa_cpu::write_direct8(u16 addr, u8 data)
+{
+ if (addr < 0x400)
+ {
+ m_data->write_byte(addr, data);
+ }
+ else
+ {
+ m_sfr->write_byte(addr - 0x400, data);
+ }
+}
+
+u16 xa_cpu::read_direct16(u16 addr)
+{
+ if (addr < 0x400)
+ {
+ return m_data->read_word(addr);
+ }
+ else
+ {
+ fatalerror("read_direct16 on sfr %03x\n", addr);
+ return 0;
+ }
+ return 0;
+}
+
+u8 xa_cpu::read_direct8(u16 addr)
+{
+ if (addr < 0x400)
+ {
+ return m_data->read_byte(addr);
+ }
+ else
+ {
+ return m_sfr->read_byte(addr - 0x400);
+ }
+ return 0;
+}
+
+std::string xa_cpu::get_data_address(u16 arg) const
+{
+ auto i = m_names.find(arg);
+ if (i == m_names.end())
+ return util::string_format("unk_SFR_%03X", arg);
+ else
+ return i->second;
+}
+
+std::string xa_cpu::get_bittext(int bit)
+{
+ int position = bit & 7;
+
+ if (bit < 0x100)
+ {
+ int reg = ((bit & 0x1ff) >> 3);
+
+ if (reg < 16)
+ return util::string_format("%s.%d", m_regnames8[reg], position);
+ else
+ return util::string_format("ill_REG_%02x.%d", reg, position);
+ }
+ else if (bit < 0x200)
+ {
+ int addr = ((bit & 0x1ff) >> 3) + 0x20;
+ return util::string_format("$%02x.%d", addr, position);
+ }
+
+ int sfr = ((bit & 0x1ff) >> 3) + 0x400;
+ return util::string_format("%s.%d", get_data_address(sfr), position);
+}
+
+std::string xa_cpu::get_directtext(int direct)
+{
+ if (direct < 0x400)
+ {
+ return util::string_format("$%03x", direct);
+ }
+
+ return util::string_format("%s", get_data_address(direct));
+}
+
+void xa_cpu::e_illegal(u8 op)
+{
+ fatalerror( "illegal");
+}
+
+void xa_cpu::handle_shift(u8 op, int shift_type)
+{
+ int size = (op & 0x0c) >> 2;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ u8 data, rd;
+ if (size == 0x03)
+ {
+ data = op2 & 0x1f;
+ rd = (op2 & 0xe0) >> 4;
+ }
+ else
+ {
+ data = op2 & 0x0f;
+ rd = (op2 & 0xf0) >> 4;
+ }
+
+ // size == 1 has already been filtered out by the time we get here
+ switch (shift_type)
+ {
+ case 0x0:
+ {
+ if (size == 0) asl_byte_rd_imm4(rd, data);
+ else if (size == 2) asl_word_rd_imm4(rd, data);
+ else if (size == 3) asl_dword_rd_imm5(rd, data);
+ break;
+ }
+ case 0x1:
+ {
+ if (size == 0) asr_byte_rd_imm4(rd, data);
+ else if (size == 2) asr_word_rd_imm4(rd, data);
+ else if (size == 3) asr_dword_rd_imm5(rd, data);
+ break;
+ }
+ case 0x2:
+ {
+ if (size == 0) lsr_byte_rd_imm4(rd, data);
+ else if (size == 2) lsr_word_rd_imm4(rd, data);
+ else if (size == 3) lsr_dword_rd_imm5(rd, data);
+ break;
+ }
+ }
+}
+
+
+void xa_cpu::handle_alu_type0(u8 op, int alu_op)
+{
+ const int size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+
+ switch (op & 0x07)
+ {
+ case 0x01:
+ {
+ const u8 rs = (op2 & 0x0f);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rd_rs(alu_op, rd, rs); } else { aluop_byte_rd_rs(alu_op, rd, rs); }
+ break;
+ }
+
+ case 0x02:
+ {
+ const int optype = op2 & 0x08;
+ if (!optype)
+ {
+ const u8 rs = (op2 & 0x07);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rd_indrs(alu_op, rd, rs); } else { aluop_byte_rd_indrs(alu_op, rd, rs); }
+ }
+ else
+ {
+ const u8 rd = (op2 & 0x07);
+ const u8 rs = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_indrd_rs(alu_op, rd, rs); } else { aluop_byte_indrd_rs(alu_op, rd, rs); }
+ }
+ break;
+ }
+
+ case 0x03:
+ {
+ const int optype = op2 & 0x08;
+ if (!optype)
+ {
+ const u8 rs = (op2 & 0x07);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rd_indrsinc(alu_op, rd, rs); } else { aluop_byte_rd_indrsinc(alu_op, rd, rs); }
+ }
+ else
+ {
+ const u8 rd = (op2 & 0x07);
+ const u8 rs = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_indrdinc_rs(alu_op, rd, rs); } else { aluop_byte_indrdinc_rs(alu_op, rd, rs); }
+ }
+ break;
+ }
+
+ case 0x04:
+ {
+ const int optype = op2 & 0x08;
+ const u8 offset8 = m_program->read_byte(m_pc++);
+ if (!optype)
+ {
+ const u8 rs = (op2 & 0x07);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rd_rsoff8(alu_op, rd, rs, offset8); } else { aluop_byte_rd_rsoff8(alu_op, rd, rs, offset8); }
+ }
+ else
+ {
+ const u8 rd = (op2 & 0x07);
+ const u8 rs = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rdoff8_rs(alu_op, rd, offset8, rs); } else { aluop_byte_rdoff8_rs(alu_op, rd, offset8, rs); }
+ }
+ break;
+ }
+
+ case 0x05:
+ {
+ const int optype = op2 & 0x08;
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const int offset16 = (op3 << 8) | op4;
+ if (!optype)
+ {
+ const u8 rs = (op2 & 0x07);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rsoff16(alu_op, rd, rs, offset16); } else { aluop_byte_rsoff16(alu_op, rd, rs, offset16); }
+ }
+ else
+ {
+ const u8 rd = (op2 & 0x07);
+ const u8 rs = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rdoff16_rs(alu_op, rd, offset16, rs); } else { aluop_byte_rdoff16_rs(alu_op, rd, offset16, rs); }
+ }
+ break;
+ }
+
+ case 0x06:
+ {
+ const int optype = op2 & 0x08;
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u16 direct = ((op2 & 0x07) << 8) | op3;
+ if (!optype)
+ {
+ const u8 rd = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_rd_direct(alu_op, rd, direct); } else { aluop_byte_rd_direct(alu_op, rd, direct); }
+ }
+ else
+ {
+ const u8 rs = (op2 & 0xf0) >> 4;
+ if (size) { aluop_word_direct_rs(alu_op, direct, rs); } else { aluop_byte_direct_rs(alu_op, direct, rs); }
+ }
+ break;
+ }
+
+ }
+}
+
+
+
+void xa_cpu::handle_alu_type1(u8 op, u8 op2)
+{
+ int alu_op = op2 & 0x0f;
+ switch (op & 0x0f)
+ {
+ case 0x01: // ALUOP.b Rd, data8
+ {
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ aluop_byte_rd_data8(alu_op, rd, data8);
+ break;
+ }
+
+ case 0x02: // ALUOP.b [Rd], data8
+ {
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ aluop_byte_indrd_data8(alu_op, rd, data8);
+ break;
+ }
+
+ case 0x03: // ALUOP.b [Rd+], data8
+ {
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ aluop_byte_indrdinc_data8(alu_op, rd, data8);
+ break;
+ }
+
+ case 0x04: // ALUOP.b [Rd+offs8], data8
+ {
+ const u8 offset8 = m_program->read_byte(m_pc++);
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ aluop_byte_rdoff8_data8(alu_op, rd, offset8, data8);
+ break;
+ }
+
+ case 0x05: // ALUOP.b [Rd+offs16], data8
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u16 offset16 = (op3 << 8) | op4;
+ aluop_byte_rdoff16_data8(alu_op, rd, offset16, data8);
+ break;
+ }
+
+ case 0x06: // ALUOP.b DIRECT, data8
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u16 direct = ((op2 & 0xf0) << 4) | op3;
+ aluop_byte_direct_data8(alu_op, direct, data8);
+ break;
+ }
+
+ case 0x09: // ALUOP.w Rd, data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u16 data16 = (op3 << 8) | op4;
+ aluop_byte_rd_data16(alu_op, rd, data16);
+ break;
+ }
+
+ case 0x0a: // ALUOP.w [Rd], data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u16 data16 = (op3 << 8) | op4;
+ aluop_byte_indrd_data16(alu_op, rd, data16);
+ break;
+ }
+
+ case 0x0b: // ALUOP.w [Rd+], data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u16 data16 = (op3 << 8) | op4;
+ aluop_byte_indrdinc_data16(alu_op, rd, data16);
+ break;
+ }
+
+ case 0x0c: // ALPOP.w [Rd+offs8], data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 op5 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const int offset8 = op3;
+ const u16 data16 = (op4 << 8) | op5;
+ aluop_byte_rdoff8_data16(alu_op, rd, offset8, data16);
+ break;
+ }
+
+ case 0x0d: // ALUOP.w [Rd+offs16], data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 op5 = m_program->read_byte(m_pc++);
+ const u8 op6 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const int offset16= (op3 << 8) | op4;
+ const u16 data16 = (op5 << 8) | op6;
+ aluop_byte_rdoff16_data16(alu_op, rd, offset16, data16);
+ break;
+ }
+
+ case 0x0e: // ALUOP.w DIRECT, data16
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 op5 = m_program->read_byte(m_pc++);
+ const u16 direct =( (op2 & 0xf0) << 4) | op3;
+ const u16 data16 = (op4 << 8) | op5;
+ aluop_byte_direct_data16(alu_op, direct, data16);
+ break;
+ }
+ }
+}
+
+std::string xa_cpu::show_expanded_data4(u16 data4, int size)
+{
+ u16 extended = util::sext(data4, 4);
+
+ if (!size)
+ {
+ extended &= 0xff;
+ return util::string_format("#$%02x", extended);
+ }
+
+ return util::string_format("#$%04x", extended);
+}
+
+void xa_cpu::handle_adds_movs(u8 op, int which)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u16 data4 = op2 & 0x0f;
+
+ switch (op & 0x07)
+ {
+ case 0x01:
+ {
+ int rd = (op2 & 0xf0) >> 4;
+ if (which) { if (size) { movs_word_rd_data4(rd, data4); } else { movs_byte_rd_data4(rd, data4); } }
+ else { if (size) { adds_word_rd_data4(rd, data4); } else { adds_byte_rd_data4(rd, data4); } }
+ break;
+ }
+ case 0x02:
+ {
+ int rd = (op2 & 0x70) >> 4;
+ if (which == 1) { if (size) { movs_word_indrd_data4(rd, data4); } else { movs_byte_indrd_data4(rd, data4); } }
+ else { if (size) { adds_word_indrd_data4(rd, data4); } else { adds_byte_indrd_data4(rd, data4); } }
+ break;
+ }
+ case 0x03:
+ {
+ int rd = (op2 & 0x70) >> 4;
+ if (which) { if (size) { movs_word_indrdinc_data4(rd, data4); } else { movs_byte_indrdinc_data4(rd, data4); } }
+ else { if (size) { adds_word_indrdinc_data4(rd, data4); } else { adds_byte_indrdinc_data4(rd, data4); } }
+ break;
+ }
+ case 0x04:
+ {
+ int rd = (op2 & 0x70) >> 4;
+ const u8 off8 = m_program->read_byte(m_pc++);
+ if (which == 1) { if (size) { movs_word_indrdoff8_data4(rd, off8, data4); } else { movs_byte_indrdoff8_data4(rd, off8, data4); } }
+ else { if (size) { adds_word_indrdoff8_data4(rd, off8, data4); } else { adds_byte_indrdoff8_data4(rd, off8, data4); } }
+ break;
+ }
+ case 0x05:
+ {
+ int rd = (op2 & 0x70) >> 4;
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const int off16 = (op3 << 8) | op4;
+ if (which == 1) { if (size) { movs_word_indrdoff16_data4(rd, off16, data4); } else { movs_byte_indrdoff16_data4(rd, off16, data4); } }
+ else { if (size) { adds_word_indrdoff16_data4(rd, off16, data4); } else { adds_byte_indrdoff16_data4(rd, off16, data4); } }
+ break;
+ }
+ case 0x06:
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u16 direct = ((op2 & 0xf0) << 4) | op3;
+ if (which == 1) { if (size) { movs_word_direct_data4(direct, data4); } else { movs_byte_direct_data4(direct, data4); } }
+ else { if (size) { adds_word_direct_data4(direct, data4); } else { adds_byte_direct_data4(direct, data4); } }
+ break;
+ }
+ }
+}
+
+std::string xa_cpu::get_word_reglist(u8 op2)
+{
+ std::string temp;
+
+ bool firstbit = true;
+ for (int i = 0; i < 8; i++)
+ {
+ int bit = (op2 & (1 << i));
+
+ if (bit)
+ {
+ temp += util::string_format("%s%s", firstbit ? "" : ",", m_regnames16[i]);
+ firstbit = false;
+ }
+ }
+ return temp;
+}
+
+std::string xa_cpu::get_byte_reglist(u8 op2, int h)
+{
+ std::string temp;
+
+ bool firstbit = true;
+ for (int i = 0; i < 8; i++)
+ {
+ int bit = (op2 & (1 << i));
+
+ if (bit)
+ {
+ temp += util::string_format("%s%s", firstbit ? "" : ",", m_regnames8[i + (h ? 8 : 0)]);
+ firstbit = false;
+ }
+ }
+ return temp;
+}
+
+void xa_cpu::push_byte_reglist(u8 op2, int h, bool force_user)
+{
+ for (int i = 7; i >= 0; i--)
+ {
+ int bit = (op2 & (1 << i));
+ if (bit)
+ {
+ u8 regval = gr8(i + (h ? 8 : 0));
+ if (force_user)
+ push_byte_to_user_stack(regval);
+ else
+ push_byte_to_stack(regval);
+ cy(2);
+ }
+ }
+}
+
+void xa_cpu::push_word_reglist(u8 op2, int h, bool force_user)
+{
+ // h is unused for word ops?
+ for (int i = 7; i >= 0; i--)
+ {
+ int bit = (op2 & (1 << i));
+ if (bit)
+ {
+ u16 regval = gr16(i);
+ if (force_user)
+ push_word_to_user_stack(regval);
+ else
+ push_word_to_stack(regval);
+ cy(2);
+ }
+ }
+}
+
+void xa_cpu::pull_byte_reglist(u8 op2, int h, bool force_user)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ int bit = (op2 & (1 << i));
+ if (bit)
+ {
+ u8 stackval;
+ if (force_user)
+ stackval = pull_byte_from_user_stack();
+ else
+ stackval = pull_byte_from_stack();
+
+ sr8(i + (h ? 8 : 0), stackval);
+ cy(2);
+ }
+ }
+}
+
+void xa_cpu::pull_word_reglist(u8 op2, int h, bool force_user)
+{
+ // h is unused for word ops?
+ for (int i = 0; i < 8; i++)
+ {
+ int bit = (op2 & (1 << i));
+ if (bit)
+ {
+ u16 stackval;
+ if (force_user)
+ stackval = pull_word_from_user_stack();
+ else
+ stackval = pull_word_from_stack();
+
+ sr16(i, stackval);
+ cy(2);
+ }
+ }
+}
+
+
+void xa_cpu::handle_push_rlist(u8 op)
+{
+ const u8 h = op & 0x40;
+ const u8 size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ if (size) { push_word_rlist(op2, h); } else { push_byte_rlist(op2, h); }
+}
+
+void xa_cpu::handle_pushu_rlist(u8 op)
+{
+ const u8 h = op & 0x40;
+ const u8 size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ if (size) { pushu_word_rlist(op2, h); } else { pushu_byte_rlist(op2, h); }
+}
+
+void xa_cpu::handle_pop_rlist(u8 op)
+{
+ const u8 h = op & 0x40;
+ const u8 size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ if (size) { pop_word_rlist(op2, h); } else { pop_byte_rlist(op2, h); }
+}
+
+void xa_cpu::handle_popu_rlist(u8 op)
+{
+ const u8 h = op & 0x40;
+ const u8 size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ if (size) { popu_word_rlist(op2, h); } else { popu_byte_rlist(op2, h); }
+}
+
+// -------------------------------------- Group 0 --------------------------------------
+
+/*
+NOP No operation 1 3 0000 0000
+*/
+void xa_cpu::e_nop(u8 op)
+{
+ do_nop();
+}
+
+/*
+CLR bit Clear bit 3 4 0000 1000 0000 00bb bbbb bbbb
+SETB bit Sets the bit specified 3 4 0000 1000 0001 00bb bbbb bbbb
+MOV C, bit Move bit to the carry flag 3 4 0000 1000 0010 00bb bbbb bbbb
+MOV bit, C Move carry to bit 3 4 0000 1000 0011 00bb bbbb bbbb
+ANL C, bit Logical AND bit to carry 3 4 0000 1000 0100 00bb bbbb bbbb
+ANL C, /bit Logical AND complement of a bit to carry 3 4 0000 1000 0101 00bb bbbb bbbb
+ORL C, bit Logical OR a bit to carry 3 4 0000 1000 0110 00bb bbbb bbbb
+ORL C, /bit Logical OR complement of a bit to carry 3 4 0000 1000 0111 00bb bbbb bbbb
+*/
+
+void xa_cpu::e_bitgroup(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+
+ u16 bit = ((op2 & 0x03) << 8) | op3;
+
+ switch (op2 & 0xf0)
+ {
+ case 0x00: clr_bit(bit); break;
+ case 0x10: setb_bit(bit); break;
+ case 0x20: mov_c_bit(bit); break;
+ case 0x30: mov_bit_c(bit); break;
+ case 0x40: anl_c_bit(bit); break;
+ case 0x50: anl_c_notbit(bit); break;
+ case 0x60: orl_c_bit(bit); break;
+ case 0x70: orl_c_notbit(bit); break;
+ default: LOGMASKED(LOG_DEBUG, "illegal bit op %s", get_bittext(bit) ); do_nop(); break;
+ }
+ return;
+}
+
+/*
+ADD Rd, Rs Add regs direct 2 3 0000 S001 dddd ssss
+ADD Rd, [Rs] Add reg-ind to reg 2 4 0000 S010 dddd 0sss
+ADD [Rd], Rs Add reg to reg-ind 2 4 0000 S010 ssss 1ddd
+ADD Rd, [Rs+] Add reg-ind w/ autoinc to reg 2 5 0000 S011 dddd 0sss
+ADD [Rd+], Rs Add reg-ind w/ autoinc to reg 2 5 0000 S011 ssss 1ddd
+ADD Rd, [Rs+offset8] Add reg-ind w/ 8-bit offs to reg 3 6 0000 S100 dddd 0sss oooo oooo
+ADD [Rd+offset8], Rs Add reg to reg-ind w/ 8-bit offs 3 6 0000 S100 ssss 1ddd oooo oooo
+ADD Rd, [Rs+offset16] Add reg-ind w/ 16-bit offs to reg 4 6 0000 S101 dddd 0sss oooo oooo oooo oooo
+ADD [Rd+offset16], Rs Add reg to reg-ind w/ 16-bit offs 4 6 0000 S101 ssss 1ddd oooo oooo oooo oooo
+ADD direct, Rs Add reg to mem 3 4 0000 S110 ssss 1DDD DDDD DDDD
+ADD Rd, direct Add mem to reg 3 4 0000 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_add(u8 op)
+{
+ handle_alu_type0(op, 0);
+}
+
+/*
+PUSH Rlist Push regs (b/w) onto the current stack 2 b* 0H00 S111 LLLL LLLL
+*/
+void xa_cpu::e_push_rlist(u8 op)
+{
+ // PUSH
+ handle_push_rlist(op);
+}
+
+// -------------------------------------- Group 1 --------------------------------------
+
+/*
+ADDC Rd, Rs Add regs direct w/ carry 2 3 0001 S001 dddd ssss
+ADDC Rd, [Rs] Add reg-ind to reg w/ carry 2 4 0001 S010 dddd 0sss
+ADDC [Rd], Rs Add reg to reg-ind w/ carry 2 4 0001 S010 ssss 1ddd
+ADDC Rd, [Rs+offset8] Add reg-ind w/ 8-bit offs to reg w/ carry 3 6 0001 S100 dddd 0sss oooo oooo
+ADDC [Rd+offset8], Rs Add reg to reg-ind w/ 8-bit offs w/ carry 3 6 0001 S100 ssss 1ddd oooo oooo
+ADDC Rd, [Rs+offset16] Add reg-ind w/ 16-bit offs to reg w/ carry 4 6 0001 S101 dddd 0sss oooo oooo oooo oooo
+ADDC [Rd+offset16], Rs Add reg to reg-ind w/ 16-bit offs w/ carry 4 6 0001 S101 ssss 1ddd oooo oooo oooo oooo
+ADDC Rd, [Rs+] Add reg-ind w/ autoinc to reg w/ carry 2 5 0001 S011 dddd 0sss
+ADDC [Rd+], Rs Add reg-ind w/ autoinc to reg w/ carry 2 5 0001 S011 ssss 1ddd
+ADDC direct, Rs Add reg to mem w/ carry 3 4 0001 S110 ssss 1DDD DDDD DDDD
+ADDC Rd, direct Add mem to reg w/ carry 3 4 0001 S110 dddd 0DDD DDDD DDDD
+*/
+
+void xa_cpu::e_addc(u8 op)
+{
+ handle_alu_type0(op, 1);
+}
+
+/*
+PUSHU Rlist Push regs (b/w) from the user stack 2 b* 0H01 S111 LLLL LLLL
+*/
+void xa_cpu::e_pushu_rlist(u8 op)
+{
+ // PUSHU
+ handle_pushu_rlist(op);
+}
+
+
+// -------------------------------------- Group 2 --------------------------------------
+
+/*
+SUB Rd, Rs Subtract regs direct 2 3 0010 S001 dddd ssss
+SUB Rd, [Rs] Subtract reg-ind to reg 2 4 0010 S010 dddd 0sss
+SUB [Rd], Rs Subtract reg to reg-ind 2 4 0010 S010 ssss 1ddd
+SUB Rd, [Rs+offset8] Subtract reg-ind w/ 8-bit offs to reg 3 6 0010 S100 dddd 0sss oooo oooo
+SUB [Rd+offset8], Rs Subtract reg to reg-ind w/ 8-bit offs 3 6 0010 S100 ssss 1ddd oooo oooo
+SUB Rd, [Rs+offset16] Subtract reg-ind w/ 16-bit offs to reg 4 6 0010 S101 dddd 0sss oooo oooo oooo oooo
+SUB [Rd+offset16], Rs Subtract reg to reg-ind w/ 16-bit offs 4 6 0010 S101 ssss 1ddd oooo oooo oooo oooo
+SUB Rd, [Rs+] Subtract reg-ind w/ autoinc to reg 2 5 0010 S011 dddd 0sss
+SUB [Rd+], Rs Subtract reg-ind w/ autoinc to reg 2 5 0010 S011 ssss 1ddd
+SUB direct, Rs Subtract reg to mem 3 4 0010 S110 ssss 1DDD DDDD DDDD
+SUB Rd, direct Subtract mem to reg 3 4 0010 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_sub(u8 op)
+{
+ handle_alu_type0(op, 2);
+}
+
+/*
+POP Rlist Pop regs (b/w) from the current stack 2 c* 0H10 S111 LLLL LLLL
+*/
+void xa_cpu::e_pop_rlist(u8 op)
+{
+ // POP
+ handle_pop_rlist(op);
+}
+
+
+// -------------------------------------- Group 3 --------------------------------------
+
+/*
+SUBB Rd, Rs Subtract w/ borrow regs direct 2 3 0011 S001 dddd ssss
+SUBB Rd, [Rs] Subtract w/ borrow reg-ind to reg 2 4 0011 S010 dddd 0sss
+SUBB [Rd], Rs Subtract w/ borrow reg to reg-ind 2 4 0011 S010 ssss 1ddd
+SUBB Rd, [Rs+] Subtract w/ borrow reg-ind w/ autoinc to reg 2 5 0011 S011 dddd 0sss
+SUBB [Rd+], Rs Subtract w/ borrow reg-ind w/ autoinc to reg 2 5 0011 S011 ssss 1ddd
+SUBB Rd, [Rs+offset8] Subtract w/ borrow reg-ind w/ 8-bit offs to reg 3 6 0011 S100 dddd 0sss oooo oooo
+SUBB [Rd+offset8], Rs Subtract w/ borrow reg to reg-ind w/ 8-bit offs 3 6 0011 S100 ssss 1ddd oooo oooo
+SUBB Rd, [Rs+offset16] Subtract w/ borrow reg-ind w/ 16-bit offs to reg 4 6 0011 S101 dddd 0sss oooo oooo oooo oooo
+SUBB [Rd+offset16], Rs Subtract w/ borrow reg to reg-ind w/ 16-bit offs 4 6 0011 S101 ssss 1ddd oooo oooo oooo oooo
+SUBB direct, Rs Subtract w/ borrow reg to mem 3 4 0011 S110 ssss 1DDD DDDD DDDD
+SUBB Rd, direct Subtract w/ borrow mem to reg 3 4 0011 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_subb(u8 op)
+{
+ handle_alu_type0(op, 3);
+}
+
+/*
+POPU Rlist Pop regs (b/w) from the user stack 2 c* 0H11 S111 LLLL LLLL
+*/
+void xa_cpu::e_popu_rlist(u8 op)
+{
+ // POPU
+ handle_popu_rlist(op);
+}
+
+
+// -------------------------------------- Group 4 --------------------------------------
+
+/*
+LEA Rd, Rs+offset8 Load 16-bit effective address w/ 8-bit offs to reg 3 3 0100 0000 0ddd 0sss oooo oooo
+*/
+void xa_cpu::e_lea_offset8(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 offs8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0x70) >> 4;
+ const u8 rs = (op2 & 0x07);
+ lea_word_rd_rs_off8(rd, rs, offs8);
+}
+
+/*
+LEA Rd, Rs+offset16 Load 16-bit effective address w/ 16-bit offs to reg 4 3 0100 1000 0ddd 0sss oooo oooo oooo oooo
+*/
+void xa_cpu::e_lea_offset16(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0x70) >> 4;
+ const u8 rs = (op2 & 0x07);
+ const u16 offs16 = (op3 << 8) | op4;
+ lea_word_rd_rs_off16(rd, rs, offs16);
+}
+
+/*
+CMP Rd, Rs Compare dest and src regs 2 3 0100 S001 dddd ssss
+CMP Rd, [Rs] Compare reg-ind w/ reg 2 4 0100 S010 dddd 0sss
+CMP [Rd], Rs Compare reg w/ reg-ind 2 4 0100 S010 ssss 1ddd
+CMP Rd, [Rs+offset8] Compare reg-ind w/ 8-bit offs w/ reg 3 6 0100 S100 dddd 0sss oooo oooo
+CMP [Rd+offset8], Rs Compare reg w/ reg-ind w/ 8-bit offs 3 6 0100 S100 ssss 1ddd oooo oooo
+CMP Rd, [Rs+offset16] Compare reg-ind w/ 16-bit offs w/ reg 4 6 0100 S101 dddd 0sss oooo oooo oooo oooo
+CMP [Rd+offset16], Rs Compare reg w/ reg-ind w/ 16-bit offs 4 6 0100 S101 ssss 1ddd oooo oooo oooo oooo
+CMP Rd, [Rs+] Compare autoinc reg-ind w/ reg 2 5 0100 S011 dddd 0sss
+CMP [Rd+], Rs Compare reg w/ autoinc reg-ind 2 5 0100 S011 ssss 1ddd
+CMP direct, Rs Compare reg w/ mem 3 4 0100 S110 ssss 1DDD DDDD DDDD
+CMP Rd, direct Compare mem w/ reg 3 4 0100 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_cmp(u8 op)
+{
+ handle_alu_type0(op, 4);
+}
+
+// -------------------------------------- Group 5 --------------------------------------
+
+/*
+XCH Rd, [Rs] Exchange contents of a reg-ind address w/ a reg 2 6 0101 S000 dddd 0sss
+*/
+void xa_cpu::e_xch_type1(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x07);
+
+ if (size) { xch_word_rd_indrs(rd, rs); } else { xch_byte_rd_indrs(rd, rs); }
+}
+
+/*
+AND Rd, Rs Logical AND regs direct 2 3 0101 S001 dddd ssss
+AND Rd, [Rs] Logical AND reg-ind to reg 2 4 0101 S010 dddd 0sss
+AND [Rd], Rs Logical AND reg to reg-ind 2 4 0101 S010 ssss 1ddd
+AND Rd, [Rs+offset8] Logical AND reg-ind w/ 8-bit offs to reg 3 6 0101 S100 dddd 0sss oooo oooo
+AND [Rd+offset8], Rs Logical AND reg to reg-ind w/ 8-bit offs 3 6 0101 S100 ssss 1ddd oooo oooo
+AND Rd, [Rs+offset16] Logical AND reg-ind w/ 16-bit offs to reg 4 6 0101 S101 dddd 0sss oooo oooo oooo oooo
+AND [Rd+offset16], Rs Logical AND reg to reg-ind w/ 16-bit offs 4 6 0101 S101 ssss 1ddd oooo oooo oooo oooo
+AND Rd, [Rs+] Logical AND reg-ind w/ autoinc to reg 2 5 0101 S011 dddd 0sss
+AND [Rd+], Rs Logical AND reg-ind w/ autoinc to reg 2 5 0101 S011 ssss 1ddd
+AND direct, Rs Logical AND reg to mem 3 4 0101 S110 ssss 1DDD DDDD DDDD
+AND Rd, direct Logical AND mem to reg 3 4 0101 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_and(u8 op)
+{
+ handle_alu_type0(op, 5);
+}
+
+// -------------------------------------- Group 6 --------------------------------------
+
+/*
+XCH Rd, Rs Exchange contents of two regs 2 5 0110 S000 dddd ssss
+*/
+void xa_cpu::e_xch_type2(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ if (size) { xch_word_rd_rs(rd, rs); } else { xch_byte_rd_rs(rd, rs); }
+}
+
+/*
+OR Rd, Rs Logical OR regs 2 3 0110 S001 dddd ssss
+OR Rd, [Rs] Logical OR reg-ind to reg 2 4 0110 S010 dddd 0sss
+OR [Rd], Rs Logical OR reg to reg-ind 2 4 0110 S010 ssss 1ddd
+OR Rd, [Rs+offset8] Logical OR reg-ind w/ 8-bit offs to reg 3 6 0110 S100 dddd 0sss oooo oooo
+OR [Rd+offset8], Rs Logical OR reg to reg-ind w/ 8-bit offs 3 6 0110 S100 ssss 1ddd oooo oooo
+OR Rd, [Rs+offset16] Logical OR reg-ind w/ 16-bit offs to reg 4 6 0110 S101 dddd 0sss oooo oooo oooo oooo
+OR [Rd+offset16], Rs Logical OR reg to reg-ind w/ 16-bit offs 4 6 0110 S101 ssss 1ddd oooo oooo oooo oooo
+OR Rd, [Rs+] Logical OR reg-ind w/ autoinc to reg 2 5 0110 S011 dddd 0sss
+OR [Rd+], Rs Logical OR reg-ind w/ autoinc to reg 2 5 0110 S011 ssss 1ddd
+OR direct, Rs Logical OR reg to mem 3 4 0110 S110 ssss 1DDD DDDD DDDD
+OR Rd, direct Logical OR mem to reg 3 4 0110 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_or(u8 op)
+{
+ handle_alu_type0(op, 6);
+}
+
+// -------------------------------------- Group 7 --------------------------------------
+
+/*
+XOR Rd, Rs Logical XOR regs 2 3 0111 S001 dddd ssss
+XOR Rd, [Rs] Logical XOR reg-ind to reg 2 4 0111 S010 dddd 0sss
+XOR [Rd], Rs Logical XOR reg to reg-ind 2 4 0111 S010 ssss 1ddd
+XOR Rd, [Rs+offset8] Logical XOR reg-ind w/ 8-bit offs to reg 3 6 0111 S100 dddd 0sss oooo oooo
+XOR [Rd+offset8], Rs Logical XOR reg to reg-ind w/ 8-bit offs 3 6 0111 S100 ssss 1ddd oooo oooo
+XOR Rd, [Rs+offset16] Logical XOR reg-ind w/ 16-bit offs to reg 4 6 0111 S101 dddd 0sss oooo oooo oooo oooo
+XOR [Rd+offset16], Rs Logical XOR reg to reg-ind w/ 16-bit offs 4 6 0111 S101 ssss 1ddd oooo oooo oooo oooo
+XOR Rd, [Rs+] Logical XOR reg-ind w/ autoinc to reg 2 5 0111 S011 dddd 0sss
+XOR [Rd+], Rs Logical XOR reg-ind w/ autoinc to reg 2 5 0111 S011 ssss 1ddd
+XOR direct, Rs Logical XOR reg to mem 3 4 0111 S110 ssss 1DDD DDDD DDDD
+XOR Rd, direct Logical XOR mem to reg 3 4 0111 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_xor(u8 op)
+{
+ handle_alu_type0(op, 7);
+}
+
+// -------------------------------------- Group 8 --------------------------------------
+
+/*
+MOVC Rd, [Rs+] Move data from WS:Rs address of code mem to reg w/ autoinc 2 4 1000 S000 dddd 0sss
+*/
+void xa_cpu::e_movc_rd_rsinc(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ int rd = (op2 & 0xf0) >> 4;
+ int rs = (op2 & 0x07);
+ if (size) { movc_word_rd_indrsinc(rd, rs); } else { movc_byte_rd_indrsinc(rd, rs); }
+}
+
+/*
+MOV Rd, Rs Move reg to reg 2 3 1000 S001 dddd ssss
+MOV Rd, [Rs] Move reg-ind to reg 2 3 1000 S010 dddd 0sss
+MOV [Rd], Rs Move reg to reg-ind 2 3 1000 S010 ssss 1ddd
+MOV Rd, [Rs+offset8] Move reg-ind w/ 8-bit offs to reg 3 5 1000 S100 dddd 0sss oooo oooo
+MOV [Rd+offset8], Rs Move reg to reg-ind w/ 8-bit offs 3 5 1000 S100 ssss 1ddd oooo oooo
+MOV Rd, [Rs+offset16] Move reg-ind w/ 16-bit offs to reg 4 5 1000 S101 dddd 0sss oooo oooo oooo oooo
+MOV [Rd+offset16], Rs Move reg to reg-ind w/ 16-bit offs 4 5 1000 S101 ssss 1ddd oooo oooo oooo oooo
+MOV Rd, [Rs+] Move reg-ind w/ autoinc to reg 2 4 1000 S011 dddd 0sss
+MOV [Rd+], Rs Move reg-ind w/ autoinc to reg 2 4 1000 S011 ssss 1ddd
+MOV direct, Rs Move reg to mem 3 4 1000 S110 ssss 1DDD DDDD DDDD
+MOV Rd, direct Move mem to reg 3 4 1000 S110 dddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_mov(u8 op)
+{
+ handle_alu_type0(op, 8);
+}
+
+/*
+POPU direct Pop the mem content (b/w) from the user stack 3 5 1000 S111 0000 0DDD DDDD DDDD
+POP direct Pop the mem content (b/w) from the current stack 3 5 1000 S111 0001 0DDD DDDD DDDD
+PUSHU direct Push the mem content (b/w) onto the user stack 3 5 1000 S111 0010 0DDD DDDD DDDD
+PUSH direct Push the mem content (b/w) onto the current stack 3 5 1000 S111 0011 0DDD DDDD DDDD
+DJNZ Rd,rel8 Decrement reg and jump if not zero 3 8t/5nt 1000 S111 dddd 1000 rrrr rrrr
+*/
+void xa_cpu::e_pushpop_djnz_subgroup(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ if (op2 & 0x08)
+ {
+ const u8 rel8 = m_program->read_byte(m_pc++);
+ int rd = (op2 & 0xf0) >> 4;
+ if (size) { djnz_word_rd_rel8(rd, rel8); } else { djnz_byte_rd_rel8(rd, rel8); }
+ }
+ else
+ {
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u16 direct = ((op2 & 0x07) << 8) | op3;
+ switch (op2 & 0xf0)
+ {
+ case 0x00: { if (size) { popu_word_direct(direct); } else { popu_byte_direct(direct); } break; }
+ case 0x10: { if (size) { pop_word_direct(direct); } else { pop_byte_direct(direct); } break; }
+ case 0x20: { if (size) { pushu_word_direct(direct); } else { pushu_byte_direct(direct); } break; }
+ case 0x30: { if (size) { push_word_direct(direct); } else { push_byte_direct(direct); } break; }
+ default: LOGMASKED(LOG_DEBUG, "illegal push/pop"); do_nop(); break;
+ }
+ }
+}
+
+
+
+// -------------------------------------- Group 9 --------------------------------------
+
+/*
+MOV [Rd+], [Rs+] Move reg-ind to reg-ind, both pointers autoinc 2 6 1001 S000 0ddd 0sss
+DA Rd Decimal Adjust byte reg 2 4 1001 0000 dddd 1000
+SEXT Rd Sign extend last operation to reg 2 3 1001 S000 dddd 1001
+CPL Rd Complement (ones complement) reg 2 3 1001 S000 dddd 1010
+NEG Rd Negate (twos complement) reg 2 3 1001 S000 dddd 1011
+MOVC A, [A+PC] Move data from code mem to the accumulator ind w/ PC 2 6 1001 0000 0100 1100
+MOVC A, [A+DPTR] Move data from code mem to the accumulator ind w/ DPTR 2 6 1001 0000 0100 1110
+MOV Rd, USP Move User Stack Pointer to reg (system mode only) 2 3 1001 0000 dddd 1111
+MOV USP, Rs Move reg to User Stack Pointer (system mode only) 2 3 1001 1000 ssss 1111
+*/
+void xa_cpu::e_g9_subgroup(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ if ((op2 & 0x0f) < 0x08)
+ {
+ int rd = (op2 & 0x70) >> 4;
+ int rs = (op2 & 0x07);
+ if (size) { mov_word_indrdinc_indrsinc(rd, rs); } else { mov_byte_indrdinc_indrsinc(rd, rs); }
+ }
+ else
+ {
+ switch (op2 & 0x0f)
+ {
+ case 0x08: { int rd = (op2 & 0xf0) >> 4; da_rd(rd); break; }
+ case 0x09: { int rd = (op2 & 0xf0) >> 4; if (size) { sext_word_rd(rd); } else { sext_byte_rd(rd); } break; }
+ case 0x0a: { int rd = (op2 & 0xf0) >> 4; if (size) { cpl_word_rd(rd); } else { cpl_byte_rd(rd); } break; }
+ case 0x0b: { int rd = (op2 & 0xf0) >> 4; if (size) { neg_word_rd(rd); } else { neg_byte_rd(rd); } break; }
+ case 0x0c: { movc_a_apc(); break; }
+ case 0x0e: { movc_a_adptr(); break; }
+ case 0x0f: { int reg = (op2 & 0xf0) >> 4; if (!size) { mov_rd_usp(reg); } else { mov_usp_rs(reg); } break; }
+ default: { LOGMASKED(LOG_DEBUG, "illegal %02x", op2); do_nop(); break; }
+ }
+ }
+}
+
+/*
+ADD Rd, #data8 Add 8-bit imm data to reg 3 3 1001 0001 dddd 0000 iiii iiii
+ADD [Rd], #data8 Add 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0000 iiii iiii
+ADD [Rd+], #data8 Add 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0000 iiii iiii
+ADD [Rd+offset8], #data8 Add 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0000 oooo oooo iiii iiii
+ADD [Rd+offset16], #data8 Add 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0000 oooo oooo oooo oooo iiii iiii
+ADD direct, #data8 Add 8-bit imm data to mem 4 4 1001 0110 0DDD 0000 DDDD DDDD iiii iiii
+ADD Rd, #data16 Add 16-bit imm data to reg 4 3 1001 1001 dddd 0000 iiii iiii iiii iiii
+ADD [Rd], #data16 Add 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0000 iiii iiii iiii iiii
+ADD [Rd+], #data16 Add 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0000 iiii iiii iiii iiii
+ADD [Rd+offset8], #data16 Add 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0000 oooo oooo iiii iiii iiii iiii
+ADD [Rd+offset16], #data16 Add 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0000 oooo oooo oooo oooo iiii iiii iiii iiii
+ADD direct, #data16 Add 16-bit imm data to mem 5 4 1001 1110 0DDD 0000 DDDD DDDD iiii iiii iiii iiii
+
+ADDC Rd, #data8 Add 8-bit imm data to reg w/ carry 3 3 1001 0001 dddd 0001 iiii iiii
+ADDC Rd, #data16 Add 16-bit imm data to reg w/ carry 4 3 1001 1001 dddd 0001 iiii iiii iiii iiii
+ADDC [Rd], #data8 Add 16-bit imm data to reg-ind w/ carry 3 4 1001 0010 0ddd 0001 iiii iiii
+ADDC [Rd], #data16 Add 16-bit imm data to reg-ind w/ carry 4 4 1001 1010 0ddd 0001 iiii iiii iiii iiii
+ADDC [Rd+], #data8 Add 8-bit imm data to reg-ind and autoinc w/ carry 3 5 1001 0011 0ddd 0001 iiii iiii
+ADDC [Rd+], #data16 Add 16-bit imm data to reg-ind and autoinc w/ carry 4 5 1001 1011 0ddd 0001 iiii iiii iiii iiii
+ADDC [Rd+offset8], #data8 Add 8-bit imm data to reg-ind w/ 8-bit offs and carry 4 6 1001 0100 0ddd 0001 oooo oooo iiii iiii
+ADDC [Rd+offset8], #data16 Add 16-bit imm data to reg-ind w/ 8-bit offs and carry 5 6 1001 1100 0ddd 0001 oooo oooo iiii iiii iiii iiii
+ADDC [Rd+offset16], #data8 Add 8-bit imm data to reg-ind w/ 16-bit offs and carry 5 6 1001 0101 0ddd 0001 oooo oooo oooo oooo iiii iiii
+ADDC [Rd+offset16], #data16 Add 16-bit imm data to reg-ind w/ 16-bit offs and carry 6 6 1001 1101 0ddd 0001 oooo oooo oooo oooo iiii iiii iiii iiii
+ADDC direct, #data8 Add 8-bit imm data to mem w/ carry 4 4 1001 0110 0DDD 0001 DDDD DDDD iiii iiii
+ADDC direct, #data16 Add 16-bit imm data to mem w/ carry 5 4 1001 1110 0DDD 0001 DDDD DDDD iiii iiii iiii iiii
+
+SUB Rd, #data8 Subtract 8-bit imm data to reg 3 3 1001 0001 dddd 0010 iiii iiii
+SUB Rd, #data16 Subtract 16-bit imm data to reg 4 3 1001 1001 dddd 0010 iiii iiii iiii iiii
+SUB [Rd], #data8 Subtract 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0010 iiii iiii
+SUB [Rd], #data16 Subtract 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0010 iiii iiii iiii iiii
+SUB [Rd+], #data8 Subtract 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0010 iiii iiii
+SUB [Rd+], #data16 Subtract 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0010 iiii iiii iiii iiii
+SUB [Rd+offset8], #data8 Subtract 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0010 oooo oooo iiii iiii
+SUB [Rd+offset8], #data16 Subtract 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0010 oooo oooo iiii iiii iiii iiii
+SUB [Rd+offset16], #data8 Subtract 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0010 oooo oooo oooo oooo iiii iiii
+SUB [Rd+offset16], #data16 Subtract 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0010 oooo oooo oooo oooo iiii iiii iiii iiii
+SUB direct, #data8 Subtract 8-bit imm data to mem 4 4 1001 0110 0DDD 0010 DDDD DDDD iiii iiii
+SUB direct, #data16 Subtract 16-bit imm data to mem 5 4 1001 1110 0DDD 0010 DDDD DDDD iiii iiii iiii iiii
+
+SUBB Rd, #data8 Subtract w/ borrow 8-bit imm data to reg 3 3 1001 0001 dddd 0011 iiii iiii
+SUBB Rd, #data16 Subtract w/ borrow 16-bit imm data to reg 4 3 1001 1001 dddd 0011 iiii iiii iiii iiii
+SUBB [Rd], #data8 Subtract w/ borrow 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0011 iiii iiii
+SUBB [Rd], #data16 Subtract w/ borrow 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0011 iiii iiii iiii iiii
+SUBB [Rd+], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0011 iiii iiii
+SUBB [Rd+], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0011 iiii iiii iiii iiii
+SUBB [Rd+offset8], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0011 oooo oooo iiii iiii
+SUBB [Rd+offset8], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0011 oooo oooo iiii iiii iiii iiii
+SUBB [Rd+offset16], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0011 oooo oooo oooo oooo iiii iiii
+SUBB [Rd+offset16], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0011 oooo oooo oooo oooo iiii iiii iiii iiii
+SUBB direct, #data8 Subtract w/ borrow 8-bit imm data to mem 4 4 1001 0110 0DDD 0011 DDDD DDDD iiii iiii
+SUBB direct, #data16 Subtract w/ borrow 16-bit imm data to mem 5 4 1001 1110 0DDD 0011 DDDD DDDD iiii iiii iiii iiii
+
+CMP Rd, #data8 Compare 8-bit imm data to reg 3 3 1001 0001 dddd 0100 iiii iiii
+CMP Rd, #data16 Compare 16-bit imm data to reg 4 3 1001 1001 dddd 0100 iiii iiii iiii iiii
+CMP [Rd], #data8 Compare 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0100 iiii iiii
+CMP [Rd], #data16 Compare 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0100 iiii iiii iiii iiii
+CMP [Rd+], #data8 Compare 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0100 iiii iiii
+CMP [Rd+], #data16 Compare 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0100 iiii iiii iiii iiii
+CMP [Rd+offset8], #data8 Compare 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0100 oooo oooo iiii iiii
+CMP [Rd+offset8], #data16 Compare 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0100 oooo oooo iiii iiii iiii iiii
+CMP [Rd+offset16], #data8 Compare 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0100 oooo oooo oooo oooo iiii iiii
+CMP [Rd+offset16], #data16 Compare 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0100 oooo oooo oooo oooo iiii iiii iiii iiii
+CMP direct, #data8 Compare 8-bit imm data to mem 4 4 1001 0110 0DDD 0100 DDDD DDDD iiii iiii
+CMP direct, #data16 Compare 16-bit imm data to mem 5 4 1001 1110 0DDD 0100 DDDD DDDD iiii iiii iiii iiii
+
+AND Rd, #data8 Logical AND 8-bit imm data to reg 3 3 1001 0001 dddd 0101 iiii iiii
+AND Rd, #data16 Logical AND 16-bit imm data to reg 4 3 1001 1001 dddd 0101 iiii iiii iiii iiii
+AND [Rd], #data8 Logical AND 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0101 iiii iiii
+AND [Rd], #data16 Logical AND 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0101 iiii iiii iiii iiii
+AND [Rd+], #data8 Logical AND 8-bit imm data to reg-ind and autoinc 3 5 1001 0011 0ddd 0101 iiii iiii
+AND [Rd+], #data16 Logical AND 16-bit imm data to reg-ind and autoinc 4 5 1001 1011 0ddd 0101 iiii iiii iiii iiii
+AND [Rd+offset8], #data8 Logical AND 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0101 oooo oooo iiii iiii
+AND [Rd+offset8], #data16 Logical AND 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0101 oooo oooo iiii iiii iiii iiii
+AND [Rd+offset16], #data8 Logical AND 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0101 oooo oooo oooo oooo iiii iiii
+AND [Rd+offset16], #data16 Logical AND 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0101 oooo oooo oooo oooo iiii iiii iiii iiii
+AND direct, #data8 Logical AND 8-bit imm data to mem 4 4 1001 0110 0DDD 0101 DDDD DDDD iiii iiii
+AND direct, #data16 Logical AND 16-bit imm data to mem 5 4 1001 1110 0DDD 0101 DDDD DDDD iiii iiii iiii iiii
+
+OR Rd, #data8 Logical OR 8-bit imm data to reg 3 3 1001 0001 dddd 0110 iiii iiii
+OR Rd, #data16 Logical OR 16-bit imm data to reg 4 3 1001 1001 dddd 0110 iiii iiii iiii iiii
+OR [Rd], #data8 Logical OR 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0110 iiii iiii
+OR [Rd], #data16 Logical OR 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0110 iiii iiii iiii iiii
+OR [Rd+], #data8 Logical OR 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0110 iiii iiii
+OR [Rd+], #data16 Logical OR 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0110 iiii iiii iiii iiii
+OR [Rd+offset8], #data8 Logical OR 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0110 oooo oooo iiii iiii
+OR [Rd+offset8], #data16 Logical OR 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0110 oooo oooo iiii iiii iiii iiii
+OR [Rd+offset16], #data8 Logical OR 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0110 oooo oooo oooo oooo iiii iiii
+OR [Rd+offset16], #data16 Logical OR 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0110 oooo oooo oooo oooo iiii iiii iiii iiii
+OR direct, #data8 Logical OR 8-bit imm data to mem 4 4 1001 0110 0DDD 0110 DDDD DDDD iiii iiii
+OR direct, #data16 Logical OR 16-bit imm data to mem 5 4 1001 1110 0DDD 0110 DDDD DDDD iiii iiii iiii iiii
+
+XOR Rd, #data8 Logical XOR 8-bit imm data to reg 3 3 1001 0001 dddd 0111 iiii iiii
+XOR Rd, #data16 Logical XOR 16-bit imm data to reg 4 3 1001 1001 dddd 0111 iiii iiii iiii iiii
+XOR [Rd], #data8 Logical XOR 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0111 iiii iiii
+XOR [Rd], #data16 Logical XOR 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0111 iiii iiii iiii iiii
+XOR [Rd+], #data8 Logical XOR 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0111 iiii iiii
+XOR [Rd+], #data16 Logical XOR 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0111 iiii iiii iiii iiii
+XOR [Rd+offset8], #data8 Logical XOR 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0111 oooo oooo iiii iiii
+XOR [Rd+offset8], #data16 Logical XOR 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0111 oooo oooo iiii iiii iiii iiii
+XOR [Rd+offset16], #data8 Logical XOR 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0111 oooo oooo oooo oooo iiii iiii
+XOR [Rd+offset16], #data16 Logical XOR 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0111 oooo oooo oooo oooo iiii iiii iiii iiii
+XOR direct, #data8 Logical XOR 8-bit imm data to mem 4 4 1001 0110 0DDD 0111 DDDD DDDD iiii iiii
+XOR direct, #data16 Logical XOR 16-bit imm data to mem 5 4 1001 1110 0DDD 0111 DDDD DDDD iiii iiii iiii iiii
+
+MOV Rd, #data8 Move 8-bit imm data to reg 3 3 1001 0001 dddd 1000 iiii iiii
+MOV Rd, #data16 Move 16-bit imm data to reg 4 3 1001 1001 dddd 1000 iiii iiii iiii iiii
+MOV [Rd], #data8 Move 16-bit imm data to reg-ind 3 3 1001 0010 0ddd 1000 iiii iiii
+MOV [Rd], #data16 Move 16-bit imm data to reg-ind 4 3 1001 1010 0ddd 1000 iiii iiii iiii iiii
+MOV [Rd+], #data8 Move 8-bit imm data to reg-ind w/ autoinc 3 4 1001 0011 0ddd 1000 iiii iiii
+MOV [Rd+], #data16 Move 16-bit imm data to reg-ind w/ autoinc 4 4 1001 1011 0ddd 1000 iiii iiii iiii iiii
+MOV [Rd+offset8], #data8 Move 8-bit imm data to reg-ind w/ 8-bit offs 4 5 1001 0100 0ddd 1000 oooo oooo iiii iiii
+MOV [Rd+offset8], #data16 Move 16-bit imm data to reg-ind w/ 8-bit offs 5 5 1001 1100 0ddd 1000 oooo oooo iiii iiii iiii iiii
+MOV [Rd+offset16], #data8 Move 8-bit imm data to reg-ind w/ 16-bit offs 5 5 1001 0101 0ddd 1000 oooo oooo oooo oooo iiii iiii
+MOV [Rd+offset16], #data16 Move 16-bit imm data to reg-ind w/ 16-bit offs 6 5 1001 1101 0ddd 1000 oooo oooo oooo oooo iiii iiii iiii iiii
+MOV direct, #data8 Move 8-bit imm data to mem 4 3 1001 0110 0DDD 1000 DDDD DDDD iiii iiii
+MOV direct, #data16 Move 16-bit imm data to mem 5 3 1001 1110 0DDD 1000 DDDD DDDD iiii iiii iiii iiii
+*/
+void xa_cpu::e_alu(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ handle_alu_type1(op, op2);
+}
+
+/*
+MOV direct, direct Move mem to mem 4 4 1001 S111 0DDD 0ddd DDDD DDDD dddd dddd
+JB bit,rel8 Jump if bit set 4 10t/6nt 1001 0111 1000 00bb bbbb bbbb rrrr rrrr
+JNB bit,rel8 Jump if bit not set 4 10t/6nt 1001 0111 1010 00bb bbbb bbbb rrrr rrrr
+JBC bit,rel8 Jump if bit set and then clear the bit 4 11t/7nt 1001 0111 1100 00bb bbbb bbbb rrrr rrrr
+*/
+void xa_cpu::e_jb_mov_subgroup(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+
+ if (op2 & 0x80)
+ {
+ int bit = ((op2 & 0x03) << 8) | op3;
+ switch (op2 & 0x70)
+ {
+ case 0x00: jb_bit_rel8(bit, op4); break;
+ case 0x20: jnb_bit_rel8(bit, op4); break;
+ case 0x40: jbc_bit_rel8(bit, op4); break;
+ default: LOGMASKED(LOG_DEBUG, "illegal conditional jump %s $%02x", get_bittext(bit), expand_rel8(op4) ); break;
+ }
+ }
+ else
+ {
+ int direct_dst = ((op2 & 0x70) << 4) | op3;
+ int direct_src = ((op2 & 0x07) << 8) | op4;
+ int size = op & 0x08;
+ if (size) { mov_word_direct_direct(direct_dst, direct_src); } else { mov_byte_direct_direct(direct_dst, direct_src); }
+ }
+}
+
+// -------------------------------------- Group a --------------------------------------
+
+/*
+XCH Rd, direct Exchange contents of mem w/ a reg 3 6 1010 S000 dddd 1DDD DDDD DDDD
+
+MOV direct, [Rs] Move reg-ind to mem 3 4 1010 S000 1sss 0DDD DDDD DDDD
+MOV [Rd], direct Move mem to reg-ind 3 4 1010 S000 0ddd 0DDD DDDD DDDD
+*/
+void xa_cpu::e_movdir(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u16 direct = ((op2 & 0x07) << 8) | op3;
+
+ if (op2 & 0x08)
+ {
+ const u8 rd = op2 & (0xf0) >> 4;
+ if (size) { xch_word_rd_direct(rd, direct); } else { xch_byte_rd_direct(rd, direct); }
+ }
+ else
+ {
+ if (op2 & 0x80)
+ {
+ const u8 rs = op2 & (0x70) >> 4;
+ if (size) { mov_word_direct_indrs(direct, rs); } else { mov_byte_direct_indrs(direct, rs); }
+ }
+ else
+ {
+ const u8 rd = op2 & (0x70) >> 4;
+ if (size) { mov_word_indrd_direct(rd, direct); } else { mov_byte_indrd_direct(rd, direct); }
+ }
+ }
+}
+
+/*
+ADDS Rd, #data4 Add 4-bit signed imm data to reg 2 3 1010 S001 dddd iiii
+ADDS [Rd], #data4 Add 4-bit signed imm data to reg-ind 2 4 1010 S010 0ddd iiii
+ADDS [Rd+], #data4 Add 4-bit signed imm data to reg-ind w/ autoinc 2 5 1010 S011 0ddd iiii
+ADDS [Rd+offset8], #data4 Add reg-ind w/ 8-bit offs to 4-bit signed imm data 3 6 1010 S100 0ddd iiii oooo oooo
+ADDS [Rd+offset16], #data4 Add reg-ind w/ 16-bit offs to 4-bit signed imm data 4 6 1010 S101 0ddd iiii oooo oooo oooo oooo
+ADDS direct, #data4 Add 4-bit signed imm data to mem 3 4 1010 S110 0DDD iiii DDDD DDDD
+*/
+void xa_cpu::e_adds(u8 op)
+{
+ handle_adds_movs(op, 0);
+}
+
+/*
+MOVX [Rd], Rs Move external data from reg to mem 2 6 1010 S111 ssss 1ddd
+MOVX Rd, [Rs] Move external data from mem to reg 2 6 1010 S111 dddd 0sss
+*/
+void xa_cpu::e_movx_subgroup(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ if (op2 & 0x08)
+ {
+ const u8 rs = (op2 & 0xf0) >> 4;
+ const u8 rd = (op2 & 0x07);
+ if (size) { movx_word_indrd_rs(rd, rs); } else { movx_byte_indrd_rs(rd, rs); }
+ }
+ else
+ {
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x07);
+ if (size) { movx_word_rd_indrs(rd, rs); } else { movx_byte_rd_indrs(rd, rs); }
+ }
+}
+
+// -------------------------------------- Group b --------------------------------------
+
+/*
+RR Rd, #data4 Rotate right reg by the 4-bit imm value 2 a* 1011 S000 dddd iiii
+*/
+void xa_cpu::e_rr(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 data = rd & 0x0f;
+ if (size) { rr_word_rd_data4(rd, data); } else { rr_byte_rd_data4(rd, data); }
+}
+
+/*
+MOVS Rd, #data4 Move 4-bit sign-extended imm data to reg 2 3 1011 S001 dddd iiii
+MOVS [Rd], #data4 Move 4-bit sign-extended imm data to reg-ind 2 3 1011 S010 0ddd iiii
+MOVS [Rd+], #data4 Move 4-bit sign-extended imm data to reg-ind w/ autoinc 2 4 1011 S011 0ddd iiii
+MOVS [Rd+offset8], #data4 Move reg-ind w/ 8-bit offs to 4-bit sign-extended imm data 3 5 1011 S100 0ddd iiii oooo oooo
+MOVS [Rd+offset16], #data4 Move reg-ind w/ 16-bit offs to 4-bit sign-extended imm data 4 5 1011 S101 0ddd iiii oooo oooo oooo oooo
+MOVS direct, #data4 Move 4-bit sign-extended imm data to mem 3 3 1011 S110 0DDD iiii DDDD DDDD
+*/
+void xa_cpu::e_movs(u8 op)
+{
+ handle_adds_movs(op, 1);
+}
+
+/*
+RRC Rd, #data4 Rotate right reg though carry by the 4-bit imm value 2 a* 1011 S111 dddd iiii
+*/
+void xa_cpu::e_rrc(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 data = rd & 0x0f;
+ if (size) { rrc_word_rd_data4(rd, data); } else { rrc_byte_rd_data4(rd, data); }
+}
+
+
+// -------------------------------------- Group c --------------------------------------
+
+/*
+LSR Rd, Rs Logical right shift dest reg by the value in the src reg 2 a* 1100 SS00 dddd ssss
+FCALL addr24 Far call (full 24-bit address space) 4 12/8(PZ) 1100 0100 aaaa aaaa AAAA AAAA AAAA AAAA
+*/
+void xa_cpu::e_lsr_fc(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u32 addr = (op2 << 8) | op3 | (op4 << 16);
+ fcall_addr24(addr);
+ }
+ else
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ if (size == 0) lsr_byte_rd_rs(rd, rs);
+ else if (size == 2) lsr_word_rd_rs(rd, rs);
+ else if (size == 3) lsr_dword_rd_rs(rd, rs);
+ }
+}
+
+/*
+ASL Rd, Rs Logical left shift dest reg by the value in the src reg 2 a* 1100 SS01 dddd ssss
+CALL rel16 Relative call (range +/- 64K) 3 7/4(PZ) 1100 0101 rrrr rrrr rrrr rrrr
+*/
+void xa_cpu::e_asl_c(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ u16 rel16 = (op2 << 8) | op3;
+ call_rel16(rel16);
+ }
+ else
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ if (size == 0) asl_byte_rd_rs(rd, rs);
+ else if (size == 2) asl_word_rd_rs(rd, rs);
+ else if (size == 3) asl_dword_rd_rs(rd, rs);
+ }
+}
+
+/*
+ASR Rd, Rs Arithmetic shift right dest reg by the count in the src 2 a* 1100 SS10 dddd ssss
+CALL [Rs] Subroutine call ind w/ a reg 2 8/5(PZ) 1100 0110 0000 0sss
+*/
+void xa_cpu::e_asr_c(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rs = op2 & 0x07;
+ call_indrs(rs);
+ }
+ else
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ if (size == 0) asr_byte_rd_rs(rd, rs);
+ else if (size == 2) asr_word_rd_rs(rd, rs);
+ else if (size == 3) asr_dword_rd_rs(rd, rs);
+ }
+}
+
+/*
+NORM Rd, Rs Logical shift left dest reg by the value in the src reg until MSB set 2 a* 1100 SS11 dddd ssss
+*/
+void xa_cpu::e_norm(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ LOGMASKED(LOG_DEBUG, "illegal %02x", op2); do_nop();
+ }
+ else
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ int rd = (op2 & 0xf0) >> 4;
+ int rs = (op2 & 0x0f);
+ if (size == 0) norm_byte_rd_rs(rd, rs);
+ else if (size == 2) norm_word_rd_rs(rd, rs);
+ else if (size == 3) norm_dword_rd_rs(rd, rs);
+ }
+}
+
+// -------------------------------------- Group d --------------------------------------
+
+/*
+LSR Rd, #data4 Logical right shift reg by the 4-bit imm value 2 a* 1101 SS00 dddd iiii
+LSR Rd, #data5 Logical right shift reg by the 4-bit imm value 2 a* 1101 1100 dddi iiii
+FJMP addr24 Far jump (full 24-bit address space) 4 6 1101 0100 aaaa aaaa AAAA AAAA AAAA AAAA
+*/
+void xa_cpu::e_lsr_fj(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u32 addr = (op2 << 8) | op3 | (op4 << 16);
+ fjmp_addr24(addr);
+ }
+ else
+ {
+ handle_shift(op, 2);
+ }
+}
+
+/*
+ASL Rd, #data4 Logical left shift reg by the 4-bit imm value 2 a* 1101 SS01 dddd iiii
+ASL Rd, #data5 Logical left shift reg by the 5-bit imm value 2 a* 1101 1101 dddi iiii
+JMP rel16 Long unconditional branch 3 6 1101 0101 rrrr rrrr rrrr rrrr
+*/
+void xa_cpu::e_asl_j(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
+ {
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ u16 offset = (op2 << 8) | op3;
+ jmp_rel16(offset);
+ }
+ else
+ {
+ handle_shift(op, 0);
+ }
+}
+
+/*
+ASR Rd, #data4 Arithmetic shift right reg by the 4-bit imm count 2 a* 1101 SS10 dddd iiii
+ASR Rd, #data5 Arithmetic shift right reg by the 5-bit imm count 2 a* 1101 1110 dddi iiii
+RESET Causes a hardware Reset (same as external Reset) 2 18 1101 0110 0001 0000
+TRAP #data4 Causes 1 of 16 hardware traps to be executed 2 23/19(PZ) 1101 0110 0011 tttt
+JMP [A+DPTR] Jump ind relative to the DPTR 2 5 1101 0110 0100 0110
+JMP [[Rs+]] Jump double-ind to the address (pointer to a pointer) 2 8 1101 0110 0110 0sss
+JMP [Rs] Jump ind to the address in the reg (64K) 2 7 1101 0110 0111 0sss
+RET Return from subroutine 2 8/6(PZ) 1101 0110 1000 0000
+RETI Return from interrupt 2 10/8(PZ) 1101 0110 1001 0000
+*/
+void xa_cpu::e_asr_j(u8 op)
+{
+ int size = (op & 0x0c) >> 2;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ if (size == 0x01)
+ {
+ switch (op2 & 0xf0)
+ {
+ case 0x10: reset(); break;
+ case 0x30: trap_data4(op2 & 0x0f); break;
+ case 0x40: jmp_ind_adptr(); break;
+ case 0x60: jmp_dblindrs(op2 & 0x07); break;
+ case 0x70: jmp_indrs(op2 & 0x07); break;
+ case 0x80: ret(); break;
+ case 0x90: reti(); break;
+ default: LOGMASKED(LOG_DEBUG, "illegal"); do_nop(); break;
+ }
+ }
+ else
+ {
+ handle_shift(op, 1);
+ }
+}
+
+/*
+RL Rd, #data4 Rotate left reg by the 4-bit imm value 2 a* 1101 S011 dddd iiii
+*/
+void xa_cpu::e_rl(u8 op)
+{
+ int size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 data4 = (op2 & 0x0f);
+ if (size) { rl_word_rd_data4(rd, data4); } else { rl_byte_rd_data4(rd, data4); }
+}
+
+/*
+RLC Rd, #data4 Rotate left reg though carry by the 4-bit imm value 2 a* 1101 S111 dddd iiii
+*/
+void xa_cpu::e_rlc(u8 op)
+{
+ int size = op & 0x08;
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 data4 = (op2 & 0x0f);
+ if (size) { rlc_word_rd_data4(rd, data4); } else { rlc_byte_rd_data4(rd, data4); }
+}
+
+// -------------------------------------- Group e --------------------------------------
+
+/*
+DJNZ direct,rel8 Decrement mem and jump if not zero 4 9t/5nt 1110 S010 0000 1DDD DDDD DDDD rrrr rrrr
+CJNE Rd,direct,rel8 Compare dir byte to reg and jump if not equal 4 10t/7nt 1110 S010 dddd 0DDD DDDD DDDD rrrr rrrr
+*/
+void xa_cpu::e_djnz_cjne(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ int size = op & 0x08;
+
+ const u16 direct = ((op2 & 0x07) << 8) | op3;
+ if (op2 & 0x08)
+ {
+ if (size) { djnz_word_direct_rel8(direct, op4); } else { djnz_byte_direct_rel8(direct, op4); }
+ }
+ else
+ {
+ int rd = (op2 & 0xf0) >> 4;
+ if (size) { cjne_word_rd_direct_rel8(rd, direct, op4); } else { cjne_byte_rd_direct_rel8(rd, direct, op4); }
+ }
+}
+
+/*
+MULU.b Rd, Rs 8X8 unsigned multiply of reg contents 2 12 1110 0000 dddd ssss
+*/
+void xa_cpu::e_mulu_b(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ mulu_byte_rd_rs(rd, rs);
+}
+
+/*
+DIVU.b Rd, Rs 8x8 unsigned reg divide 2 12 1110 0001 dddd ssss
+*/
+void xa_cpu::e_divu_b(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ divu_byte_rd_rs(rd, rs);
+}
+
+/*
+MULU.w Rd, Rs 16X16 unsigned reg multiply 2 12 1110 0100 dddd ssss
+*/
+void xa_cpu::e_mulu_w(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ mulu_word_rd_rs(rd, rs);
+}
+
+/*
+DIVU.w Rd, Rs 16X8 unsigned reg divide 2 12 1110 0101 dddd ssss
+*/
+void xa_cpu::e_divu_w(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ divu_word_rd_rs(rd, rs);
+}
+
+/*
+MUL.w Rd, Rs 16X16 signed multiply of reg contents 2 12 1110 0110 dddd ssss
+*/
+void xa_cpu::e_mul_w(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ mul_word_rd_rs(rd, rs);
+}
+
+/*
+DIV.w Rd, Rs 16x8 signed reg divide 2 14 1110 0111 dddd ssss
+*/
+void xa_cpu::e_div_w(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ div_word_rd_rs(rd, rs);
+}
+
+/*
+MULU.b Rd, #data8 8X8 unsigned multiply of 8-bit imm data w/ reg 3 12 1110 1000 dddd 0000 iiii iiii
+DIVU.b Rd, #data8 8X8 unsigned reg divide w/ imm byte 3 12 1110 1000 dddd 0001 iiii iiii
+DIVU.w Rd, #data8 16X8 unsigned reg divide w/ imm byte 3 12 1110 1000 dddd 0011 iiii iiii
+DIV.w Rd, #data8 16x8 signed divide reg w/ imm word 3 14 1110 1000 dddd 1011 iiii iiii
+
+*/
+void xa_cpu::e_div_data8(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 data8 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xf0) >> 4;
+
+ switch (op2 & 0x0f)
+ {
+ case 0x00: { mulu_byte_rd_data8(rd, data8); break; }
+ case 0x01: { divu_byte_rd_data8(rd, data8); break; }
+ case 0x03: { divu_word_rd_data8(rd, data8); break; }
+ case 0x0b: { div_word_rd_data8(rd, data8);break; }
+ default: { LOGMASKED(LOG_DEBUG, "illegal mul/div data8 %s #$%02x", m_regnames8[rd], data8); do_nop(); break; }
+ }
+}
+
+/*
+MULU.w Rd, #data16 16X16 unsigned multiply 16-bit imm data w/ reg 4 12 1110 1001 dddd 0000 iiii iiii iiii iiii
+DIVU.d Rd, #data16 32X16 unsigned double reg divide w/ imm word 4 22 1110 1001 ddd0 0001 iiii iiii iiii iiii
+MUL.w Rd, #data16 16X16 signed multiply 16-bit imm data w/ reg 4 12 1110 1001 dddd 1000 iiii iiii iiii iiii
+DIV.d Rd, #data16 32x16 signed double reg divide w/ imm word 4 24 1110 1001 ddd0 1001 iiii iiii iiii iiii
+*/
+void xa_cpu::e_div_d16(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u16 data16 = (op3 << 8) | op4;
+ switch (op2 & 0x0f)
+ {
+ case 0x00: { const u8 rd = (op2 & 0xf0) >> 4; mulu_word_rd_data16(rd, data16); break; }
+ case 0x01: { const u8 rd = (op2 & 0xe0) >> 4; divu_dword_rd_data16(rd, data16); break; }
+ case 0x08: { const u8 rd = (op2 & 0xf0) >> 4; mul_word_rd_data16(rd, data16); break; }
+ case 0x09: { const u8 rd = (op2 & 0xe0) >> 4; div_dword_rd_data16(rd, data16); break; }
+ default: { const u8 rd = (op2 & 0xf0) >> 4; LOGMASKED(LOG_DEBUG, "illegal mul/div data16 %s, #$%04x", m_regnames16[rd], data16); do_nop(); break; }
+ }
+}
+
+/*
+DIVU.d Rd, Rs 32X16 unsigned double reg divide 2 22 1110 1101 ddd0 ssss
+*/
+void xa_cpu::e_divu_d(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xe0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ divu_dword_rd_rs(rd, rs);
+}
+
+/*
+DIV.d Rd, Rs 32x16 signed double reg divide 2 24 1110 1111 ddd0 ssss
+*/
+void xa_cpu::e_div_d(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 rd = (op2 & 0xe0) >> 4;
+ const u8 rs = (op2 & 0x0f);
+ div_dword_rd_rs(rd, rs);
+}
+
+/*
+CJNE [Rd],#data8,rel8 Compare imm word to reg-ind and jump if not equal 4 10t/7nt 1110 0011 0ddd 1000 rrrr rrrr iiii iiii
+CJNE Rd,#data8,rel8 Compare imm byte to reg and jump if not equal 4 9t/6nt 1110 0011 dddd 0000 rrrr rrrr iiii iiii
+*/
+void xa_cpu::e_cjne_d8(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ if (op2 & 0x08)
+ {
+ const u8 rd = (op2 & 0x70) >> 4;
+ cjne_indrd_data8_rel8(rd, op4, op3);
+ }
+ else
+ {
+ const u8 rd = (op2 & 0xf0) >> 4;
+ cjne_rd_data8_rel8(rd, op4, op3);
+ }
+}
+
+/*
+CJNE [Rd],#data16,rel8 Compare imm word to reg-ind and jump if not equal 5 10t/7nt 1110 1011 0ddd 1000 rrrr rrrr iiii iiii iiii iiii
+CJNE Rd,#data16,rel8 Compare imm word to reg and jump if not equal 5 9t/6nt 1110 1011 dddd 0000 rrrr rrrr iiii iiii iiii iiii
+*/
+void xa_cpu::e_cjne_d16(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ const u8 op3 = m_program->read_byte(m_pc++);
+ const u8 op4 = m_program->read_byte(m_pc++);
+ const u8 op5 = m_program->read_byte(m_pc++);
+ const u16 data = (op4 << 8) | op5;
+ if (op2 & 0x08)
+ {
+ const u8 rd = (op2 & 0x70) >> 4;
+ cjne_indrd_data16_rel8(rd, data, op3);
+ }
+ else
+ {
+ const u8 rd = (op2 & 0xf0) >> 4;
+ cjne_rd_data16_rel8(rd, data, op3);
+ }
+}
+
+/*
+JZ rel8 Jump if accumulator equals zero 2 6t/3nt 1110 1100 rrrr rrrr
+*/
+void xa_cpu::e_jz_rel8(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ jz_rel8(op2);
+}
+
+/*
+JNZ rel8 Jump if accumulator not equal zero 2 6t/3nt 1110 1110 rrrr rrrr
+*/
+void xa_cpu::e_jnz_rel8(u8 op)
+{
+ const u8 op2 = m_program->read_byte(m_pc++);
+ jnz_rel8(op2);
+}
+
+
+// -------------------------------------- Group f --------------------------------------
+
+/*
+BCC rel8 Branch if the carry flag is clear 2 6t/3nt 1111 0000 rrrr rrrr
+BCS rel8 Branch if the carry flag is set 2 6t/3nt 1111 0001 rrrr rrrr
+BNE rel8 Branch if the zero flag is not set 2 6t/3nt 1111 0010 rrrr rrrr
+BEQ rel8 Branch if the zero flag is set 2 6t/3nt 1111 0011 rrrr rrrr
+BNV rel8 Branch if overflow flag is clear 2 6t/3nt 1111 0100 rrrr rrrr
+BOV rel8 Branch if overflow flag is set 2 6t/3nt 1111 0101 rrrr rrrr
+BPL rel8 Branch if the negative flag is clear 2 6t/3nt 1111 0110 rrrr rrrr
+BMI rel8 Branch if the negative flag is set 2 6t/3nt 1111 0111 rrrr rrrr
+BG rel8 Branch if greater than (unsigned) 2 6t/3nt 1111 1000 rrrr rrrr
+BL rel8 Branch if less than or equal to (unsigned) 2 6t/3nt 1111 1001 rrrr rrrr
+BGE rel8 Branch if greater than or equal to (signed) 2 6t/3nt 1111 1010 rrrr rrrr
+BLT rel8 Branch if less than (signed) 2 6t/3nt 1111 1011 rrrr rrrr
+BGT rel8 Branch if greater than (signed) 2 6t/3nt 1111 1100 rrrr rrrr
+BLE rel8 Branch if less than or equal to (signed) 2 6t/3nt 1111 1101 rrrr rrrr
+BR rel8 Short unconditional branch 2 6 1111 1110 rrrr rrrr
+*/
+
+void xa_cpu::e_branch(u8 op)
+{
+ const u8 rel8 = m_program->read_byte(m_pc++);
+ switch (op & 0x0f)
+ {
+ case 0x00: bcc_rel8(rel8); break;
+ case 0x01: bcs_rel8(rel8); break;
+ case 0x02: bne_rel8(rel8); break;
+ case 0x03: beq_rel8(rel8); break;
+ case 0x04: bnv_rel8(rel8); break;
+ case 0x05: bov_rel8(rel8); break;
+ case 0x06: bpl_rel8(rel8); break;
+ case 0x07: bmi_rel8(rel8); break;
+ case 0x08: bg_rel8(rel8); break;
+ case 0x09: bl_rel8(rel8); break;
+ case 0x0a: bge_rel8(rel8); break;
+ case 0x0b: blt_rel8(rel8); break;
+ case 0x0c: bgt_rel8(rel8); break;
+ case 0x0d: ble_rel8(rel8); break;
+ case 0x0e: br_rel8(rel8); break;
+ case 0x0f: LOGMASKED(LOG_DEBUG, "Illegal branch type"); do_nop(); break; // probably acts as 'branch never'
+ }
+}
+
+/*
+BKPT Cause the breakpoint trap to be executed. 1 23/19(PZ) 1111 1111
+*/
+void xa_cpu::e_bkpt(u8 op)
+{
+ fatalerror( "BKPT");
+}
+
/*****************************************************************************/
-void xa_cpu_device::device_start()
+void xa_cpu::device_start()
{
m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
+ m_sfr = &space(AS_IO);
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%08X");
state_add(STATE_GENPCBASE, "CURPC", m_pc).callexport().noshow();
+ state_add(XA_BANK0_R0, "BANK0_R0", m_regs[0]);
+ state_add(XA_BANK0_R1, "BANK0_R1", m_regs[1]);
+ state_add(XA_BANK0_R2, "BANK0_R2", m_regs[2]);
+ state_add(XA_BANK0_R3, "BANK0_R3", m_regs[3]);
+
+ state_add(XA_BANK1_R0, "BANK1_R0", m_regs[4]);
+ state_add(XA_BANK1_R1, "BANK1_R1", m_regs[5]);
+ state_add(XA_BANK1_R2, "BANK1_R2", m_regs[6]);
+ state_add(XA_BANK1_R3, "BANK1_R3", m_regs[7]);
+
+ state_add(XA_BANK2_R0, "BANK2_R0", m_regs[8]);
+ state_add(XA_BANK2_R1, "BANK2_R1", m_regs[9]);
+ state_add(XA_BANK2_R2, "BANK2_R2", m_regs[10]);
+ state_add(XA_BANK2_R3, "BANK2_R3", m_regs[11]);
+
+ state_add(XA_BANK3_R0, "BANK3_R0", m_regs[12]);
+ state_add(XA_BANK3_R1, "BANK3_R1", m_regs[13]);
+ state_add(XA_BANK3_R2, "BANK3_R2", m_regs[14]);
+ state_add(XA_BANK3_R3, "BANK3_R3", m_regs[15]);
+
+ state_add(XA_R4, "R4", m_regs[16]);
+ state_add(XA_R5, "R5", m_regs[17]);
+ state_add(XA_R6, "R6", m_regs[18]);
+// state_add(XA_R7, "R7", m_usermode ? m_USP : m_SSP);
+
+ state_add(XA_USP, "R7 USP", m_USP);
+ state_add(XA_SSP, "R7 SSP", m_SSP);
+
set_icountptr(m_icount);
+
+ save_item(NAME(m_im));
+ save_item(NAME(m_rs));
+ save_item(NAME(m_zflag));
+ save_item(NAME(m_nflag));
+ save_item(NAME(m_vflag));
+ save_item(NAME(m_cflag));
+ save_item(NAME(m_acflag));
+ save_item(NAME(m_sm_flag));
+ save_item(NAME(m_tm_flag));
+ save_item(NAME(m_p_flag));
+ save_item(NAME(m_f0_flag));
+ save_item(NAME(m_f1_flag));
+ save_item(NAME(m_pc));
+ save_item(NAME(m_usermode));
+ save_item(NAME(m_pagezeromode));
+ save_item(NAME(m_USP));
+ save_item(NAME(m_SSP));
+ save_item(NAME(m_WDCON));
+ save_item(NAME(m_SCR));
+ save_item(NAME(m_IEL));
+ save_item(NAME(m_regs));
+ save_item(NAME(m_PSWL));
+ save_item(NAME(m_PSWH));
+ save_item(NAME(m_regbank));
+
+ save_item(NAME(m_PxCFGA));
+ save_item(NAME(m_PxCFGB));
+
+ save_item(NAME(m_in_interrupt));
+ save_item(NAME(m_irq_pending));
+
}
-void xa_cpu_device::device_reset()
+void xa_cpu::device_reset()
{
- // temp, as there is code here on superkds
+ u16 temppsw = m_program->read_word(0);
+ sfr_PSWL_w(temppsw & 0xff);
+ sfr_PSWH_w((temppsw >> 8) & 0xff);
m_pc = m_program->read_word(2);
+
+ m_WDCON = 0x00;
+ m_SCR = 0x00;
+ m_IEL = 0x00;
+
+ m_USP = 0x0100;
+ m_SSP = 0x0100;
+
+ for (int i = 0; i < 4 * 4 + 4; i++)
+ {
+ m_regs[i] = 0x0000;
+ }
+
+ m_nflag = 0;
+ m_zflag = 0;
+ m_cflag = 0;
+ m_vflag = 0;
+ m_acflag = 0;
+
+ m_pagezeromode = 1;
+
+ m_in_interrupt = 0;
+ m_irq_pending = 0;
+
+ for (int i = 0; i < 4; i++)
+ {
+ m_PxCFGA[i] = 0;
+ m_PxCFGB[i] = 0;
+ }
}
/*****************************************************************************/
-void xa_cpu_device::execute_run()
+void xa_cpu::check_external_irq_level(int level)
+{
+ if (m_IEL & 0x80)
+ {
+ if (m_IEL & (1 << level))
+ {
+ if (m_irq_pending & (1 << level))
+ {
+ LOGMASKED(LOG_DEBUG, "testing irq %d\n", level);
+ int vector = 0x20 + level;
+ push_word_to_system_stack(sfr_PSWH_r());
+ push_word_to_system_stack(sfr_PSWL_r());
+ push_word_to_system_stack(m_pc);
+
+ u16 temppsw = m_program->read_word(vector*4);
+ sfr_PSWL_w(temppsw & 0xff);
+ sfr_PSWH_w((temppsw >> 8) & 0xff);
+ m_pc = m_program->read_word((vector*4)+2);
+ m_in_interrupt = 1;
+ m_irq_pending &= ~(1 << level);
+ standard_irq_callback(level, m_pc);
+ }
+ }
+ }
+}
+
+void xa_cpu::check_interrupts()
+{
+ if (m_irq_pending)
+ {
+ if (!m_in_interrupt)
+ {
+ for (int i = 0; i < 4; i++)
+ check_external_irq_level(i);
+ }
+ }
+
+}
+
+void xa_cpu::execute_set_input(int inputnum, int state)
+{
+ // This is not accurate, just test code for fearless/superkds
+ m_irq_pending |= 1 << inputnum;
+ check_interrupts();
+}
+
+void xa_cpu::execute_run()
{
while (m_icount > 0)
{
+ check_interrupts();
+
debugger_instruction_hook(m_pc);
- m_pc++;
- m_icount--;
+ u32 oldpc = m_pc;
+ u8 op = m_program->read_byte(m_pc++);
+ int old_icount = m_icount;
+ (this->*s_instruction[op])(op);
+ if (m_icount == old_icount)
+ fatalerror("op at %06x took no cycles\n", oldpc);
}
}
diff --git a/src/devices/cpu/xa/xa.h b/src/devices/cpu/xa/xa.h
index 983fff36724..3fbf7a3cb92 100644
--- a/src/devices/cpu/xa/xa.h
+++ b/src/devices/cpu/xa/xa.h
@@ -6,13 +6,54 @@
#pragma once
-class xa_cpu_device : public cpu_device
+enum {
+ XA_EXT_IRQ0,
+ XA_EXT_IRQ1,
+ XA_EXT_IRQ2,
+ XA_EXT_IRQ3,
+};
+
+enum {
+ XA_BANK0_R0,
+ XA_BANK0_R1,
+ XA_BANK0_R2,
+ XA_BANK0_R3,
+
+ XA_BANK1_R0,
+ XA_BANK1_R1,
+ XA_BANK1_R2,
+ XA_BANK1_R3,
+
+ XA_BANK2_R0,
+ XA_BANK2_R1,
+ XA_BANK2_R2,
+ XA_BANK2_R3,
+
+ XA_BANK3_R0,
+ XA_BANK3_R1,
+ XA_BANK3_R2,
+ XA_BANK3_R3,
+
+ XA_R4,
+ XA_R5,
+ XA_R6,
+ XA_R7,
+
+ XA_USP,
+ XA_SSP,
+};
+
+
+class xa_cpu : public cpu_device
{
public:
- xa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ xa_cpu(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <unsigned N> auto port_in_cb() { return m_port_in_cb[N].bind(); }
+ template <unsigned N> auto port_out_cb() { return m_port_out_cb[N].bind(); }
protected:
- xa_cpu_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor prg_map);
+ xa_cpu(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor prg_map, address_map_constructor dat_map);
virtual void device_start() override;
virtual void device_reset() override;
@@ -21,6 +62,7 @@ protected:
virtual uint32_t execute_max_cycles() const noexcept override { return 5; }
virtual uint32_t execute_input_lines() const noexcept override { return 0; }
virtual void execute_run() override;
+ virtual void execute_set_input(int inputnum, int state) override;
virtual space_config_vector memory_space_config() const override;
@@ -28,26 +70,900 @@ protected:
private:
void internal_map(address_map &map);
+ void internal_data_map(address_map &map);
+ void data_map(address_map &map);
+ void sfr_map(address_map &map);
address_space_config m_program_config;
+ address_space_config m_data_config;
+ address_space_config m_sfr_config;
+
+ struct mem_info {
+ int addr;
+ const char *name;
+ };
+
+
+ static const mem_info default_names[];
+ void add_names(const mem_info *info);
+
+ std::string get_data_address(u16 arg) const;
+
+ typedef void (xa_cpu::*op_func) (u8 op);
+ static const op_func s_instruction[256];
+
+ const char* m_regnames16[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal" };
+ const char* m_regnames8[16] = { "R0L", "R0H", "R1L", "R1H", "R2L", "R2H", "R3L", "R3H", "R4L", "R4H", "R5L", "R5H", "R6L", "R6H", "R7L", "R7H"};
+
+ std::string get_bittext(int bit);
+ std::string get_directtext(int bit);
+ std::string show_expanded_data4(u16 data4, int size);
+ std::string get_word_reglist(u8 op2);
+ std::string get_byte_reglist(u8 op2, int h);
+
+ void check_external_irq_level(int level);
+ void check_interrupts();
+
+ u16 expand_rel16(u16 rel16);
+ u16 expand_rel8(u8 rel8);
+
+ void cy(u8 cycles)
+ {
+ m_icount -= cycles;
+ }
+
+ void do_nz_flags_16(u16 data);
+ void do_nz_flags_8(u8 data);
+
+ u8 get_n_flag() { return m_nflag; }
+ void set_n_flag() { m_nflag = 1; }
+ void clear_n_flag() { m_nflag = 0; }
+
+ u8 get_z_flag() { return m_zflag; }
+ void set_z_flag() { m_zflag = 1; }
+ void clear_z_flag() { m_zflag = 0; }
+
+ u8 get_c_flag() { return m_cflag; }
+ void set_c_flag() { m_cflag = 1; }
+ void clear_c_flag() { m_cflag = 0; }
+
+ u8 get_v_flag() { return m_vflag; }
+ void set_v_flag() { m_vflag = 1; }
+ void clear_v_flag() { m_vflag = 0; }
+
+ u8 get_ac_flag() { return m_acflag; }
+ void set_ac_flag() { m_acflag = 1; }
+ void clear_ac_flag() { m_acflag = 0; }
+
+
+ u8 gr8(int reg);
+ void sr8(int reg, u8 data);
+
+ u16 gr16(int reg);
+ void sr16(int reg, u16 data);
+
+ u32 gr32(int reg);
+ void sr32(int reg, u32 data);
+
+ void set_pc_in_current_page(u16 addr);
+
+ void push_word_reglist(u8 op2, int h, bool force_user);
+ void pull_word_reglist(u8 op2, int h, bool force_user);
+ void push_byte_reglist(u8 op2, int h, bool force_user);
+ void pull_byte_reglist(u8 op2, int h, bool force_user);
+
+ void push_word_to_user_stack(u16 data);
+ void push_word_to_system_stack(u16 data);
+ void push_word_to_stack(u16 data);
+
+ u16 pull_word_from_user_stack();
+ u16 pull_word_from_system_stack();
+ u16 pull_word_from_stack();
+
+ void push_byte_to_user_stack(u8 data);
+ void push_byte_to_system_stack(u8 data);
+ void push_byte_to_stack(u16 data);
+
+ u8 pull_byte_from_user_stack();
+ u8 pull_byte_from_system_stack();
+ u8 pull_byte_from_stack();
+
+ void wdat8(int address, u8 data);
+ void wdat16(int address, u16 data);
+
+ u8 rdat8(int address);
+ u16 rdat16(int address);
+
+ u8 sfr_WDCON_r();
+
+ u8 sfr_PSWL_r();
+ void sfr_PSWL_w(u8 data);
+
+ u8 sfr_PSWH_r();
+ void sfr_PSWH_w(u8 data);
+ void sfr_PSW51_w(u8 data);
+
+ void sfr_SCR_w(u8 data);
+ void sfr_WFEED1_w(u8 data);
+ void sfr_WFEED2_w(u8 data);
+
+ u8 sfr_IEL_r();
+ void sfr_IEL_w(u8 data);
+
+ u8 sfr_port_r(offs_t offset);
+ void sfr_port_w(offs_t offset, u8 data);
+
+ u8 sfr_PxCFGA_r(offs_t offset);
+ void sfr_PxCFGA_w(offs_t offset, u8 data);
+
+ u8 sfr_PxCFGB_r(offs_t offset);
+ void sfr_PxCFGB_w(offs_t offset, u8 data);
+
+ void set_bit_8_helper(u16 bit, u8 val);
+
+ u32 asl32_helper(u32 fullreg, u8 amount);
+ u32 lsr32_helper(u32 fullreg, u8 amount);
+ u16 lsr16_helper(u16 fullreg, u8 amount);
+
+ u8 read_direct8(u16 addr);
+ u16 read_direct16(u16 addr);
+
+ void write_direct8(u16 addr, u8 data);
+ void write_direct16(u16 addr, u16 data);
+
+ u16 do_subb_16(u16 val1, u16 val2);
+ u16 do_sub_16(u16 val1, u16 val2);
+ u16 do_sub_16_helper(u16 val1, u16 val2, u8 c);
+
+ u16 do_addc_16(u16 val1, u16 val2);
+ u16 do_add_16(u16 val1, u16 val2);
+ u16 do_add_16_helper(u16 val1, u16 val2, u8 c);
+
+ u16 do_xor_16(u16 val1, u16 val2);
+ u16 do_or_16(u16 val1, u16 val2);
+ u16 do_and_16(u16 val1, u16 val2);
+
+ u8 do_sub_8(u8 val1, u8 val2);
+ u8 do_subb_8(u8 val1, u8 val2);
+ u8 do_sub_8_helper(u8 val1, u8 val2, u8 c);
+
+ u8 do_add_8(u8 val1, u8 val2);
+ u8 do_addc_8(u8 val1, u8 val2);
+ u8 do_add_8_helper(u8 val1, u8 val2, u8 c);
+
+ u8 do_xor_8(u8 val1, u8 val2);
+ u8 do_or_8(u8 val1, u8 val2);
+ u8 do_and_8(u8 val1, u8 val2);
+
+ u8 do_cjne_8_helper(u8 val1, u8 val2);
+
+ void handle_alu_type0(u8 op, int alu_op);
+ void handle_alu_type1(u8 op, u8 op2);
+ void handle_push_rlist(u8 op);
+ void handle_pushu_rlist(u8 op);
+ void handle_pop_rlist(u8 op);
+ void handle_popu_rlist(u8 op);
+ void handle_adds_movs(u8 op, int which);
+ void handle_shift(u8 op, int shift_type);
+
+ void e_illegal(u8 op);
+
+ void e_nop(u8 op);
+ void e_bitgroup(u8 op);
+ void e_add(u8 op);
+ void e_push_rlist(u8 op);
+ void e_addc(u8 op);
+ void e_pushu_rlist(u8 op);
+ void e_sub(u8 op);
+ void e_pop_rlist(u8 op);
+ void e_subb(u8 op);
+ void e_popu_rlist(u8 op);
+ void e_lea_offset8(u8 op);
+ void e_lea_offset16(u8 op);
+ void e_cmp(u8 op);
+ void e_xch_type1(u8 op);
+ void e_and(u8 op);
+ void e_xch_type2(u8 op);
+ void e_or(u8 op);
+ void e_xor(u8 op);
+ void e_movc_rd_rsinc(u8 op);
+ void e_mov(u8 op);
+ void e_pushpop_djnz_subgroup(u8 op);
+ void e_g9_subgroup(u8 op);
+ void e_alu(u8 op);
+ void e_jb_mov_subgroup(u8 op);
+ void e_movdir(u8 op);
+ void e_adds(u8 op);
+ void e_movx_subgroup(u8 op);
+ void e_rr(u8 op);
+ void e_movs(u8 op);
+ void e_rrc(u8 op);
+ void e_lsr_fc(u8 op);
+ void e_asl_c(u8 op);
+ void e_asr_c(u8 op);
+ void e_norm(u8 op);
+ void e_lsr_fj(u8 op);
+ void e_asl_j(u8 op);
+ void e_asr_j(u8 op);
+ void e_rl(u8 op);
+ void e_rlc(u8 op);
+ void e_djnz_cjne(u8 op);
+ void e_mulu_b(u8 op);
+ void e_divu_b(u8 op);
+ void e_mulu_w(u8 op);
+ void e_divu_w(u8 op);
+ void e_mul_w(u8 op);
+ void e_div_w(u8 op);
+ void e_div_data8(u8 op);
+ void e_div_d16(u8 op);
+ void e_divu_d(u8 op);
+ void e_div_d(u8 op);
+ void e_cjne_d8(u8 op);
+ void e_cjne_d16(u8 op);
+ void e_jz_rel8(u8 op);
+ void e_jnz_rel8(u8 op);
+ void e_branch(u8 op);
+ void e_bkpt(u8 op);
+
+ void do_nop();
+
+ void add_byte_rd_data8(u8 rd, u8 data8);
+ void addc_byte_rd_data8(u8 rd, u8 data8);
+ void sub_byte_rd_data8(u8 rd, u8 data8);
+ void subb_byte_rd_data8(u8 rd, u8 data8);
+ void cmp_byte_rd_data8(u8 rd, u8 data8);
+ void and_byte_rd_data8(u8 rd, u8 data8);
+ void or_byte_rd_data8(u8 rd, u8 data8);
+ void xor_byte_rd_data8(u8 rd, u8 data8);
+ void mov_byte_rd_data8(u8 rd, u8 data8);
+
+ void add_byte_indrd_data8(u8 rd, u8 data8);
+ void addc_byte_indrd_data8(u8 rd, u8 data8);
+ void sub_byte_indrd_data8(u8 rd, u8 data8);
+ void subb_byte_indrd_data8(u8 rd, u8 data8);
+ void cmp_byte_indrd_data8(u8 rd, u8 data8);
+ void and_byte_indrd_data8(u8 rd, u8 data8);
+ void or_byte_indrd_data8(u8 rd, u8 data8);
+ void xor_byte_indrd_data8(u8 rd, u8 data8);
+ void mov_byte_indrd_data8(u8 rd, u8 data8);
+
+ void add_byte_indrdinc_data8(u8 rd, u8 data8);
+ void addc_byte_indrdinc_data8(u8 rd, u8 data8);
+ void sub_byte_indrdinc_data8(u8 rd, u8 data8);
+ void subb_byte_indrdinc_data8(u8 rd, u8 data8);
+ void cmp_byte_indrdinc_data8(u8 rd, u8 data8);
+ void and_byte_indrdinc_data8(u8 rd, u8 data8);
+ void or_byte_indrdinc_data8(u8 rd, u8 data8);
+ void xor_byte_indrdinc_data8(u8 rd, u8 data8);
+ void mov_byte_indrdinc_data8(u8 rd, u8 data8);
+
+ void add_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void addc_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void sub_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void subb_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void cmp_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void and_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void or_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void xor_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+ void mov_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8);
+
+ void add_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void addc_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void sub_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void subb_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void cmp_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void and_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void or_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void xor_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+ void mov_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8);
+
+ void add_byte_direct_data8(u16 direct, u8 data8);
+ void addc_byte_direct_data8(u16 direct, u8 data8);
+ void sub_byte_direct_data8(u16 direct, u8 data8);
+ void subb_byte_direct_data8(u16 direct, u8 data8);
+ void cmp_byte_direct_data8(u16 direct, u8 data8);
+ void and_byte_direct_data8(u16 direct, u8 data8);
+ void or_byte_direct_data8(u16 direct, u8 data8);
+ void xor_byte_direct_data8(u16 direct, u8 data8);
+ void mov_byte_direct_data8(u16 direct, u8 data8);
+
+ void add_word_rd_data16(u8 rd, u16 data16);
+ void addc_word_rd_data16(u8 rd, u16 data16);
+ void sub_word_rd_data16(u8 rd, u16 data16);
+ void subb_word_rd_data16(u8 rd, u16 data16);
+ void cmp_word_rd_data16(u8 rd, u16 data16);
+ void and_word_rd_data16(u8 rd, u16 data16);
+ void or_word_rd_data16(u8 rd, u16 data16);
+ void xor_word_rd_data16(u8 rd, u16 data16);
+ void mov_word_rd_data16(u8 rd, u16 data16);
+
+ void add_word_indrd_data16(u8 rd, u16 data16);
+ void addc_word_indrd_data16(u8 rd, u16 data16);
+ void sub_word_indrd_data16(u8 rd, u16 data16);
+ void subb_word_indrd_data16(u8 rd, u16 data16);
+ void cmp_word_indrd_data16(u8 rd, u16 data16);
+ void and_word_indrd_data16(u8 rd, u16 data16);
+ void or_word_indrd_data16(u8 rd, u16 data16);
+ void xor_word_indrd_data16(u8 rd, u16 data16);
+ void mov_word_indrd_data16(u8 rd, u16 data16);
+
+ void add_word_indrdinc_data16(u8 rd, u16 data16);
+ void addc_word_indrdinc_data16(u8 rd, u16 data16);
+ void sub_word_indrdinc_data16(u8 rd, u16 data16);
+ void subb_word_indrdinc_data16(u8 rd, u16 data16);
+ void cmp_word_indrdinc_data16(u8 rd, u16 data16);
+ void and_word_indrdinc_data16(u8 rd, u16 data16);
+ void or_word_indrdinc_data16(u8 rd, u16 data16);
+ void xor_word_indrdinc_data16(u8 rd, u16 data16);
+ void mov_word_indrdinc_data16(u8 rd, u16 data16);
+
+ void add_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void addc_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void sub_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void subb_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void cmp_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void and_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void or_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void xor_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+ void mov_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16);
+
+ void add_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void addc_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void sub_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void subb_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void cmp_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void and_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void or_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void xor_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+ void mov_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16);
+
+ void add_word_direct_data16(u16 direct, u16 data16);
+ void addc_word_direct_data16(u16 direct, u16 data16);
+ void sub_word_direct_data16(u16 direct, u16 data16);
+ void subb_word_direct_data16(u16 direct, u16 data16);
+ void cmp_word_direct_data16(u16 direct, u16 data16);
+ void and_word_direct_data16(u16 direct, u16 data16);
+ void or_word_direct_data16(u16 direct, u16 data16);
+ void xor_word_direct_data16(u16 direct, u16 data16);
+ void mov_word_direct_data16(u16 direct, u16 data16);
+
+ void aluop_word_rd_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_byte_rd_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_word_rd_indrs(int alu_op, u8 rd, u8 rs);
+ void aluop_byte_rd_indrs(int alu_op, u8 rd, u8 rs);
+ void aluop_word_indrd_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_byte_indrd_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_word_rd_indrsinc(int alu_op, u8 rd, u8 rs);
+ void aluop_byte_rd_indrsinc(int alu_op, u8 rd, u8 rs);
+ void aluop_word_indrdinc_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_byte_indrdinc_rs(int alu_op, u8 rd, u8 rs);
+ void aluop_word_rd_rsoff8(int alu_op, u8 rd, u8 rs, u8 offset8);
+ void aluop_byte_rd_rsoff8(int alu_op, u8 rd, u8 rs, u8 offset8);
+ void aluop_word_rdoff8_rs(int alu_op, u8 rd, u8 offset8, u8 rs);
+ void aluop_byte_rdoff8_rs(int alu_op, u8 rd, u8 offset8, u8 rs);
+ void aluop_word_rsoff16(int alu_op, u8 rd, u8 rs, u16 offset16);
+ void aluop_byte_rsoff16(int alu_op, u8 rd, u8 rs, u16 offset16);
+ void aluop_word_rdoff16_rs(int alu_op, u8 rd, u16 offset16, u8 rs);
+ void aluop_byte_rdoff16_rs(int alu_op, u8 rd, u16 offset16, u8 rs);
+ void aluop_word_rd_direct(int alu_op, u8 rd, u16 direct);
+ void aluop_byte_rd_direct(int alu_op, u8 rd, u16 direct);
+ void aluop_word_direct_rs(int alu_op, u16 direct, u8 rs);
+ void aluop_byte_direct_rs(int alu_op, u16 direct, u8 rs);
+
+ void aluop_byte_rd_data8(int alu_op, u8 rd, u8 data8);
+ void aluop_byte_indrd_data8(int alu_op, u8 rd, u8 data8);
+ void aluop_byte_indrdinc_data8(int alu_op, u8 rd, u8 data8);
+ void aluop_byte_rdoff8_data8(int alu_op, u8 rd, u8 offset8, u8 data8);
+ void aluop_byte_rdoff16_data8(int alu_op, u8 rd, u16 offset16, u8 data8);
+ void aluop_byte_direct_data8(int alu_op, u16 direct, u8 data8);
+ void aluop_byte_rd_data16(int alu_op, u8 rd, u16 data16);
+ void aluop_byte_indrd_data16(int alu_op, u8 rd, u16 data16);
+ void aluop_byte_indrdinc_data16(int alu_op, u8 rd, u16 data16);
+ void aluop_byte_rdoff8_data16(int alu_op, u8 rd, u8 offset8, u16 data16);
+ void aluop_byte_rdoff16_data16(int alu_op, u8 rd, u16 offset16, u16 data16);
+ void aluop_byte_direct_data16(int alu_op, u16 direct, u16 data16);
+
+ void add_word_rd_rs(u8 rd, u8 rs);
+ void addc_word_rd_rs(u8 rd, u8 rs);
+ void sub_word_rd_rs(u8 rd, u8 rs);
+ void subb_word_rd_rs(u8 rd, u8 rs);
+ void cmp_word_rd_rs(u8 rd, u8 rs);
+ void and_word_rd_rs(u8 rd, u8 rs);
+ void or_word_rd_rs(u8 rd, u8 rs);
+ void xor_word_rd_rs(u8 rd, u8 rs);
+ void mov_word_rd_rs(u8 rd, u8 rs);
+
+ void add_byte_rd_rs(u8 rd, u8 rs);
+ void addc_byte_rd_rs(u8 rd, u8 rs);
+ void sub_byte_rd_rs(u8 rd, u8 rs);
+ void subb_byte_rd_rs(u8 rd, u8 rs);
+ void cmp_byte_rd_rs(u8 rd, u8 rs);
+ void and_byte_rd_rs(u8 rd, u8 rs);
+ void or_byte_rd_rs(u8 rd, u8 rs);
+ void xor_byte_rd_rs(u8 rd, u8 rs);
+ void mov_byte_rd_rs(u8 rd, u8 rs);
+
+ void add_word_rd_indrs(u8 rd, u8 rs);
+ void addc_word_rd_indrs(u8 rd, u8 rs);
+ void sub_word_rd_indrs(u8 rd, u8 rs);
+ void subb_word_rd_indrs(u8 rd, u8 rs);
+ void cmp_word_rd_indrs(u8 rd, u8 rs);
+ void and_word_rd_indrs(u8 rd, u8 rs);
+ void or_word_rd_indrs(u8 rd, u8 rs);
+ void xor_word_rd_indrs(u8 rd, u8 rs);
+ void mov_word_rd_indrs(u8 rd, u8 rs);
+
+ void add_byte_rd_indrs(u8 rd, u8 rs);
+ void addc_byte_rd_indrs(u8 rd, u8 rs);
+ void sub_byte_rd_indrs(u8 rd, u8 rs);
+ void subb_byte_rd_indrs(u8 rd, u8 rs);
+ void cmp_byte_rd_indrs(u8 rd, u8 rs);
+ void and_byte_rd_indrs(u8 rd, u8 rs);
+ void or_byte_rd_indrs(u8 rd, u8 rs);
+ void xor_byte_rd_indrs(u8 rd, u8 rs);
+ void mov_byte_rd_indrs(u8 rd, u8 rs);
+
+ void add_word_indrd_rs(u8 rd, u8 rs);
+ void addc_word_indrd_rs(u8 rd, u8 rs);
+ void sub_word_indrd_rs(u8 rd, u8 rs);
+ void subb_word_indrd_rs(u8 rd, u8 rs);
+ void cmp_word_indrd_rs(u8 rd, u8 rs);
+ void and_word_indrd_rs(u8 rd, u8 rs);
+ void or_word_indrd_rs(u8 rd, u8 rs);
+ void xor_word_indrd_rs(u8 rd, u8 rs);
+ void mov_word_indrd_rs(u8 rd, u8 rs);
+
+ void add_byte_indrd_rs(u8 rd, u8 rs);
+ void addc_byte_indrd_rs(u8 rd, u8 rs);
+ void sub_byte_indrd_rs(u8 rd, u8 rs);
+ void subb_byte_indrd_rs(u8 rd, u8 rs);
+ void cmp_byte_indrd_rs(u8 rd, u8 rs);
+ void and_byte_indrd_rs(u8 rd, u8 rs);
+ void or_byte_indrd_rs(u8 rd, u8 rs);
+ void xor_byte_indrd_rs(u8 rd, u8 rs);
+ void mov_byte_indrd_rs(u8 rd, u8 rs);
+
+ void add_word_rd_indrsinc(u8 rd, u8 rs);
+ void addc_word_rd_indrsinc(u8 rd, u8 rs);
+ void sub_word_rd_indrsinc(u8 rd, u8 rs);
+ void subb_word_rd_indrsinc(u8 rd, u8 rs);
+ void cmp_word_rd_indrsinc(u8 rd, u8 rs);
+ void and_word_rd_indrsinc(u8 rd, u8 rs);
+ void or_word_rd_indrsinc(u8 rd, u8 rs);
+ void xor_word_rd_indrsinc(u8 rd, u8 rs);
+ void mov_word_rd_indrsinc(u8 rd, u8 rs);
+
+ void add_byte_rd_indrsinc(u8 rd, u8 rs);
+ void addc_byte_rd_indrsinc(u8 rd, u8 rs);
+ void sub_byte_rd_indrsinc(u8 rd, u8 rs);
+ void subb_byte_rd_indrsinc(u8 rd, u8 rs);
+ void cmp_byte_rd_indrsinc(u8 rd, u8 rs);
+ void and_byte_rd_indrsinc(u8 rd, u8 rs);
+ void or_byte_rd_indrsinc(u8 rd, u8 rs);
+ void xor_byte_rd_indrsinc(u8 rd, u8 rs);
+ void mov_byte_rd_indrsinc(u8 rd, u8 rs);
+
+ void add_word_indrdinc_rs(u8 rd, u8 rs);
+ void addc_word_indrdinc_rs(u8 rd, u8 rs);
+ void sub_word_indrdinc_rs(u8 rd, u8 rs);
+ void subb_word_indrdinc_rs(u8 rd, u8 rs);
+ void cmp_word_indrdinc_rs(u8 rd, u8 rs);
+ void and_word_indrdinc_rs(u8 rd, u8 rs);
+ void or_word_indrdinc_rs(u8 rd, u8 rs);
+ void xor_word_indrdinc_rs(u8 rd, u8 rs);
+ void mov_word_indrdinc_rs(u8 rd, u8 rs);
+
+ void add_byte_indrdinc_rs(u8 rd, u8 rs);
+ void addc_byte_indrdinc_rs(u8 rd, u8 rs);
+ void sub_byte_indrdinc_rs(u8 rd, u8 rs);
+ void subb_byte_indrdinc_rs(u8 rd, u8 rs);
+ void cmp_byte_indrdinc_rs(u8 rd, u8 rs);
+ void and_byte_indrdinc_rs(u8 rd, u8 rs);
+ void or_byte_indrdinc_rs(u8 rd, u8 rs);
+ void xor_byte_indrdinc_rs(u8 rd, u8 rs);
+ void mov_byte_indrdinc_rs(u8 rd, u8 rs);
+
+ void add_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void addc_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void sub_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void subb_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void cmp_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void and_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void or_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void xor_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void mov_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+
+ void add_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void addc_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void sub_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void subb_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void cmp_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void and_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void or_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void xor_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+ void mov_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8);
+
+ void add_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void addc_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void sub_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void subb_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void cmp_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void and_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void or_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void xor_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void mov_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+
+ void add_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void addc_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void sub_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void subb_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void cmp_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void and_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void or_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void xor_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+ void mov_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs);
+
+ void add_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void addc_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void sub_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void subb_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void cmp_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void and_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void or_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void xor_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void mov_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+
+ void add_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void addc_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void sub_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void subb_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void cmp_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void and_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void or_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void xor_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+ void mov_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16);
+
+ void add_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void addc_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void sub_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void subb_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void cmp_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void and_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void or_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void xor_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void mov_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+
+ void add_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void addc_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void sub_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void subb_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void cmp_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void and_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void or_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void xor_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+ void mov_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs);
+
+ void add_word_rd_direct(u8 rd, u16 direct);
+ void addc_word_rd_direct(u8 rd, u16 direct);
+ void sub_word_rd_direct(u8 rd, u16 direct);
+ void subb_word_rd_direct(u8 rd, u16 direct);
+ void cmp_word_rd_direct(u8 rd, u16 direct);
+ void and_word_rd_direct(u8 rd, u16 direct);
+ void or_word_rd_direct(u8 rd, u16 direct);
+ void xor_word_rd_direct(u8 rd, u16 direct);
+ void mov_word_rd_direct(u8 rd, u16 direct);
+
+ void add_byte_rd_direct(u8 rd, u16 direct);
+ void addc_byte_rd_direct(u8 rd, u16 direct);
+ void sub_byte_rd_direct(u8 rd, u16 direct);
+ void subb_byte_rd_direct(u8 rd, u16 direct);
+ void cmp_byte_rd_direct(u8 rd, u16 direct);
+ void and_byte_rd_direct(u8 rd, u16 direct);
+ void or_byte_rd_direct(u8 rd, u16 direct);
+ void xor_byte_rd_direct(u8 rd, u16 direct);
+ void mov_byte_rd_direct(u8 rd, u16 direct);
+
+ void add_word_direct_rs(u16 direct, u8 rs);
+ void addc_word_direct_rs(u16 direct, u8 rs);
+ void sub_word_direct_rs(u16 direct, u8 rs);
+ void subb_word_direct_rs(u16 direct, u8 rs);
+ void cmp_word_direct_rs(u16 direct, u8 rs);
+ void and_word_direct_rs(u16 direct, u8 rs);
+ void or_word_direct_rs(u16 direct, u8 rs);
+ void xor_word_direct_rs(u16 direct, u8 rs);
+ void mov_word_direct_rs(u16 direct, u8 rs);
+
+ void add_byte_direct_rs(u16 direct, u8 rs);
+ void addc_byte_direct_rs(u16 direct, u8 rs);
+ void sub_byte_direct_rs(u16 direct, u8 rs);
+ void subb_byte_direct_rs(u16 direct, u8 rs);
+ void cmp_byte_direct_rs(u16 direct, u8 rs);
+ void and_byte_direct_rs(u16 direct, u8 rs);
+ void or_byte_direct_rs(u16 direct, u8 rs);
+ void xor_byte_direct_rs(u16 direct, u8 rs);
+ void mov_byte_direct_rs(u16 direct, u8 rs);
+
+ void movs_word_rd_data4(u8 rd, u8 data4);
+ void movs_byte_rd_data4(u8 rd, u8 data4);
+ void adds_word_rd_data4(u8 rd, u8 data4);
+ void adds_byte_rd_data4(u8 rd, u8 data4);
+
+ void movs_word_indrd_data4(u8 rd, u8 data4);
+ void movs_byte_indrd_data4(u8 rd, u8 data4);
+ void adds_word_indrd_data4(u8 rd, u8 data4);
+ void adds_byte_indrd_data4(u8 rd, u8 data4);
+
+ void movs_word_indrdinc_data4(u8 rd, u8 data4);
+ void movs_byte_indrdinc_data4(u8 rd, u8 data4);
+ void adds_word_indrdinc_data4(u8 rd, u8 data4);
+ void adds_byte_indrdinc_data4(u8 rd, u8 data4);
+
+ void movs_word_indrdoff8_data4(u8 rd, u8 off8, u8 data4);
+ void movs_byte_indrdoff8_data4(u8 rd, u8 off8, u8 data4);
+ void adds_word_indrdoff8_data4(u8 rd, u8 off8, u8 data4);
+ void adds_byte_indrdoff8_data4(u8 rd, u8 off8, u8 data4);
+
+ void movs_word_indrdoff16_data4(u8 rd, u16 off16, u8 data4);
+ void movs_byte_indrdoff16_data4(u8 rd, u16 off16, u8 data4);
+ void adds_word_indrdoff16_data4(u8 rd, u16 off16, u8 data4);
+ void adds_byte_indrdoff16_data4(u8 rd, u16 off16, u8 data4);
+
+ void movs_word_direct_data4(u16 direct, u8 data4);
+ void movs_byte_direct_data4(u16 direct, u8 data4);
+ void adds_word_direct_data4(u16 direct, u8 data4);
+ void adds_byte_direct_data4(u16 direct, u8 data4);
+
+ void call_rel16(u16 rel16);
+
+ void bcc_rel8(u8 rel8);
+ void bcs_rel8(u8 rel8);
+ void bne_rel8(u8 rel8);
+ void beq_rel8(u8 rel8);
+ void bnv_rel8(u8 rel8);
+ void bov_rel8(u8 rel8);
+ void bpl_rel8(u8 rel8);
+ void bmi_rel8(u8 rel8);
+ void bg_rel8(u8 rel8);
+ void bl_rel8(u8 rel8);
+ void bge_rel8(u8 rel8);
+ void blt_rel8(u8 rel8);
+ void bgt_rel8(u8 rel8);
+ void ble_rel8(u8 rel8);
+ void br_rel8(u8 rel8);
+
+ void asl_byte_rd_imm4(u8 rd, u8 amount);
+ void asl_word_rd_imm4(u8 rd, u8 amount);
+ void asl_dword_rd_imm5(u8 rd, u8 amount);
+
+ void asr_byte_rd_imm4(u8 rd, u8 amount);
+ void asr_word_rd_imm4(u8 rd, u8 amount);
+ void asr_dword_rd_imm5(u8 rd, u8 amount);
+
+ void lsr_byte_rd_imm4(u8 rd, u8 amount);
+ void lsr_word_rd_imm4(u8 rd, u8 amount);
+ void lsr_dword_rd_imm5(u8 rd, u8 amount);
+
+ void asl_byte_rd_rs(u8 rd, u8 rs);
+ void asl_word_rd_rs(u8 rd, u8 rs);
+ void asl_dword_rd_rs(u8 rd, u8 rs);
+
+ void asr_byte_rd_rs(u8 rd, u8 rs);
+ void asr_word_rd_rs(u8 rd, u8 rs);
+ void asr_dword_rd_rs(u8 rd, u8 rs);
+
+ void lsr_byte_rd_rs(u8 rd, u8 rs);
+ void lsr_word_rd_rs(u8 rd, u8 rs);
+ void lsr_dword_rd_rs(u8 rd, u8 rs);
+
+ void norm_byte_rd_rs(u8 rd, u8 rs);
+ void norm_word_rd_rs(u8 rd, u8 rs);
+ void norm_dword_rd_rs(u8 rd, u8 rs);
+
+ void mulu_byte_rd_rs(u8 rd, u8 rs);
+ void divu_byte_rd_rs(u8 rd, u8 rs);
+ void mulu_word_rd_rs(u8 rd, u8 rs);
+ void divu_word_rd_rs(u8 rd, u8 rs);
+ void mul_word_rd_rs(u8 rd, u8 rs);
+ void div_word_rd_rs(u8 rd, u8 rs);
+ void div_word_rd_data8(u8 rd, u8 data8);
+ void divu_byte_rd_data8(u8 rd, u8 data8);
+ void divu_word_rd_data8(u8 rd, u8 data8);
+ void mulu_byte_rd_data8(u8 rd, u8 data8);
+ void mulu_word_rd_data16(u8 rd, u16 data16);
+ void mul_word_rd_data16(u8 rd, u16 data16);
+ void divu_dword_rd_data16(u8 rd, u16 data16);
+ void div_dword_rd_data16(u8 rd, u16 data16);
+ void divu_dword_rd_rs(u8 rd, u8 rs);
+ void div_dword_rd_rs(u8 rd, u8 rs);
+
+ void clr_bit(u16 bit);
+ void setb_bit(u16 bit);
+ void mov_c_bit(u16 bit);
+ void mov_bit_c(u16 bit);
+ void anl_c_bit(u16 bit);
+ void anl_c_notbit(u16 bit);
+ void orl_c_bit(u16 bit);
+ void orl_c_notbit(u16 bit);
+
+ void lea_word_rd_rs_off8(u8 rd, u8 rs, u8 offs8);
+ void lea_word_rd_rs_off16(u8 rd, u8 rs, u16 offs16);
+
+ void xch_word_rd_indrs(u8 rd, u8 rs);
+ void xch_byte_rd_indrs(u8 rd, u8 rs);
+ void xch_word_rd_rs(u8 rd, u8 rs);
+ void xch_byte_rd_rs(u8 rd, u8 rs);
+
+ void movc_word_rd_indrsinc(u8 rd, u8 rs);
+ void movc_byte_rd_indrsinc(u8 rd, u8 rs);
+
+ void djnz_word_rd_rel8(u8 rd, u8 rel8);
+ void djnz_byte_rd_rel8(u8 rd, u8 rel8);
+
+ void popu_word_direct(u16 direct);
+ void popu_byte_direct(u16 direct);
+ void pop_word_direct(u16 direct);
+ void pop_byte_direct(u16 direct);
+ void pushu_word_direct(u16 direct);
+ void pushu_byte_direct(u16 direct);
+ void push_word_direct(u16 direct);
+ void push_byte_direct(u16 direct);
+
+ void mov_word_indrdinc_indrsinc(u8 rd, u8 rs);
+ void mov_byte_indrdinc_indrsinc(u8 rd, u8 rs);
+
+ void da_rd(u8 rd);
+ void sext_word_rd(u8 rd);
+ void sext_byte_rd(u8 rd);
+ void cpl_word_rd(u8 rd);
+ void cpl_byte_rd(u8 rd);
+ void neg_word_rd(u8 rd);
+ void neg_byte_rd(u8 rd);
+ void movc_a_apc();
+ void movc_a_adptr();
+ void mov_rd_usp(u8 rd);
+ void mov_usp_rs(u8 rs);
+
+ void jb_bit_rel8(u16 bit, u8 rel8);
+ void jnb_bit_rel8(u16 bit, u8 rel8);
+ void jbc_bit_rel8(u16 bit, u8 rel8);
+
+ void mov_word_direct_direct(u16 direct1, u16 direct2);
+ void mov_byte_direct_direct(u16 direct1, u16 direct2);
+
+ void xch_word_rd_direct(u8 rd, u16 direct);
+ void xch_byte_rd_direct(u8 rd, u16 direct);
+
+ void mov_word_direct_indrs(u16 direct, u8 rs);
+ void mov_byte_direct_indrs(u16 direct, u8 rs);
+
+ void mov_word_indrd_direct(u8 rd, u16 direct);
+ void mov_byte_indrd_direct(u8 rd, u16 direct);
+
+ void movx_word_indrd_rs(u8 rd, u8 rs);
+ void movx_byte_indrd_rs(u8 rd, u8 rs);
+
+ void movx_word_rd_indrs(u8 rd, u8 rs);
+ void movx_byte_rd_indrs(u8 rd, u8 rs);
+
+ void rr_word_rd_data4(u8 rd, u8 data4);
+ void rr_byte_rd_data4(u8 rd, u8 data4);
+
+ void rrc_word_rd_data4(u8 rd, u8 data4);
+ void rrc_byte_rd_data4(u8 rd, u8 data4);
+
+ void rl_word_rd_data4(u8 rd, u8 data4);
+ void rl_byte_rd_data4(u8 rd, u8 data4);
+
+ void rlc_word_rd_data4(u8 rd, u8 data4);
+ void rlc_byte_rd_data4(u8 rd, u8 data4);
+
+ void fcall_addr24(u32 addr24);
+ void call_indrs(u8 rs);
+ void fjmp_addr24(u32 addr24);
+ void jmp_rel16(u16 rel16);
+
+ void djnz_word_direct_rel8(u16 direct, u8 rel8);
+ void djnz_byte_direct_rel8(u16 direct, u8 rel8);
+
+ void cjne_word_rd_direct_rel8(u8 rd, u16 direct, u8 rel8);
+ void cjne_byte_rd_direct_rel8(u8 rd, u16 direct, u8 rel8);
+
+ void cjne_indrd_data8_rel8(u8 rd, u8 data8, u8 rel8);
+ void cjne_rd_data8_rel8(u8 rd, u8 data8, u8 rel8);
+
+ void cjne_indrd_data16_rel8(u8 rd, u16 data16, u8 rel8);
+ void cjne_rd_data16_rel8(u8 rd, u16 data16, u8 rel8);
+
+ void reset();
+ void trap_data4(u8 data4);
+ void jmp_ind_adptr();
+ void jmp_dblindrs(u8 rs);
+ void jmp_indrs(u8 rs);
+ void ret();
+ void reti();
+
+ void jz_rel8(u8 rel8);
+ void jnz_rel8(u8 rel8);
+
+ void push_word_rlist(u8 bitfield, int h);
+ void push_byte_rlist(u8 bitfield, int h);
+
+ void pushu_word_rlist(u8 bitfield, int h);
+ void pushu_byte_rlist(u8 bitfield, int h);
+
+ void pop_word_rlist(u8 bitfield, int h);
+ void pop_byte_rlist(u8 bitfield, int h);
+
+ void popu_word_rlist(u8 bitfield, int h);
+ void popu_byte_rlist(u8 bitfield, int h);
+
+ std::unordered_map<offs_t, const char *> m_names;
+
+ u8 m_im;
+ u8 m_rs;
+ u8 m_zflag;
+ u8 m_nflag;
+ u8 m_vflag;
+ u8 m_cflag;
+ u8 m_acflag;
+ u8 m_sm_flag;
+ u8 m_tm_flag;
+ u8 m_p_flag;
+ u8 m_f0_flag;
+ u8 m_f1_flag;
uint32_t m_pc;
+ bool m_usermode;
+ u8 m_pagezeromode;
+
+ u16 m_USP; // user stack pointer
+ u16 m_SSP; // system stack pointer
+
+ u8 m_WDCON;
+ u8 m_SCR;
+ u8 m_IEL;
+ u8 m_PSWL;
+ u8 m_PSWH;
+
+ u8 m_regbank;
+
+ u8 m_PxCFGA[4];
+ u8 m_PxCFGB[4];
+
+ // hacks for IRQ testing
+ u8 m_in_interrupt;
+ u8 m_irq_pending;
+
+
+ // 16-bit regs R0-R3 can have 4 selectable banks, R4-R7 are global
+ // for 8-bit use each register can be seen as High and Low parts
+ // R4 when split is R4H and R4L, R4L acts as ACC from i8051 for compatibility, R4H acts as B
+ // R6H is DPH, R6L is DPL
+ u16 m_regs[(4 * 4) + 4];
+
address_space *m_program;
+ address_space *m_data;
+ address_space *m_sfr;
int m_icount;
+
+ devcb_read8::array<4> m_port_in_cb;
+ devcb_write8::array<4> m_port_out_cb;
};
-class mx10exa_cpu_device : public xa_cpu_device
+class mx10exa_cpu_device : public xa_cpu
{
public:
mx10exa_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
private:
void mx10exa_internal_map(address_map &map);
+ void mx10exa_internal_data_map(address_map &map);
+
};
-DECLARE_DEVICE_TYPE(XA, xa_cpu_device)
+DECLARE_DEVICE_TYPE(XA, xa_cpu)
DECLARE_DEVICE_TYPE(MX10EXA, mx10exa_cpu_device)
#endif // MAME_CPU_XA_XA_H
diff --git a/src/devices/cpu/xa/xa_ops.cpp b/src/devices/cpu/xa/xa_ops.cpp
new file mode 100644
index 00000000000..ae803581380
--- /dev/null
+++ b/src/devices/cpu/xa/xa_ops.cpp
@@ -0,0 +1,1893 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "xa.h"
+#include "xadasm.h"
+
+#define get_addr gr16
+#define set_addr sr16
+
+u32 xa_cpu::gr32(int reg)
+{
+ if (reg & 1)
+ fatalerror("gr32 with low bit set\n");
+
+ u16 reg1 = gr16(reg);
+ u16 reg2 = gr16(reg + 1);
+
+ return (reg2 << 16) | reg1;
+}
+
+void xa_cpu::sr32(int reg, u32 data)
+{
+ if (reg & 1)
+ fatalerror("sr32 with low bit set\n");
+
+ sr16(reg, data & 0xffff);
+ sr16(reg + 1, (data >> 16) & 0xffff);
+}
+
+u16 xa_cpu::do_subb_16(u16 val1, u16 val2)
+{
+ return do_sub_16_helper(val1, val2, get_c_flag());
+}
+
+u16 xa_cpu::do_sub_16(u16 val1, u16 val2)
+{
+ return do_sub_16_helper(val1, val2, 0);
+}
+
+u16 xa_cpu::do_sub_16_helper(u16 val1, u16 val2, u8 c)
+{
+ u32 result = val1 - (val2 + c);
+ s32 result1 = (s16)val1 - (s16)(val2 + c);
+ u32 result3 = (val1 & 0x0fff) - ((val2 & 0x0fff) + c);
+
+ if (result & 0x10000) set_c_flag(); else clear_c_flag();
+ if (result3 & 0x1000) set_ac_flag(); else clear_ac_flag();
+ if ((result1 < -32768 || result1 > 32767)) set_v_flag(); else clear_v_flag();
+
+ do_nz_flags_16((u16)result);
+ return (u16)result;
+}
+
+
+u16 xa_cpu::do_addc_16(u16 val1, u16 val2)
+{
+ return do_add_16_helper(val1, val2, get_c_flag());
+}
+
+u16 xa_cpu::do_add_16(u16 val1, u16 val2)
+{
+ return do_add_16_helper(val1, val2, 0);
+}
+
+
+u16 xa_cpu::do_add_16_helper(u16 val1, u16 val2, u8 c)
+{
+ u32 result = val1 + val2 + c;
+ s32 result1 = (s16)val1 + (s16)val2 + c;
+ u32 result3 = (val1 & 0x0fff) + (val2 & 0x0fff) + c;
+ if (result & 0x10000) set_c_flag(); else clear_c_flag();
+ if (result3 & 0x1000) set_ac_flag(); else clear_ac_flag();
+ if ((result1 < -32768 || result1 > 32767)) set_v_flag(); else clear_v_flag();
+
+ do_nz_flags_16((u16)result);
+ return (u16)result;
+}
+
+
+u16 xa_cpu::do_xor_16(u16 val1, u16 val2)
+{
+ u16 result = val1 ^ val2;
+ do_nz_flags_16(result);
+ return result;
+}
+
+u16 xa_cpu::do_or_16(u16 val1, u16 val2)
+{
+ u16 result = val1 | val2;
+ do_nz_flags_16(result);
+ return result;
+}
+
+u16 xa_cpu::do_and_16(u16 val1, u16 val2)
+{
+ u16 result = val1 & val2;
+ do_nz_flags_16(result);
+ return result;
+}
+
+u32 xa_cpu::asl32_helper(u32 fullreg, u8 amount)
+{
+ cy(6 + (amount >> 1));
+
+ int lastbit = 0;
+
+ u32 topbit = fullreg & 0x8000000;
+
+ while (amount)
+ {
+ lastbit = fullreg & 0x8000000;
+ fullreg = fullreg << 1;
+ amount--;
+ }
+
+ if (lastbit)
+ set_c_flag();
+ else
+ clear_c_flag();
+
+ if (fullreg == 0)
+ set_z_flag();
+ else
+ clear_z_flag();
+
+ if (fullreg & 0x8000000)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ if (topbit != (fullreg & 0x8000000))
+ set_v_flag();
+ else
+ clear_v_flag();
+
+ return fullreg;
+}
+
+u32 xa_cpu::lsr32_helper(u32 fullreg, u8 amount)
+{
+ cy(6 + (amount >> 1));
+
+ int lastbit = 0;
+
+ while (amount)
+ {
+ lastbit = fullreg & 0x0000001;
+ fullreg = fullreg >> 1;
+ amount--;
+ }
+
+ if (lastbit)
+ set_c_flag();
+ else
+ clear_c_flag();
+
+ if (fullreg == 0)
+ set_z_flag();
+ else
+ clear_z_flag();
+
+ if (fullreg & 0x8000000)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ return fullreg;
+}
+
+u16 xa_cpu::lsr16_helper(u16 fullreg, u8 amount)
+{
+ cy(6 + (amount >> 1));
+
+ int lastbit = 0;
+
+ while (amount)
+ {
+ lastbit = fullreg & 0x0001;
+ fullreg = fullreg >> 1;
+ amount--;
+ }
+
+ if (lastbit)
+ set_c_flag();
+ else
+ clear_c_flag();
+
+ if (fullreg == 0)
+ set_z_flag();
+ else
+ clear_z_flag();
+
+ if (fullreg & 0x8000)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ return fullreg;
+}
+
+
+u8 xa_cpu::do_subb_8(u8 val1, u8 val2)
+{
+ return do_sub_8_helper(val1, val2, get_c_flag());
+}
+
+u8 xa_cpu::do_sub_8(u8 val1, u8 val2)
+{
+ return do_sub_8_helper(val1, val2, 0);
+}
+
+u8 xa_cpu::do_sub_8_helper(u8 val1, u8 val2, u8 c)
+{
+ u16 result = val1 - (val2 + c);
+ s16 result1 = (s8)val1 - (s8)(val2 + c);
+ u16 result3 = (val1 & 0x0f) - ((val2 & 0x0f) + c);
+ if (result & 0x100) set_c_flag(); else clear_c_flag();
+ if (result3 & 0x10) set_ac_flag(); else clear_ac_flag();
+ if ((result1 < -128 || result1 > 127)) set_v_flag(); else clear_v_flag();
+
+ do_nz_flags_8((u8)result);
+ return (u8)result;
+}
+
+u8 xa_cpu::do_addc_8(u8 val1, u8 val2)
+{
+ return do_add_8_helper(val1, val2, get_c_flag());
+}
+
+u8 xa_cpu::do_add_8(u8 val1, u8 val2)
+{
+ return do_add_8_helper(val1, val2, 0);
+}
+
+
+u8 xa_cpu::do_add_8_helper(u8 val1, u8 val2, u8 c)
+{
+ u16 result = val1 + val2 + c;
+ s16 result1 = (s8)val1 + (s8)val2 + c;
+ u16 result3 = (val1 & 0x0f) + (val2 & 0x0f) + c;
+ if (result & 0x100) set_c_flag(); else clear_c_flag();
+ if (result3 & 0x10) set_ac_flag(); else clear_ac_flag();
+ if ((result1 < -128 || result1 > 127)) set_v_flag(); else clear_v_flag();
+
+ do_nz_flags_8((u8)result);
+ return (u8)result;
+}
+
+u8 xa_cpu::do_xor_8(u8 val1, u8 val2)
+{
+ u8 result = val1 ^ val2;
+ do_nz_flags_8(result);
+ return result;
+}
+
+u8 xa_cpu::do_or_8(u8 val1, u8 val2)
+{
+ u8 result = val1 | val2;
+ do_nz_flags_8(result);
+ return result;
+}
+
+u8 xa_cpu::do_and_8(u8 val1, u8 val2)
+{
+ u8 result = val1 & val2;
+ do_nz_flags_8(result);
+ return result;
+}
+
+
+
+u8 xa_cpu::do_cjne_8_helper(u8 val1, u8 val2)
+{
+ u16 result = val1 - val2;
+ do_nz_flags_8((u8)result);
+ if (result & 0x100) set_c_flag(); else clear_c_flag();
+ return (u8)result;
+}
+
+
+void xa_cpu::set_bit_8_helper(u16 bit, u8 val)
+{
+ int position = bit & 7;
+
+ if (bit < 0x100)
+ {
+ int reg = ((bit & 0x1ff) >> 3);
+
+ if (reg < 16)
+ fatalerror("set_bit_helper %s.%d", m_regnames8[reg], position);
+ else
+ fatalerror("set_bit_helper ill_REG_%02x.%d", reg, position);
+ }
+ else if (bit < 0x200)
+ {
+ int addr = ((bit & 0x1ff) >> 3) + 0x20;
+ fatalerror("set_bit_helper $%02x.%d", addr, position);
+ }
+
+ int sfr = ((bit & 0x1ff) >> 3);
+ u8 mask = (1 << position) ^ 0xff;
+
+ u8 sfr_val = m_sfr->read_byte(sfr) & mask;
+ sfr_val |= (val << position);
+ m_sfr->write_byte(sfr, sfr_val);
+}
+
+// NOP No operation 1 3 0000 0000
+void xa_cpu::do_nop() { cy(3); }
+
+// ALUOP.b Rd, data8
+// ADD Rd, #data8 Add 8-bit imm data to reg 3 3 1001 0001 dddd 0000 iiii iiii
+// ADDC Rd, #data8 Add 8-bit imm data to reg w/ carry 3 3 1001 0001 dddd 0001 iiii iiii
+// SUB Rd, #data8 Subtract 8-bit imm data to reg 3 3 1001 0001 dddd 0010 iiii iiii
+// SUBB Rd, #data8 Subtract w/ borrow 8-bit imm data to reg 3 3 1001 0001 dddd 0011 iiii iiii
+// CMP Rd, #data8 Compare 8-bit imm data to reg 3 3 1001 0001 dddd 0100 iiii iiii
+// AND Rd, #data8 Logical AND 8-bit imm data to reg 3 3 1001 0001 dddd 0101 iiii iiii
+// OR Rd, #data8 Logical OR 8-bit imm data to reg 3 3 1001 0001 dddd 0110 iiii iiii
+// XOR Rd, #data8 Logical XOR 8-bit imm data to reg 3 3 1001 0001 dddd 0111 iiii iiii
+// MOV Rd, #data8 Move 8-bit imm data to reg 3 3 1001 0001 dddd 1000 iiii iiii
+void xa_cpu::aluop_byte_rd_data8(int alu_op, u8 rd, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_data8(rd, data8); break;
+ case 0x1: addc_byte_rd_data8(rd, data8); break;
+ case 0x2: sub_byte_rd_data8(rd, data8); break;
+ case 0x3: subb_byte_rd_data8(rd, data8); break;
+ case 0x4: cmp_byte_rd_data8(rd, data8); break;
+ case 0x5: and_byte_rd_data8(rd, data8); break;
+ case 0x6: or_byte_rd_data8(rd, data8); break;
+ case 0x7: xor_byte_rd_data8(rd, data8); break;
+ case 0x8: mov_byte_rd_data8(rd, data8); break;
+ default: logerror("UNK_ALUOP.b %s, #$%02x", m_regnames8[rd], data8); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); u8 result = do_add_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::addc_byte_rd_data8(u8 rd, u8 data8){ u8 rdval = gr8(rd); u8 result = do_addc_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::sub_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); u8 result = do_sub_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::subb_byte_rd_data8(u8 rd, u8 data8){ u8 rdval = gr8(rd); u8 result = do_subb_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::cmp_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); do_sub_8(rdval, data8); cy(3); }
+void xa_cpu::and_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); u8 result = do_and_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::or_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); u8 result = do_or_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::xor_byte_rd_data8(u8 rd, u8 data8) { u8 rdval = gr8(rd); u8 result = do_xor_8(rdval, data8); sr8(rd, result); cy(3); }
+void xa_cpu::mov_byte_rd_data8(u8 rd, u8 data8) { u8 result = data8; do_nz_flags_8(result); sr8(rd, result); cy(3); }
+
+// ------------------------------------------
+
+// ALUOP.b [Rd], data8
+// ADD [Rd], #data8 Add 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0000 iiii iiii
+// ADDC [Rd], #data8 Add 16-bit imm data to reg-ind w/ carry 3 4 1001 0010 0ddd 0001 iiii iiii
+// SUB [Rd], #data8 Subtract 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0010 iiii iiii
+// SUBB [Rd], #data8 Subtract w/ borrow 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0011 iiii iiii
+// CMP [Rd], #data8 Compare 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0100 iiii iiii
+// AND [Rd], #data8 Logical AND 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0101 iiii iiii
+// OR [Rd], #data8 Logical OR 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0110 iiii iiii
+// XOR [Rd], #data8 Logical XOR 8-bit imm data to reg-ind 3 4 1001 0010 0ddd 0111 iiii iiii
+// MOV [Rd], #data8 Move 16-bit imm data to reg-ind 3 3 1001 0010 0ddd 1000 iiii iiii
+void xa_cpu::aluop_byte_indrd_data8(int alu_op, u8 rd, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrd_data8(rd, data8); break;
+ case 0x1: addc_byte_indrd_data8(rd, data8); break;
+ case 0x2: sub_byte_indrd_data8(rd, data8); break;
+ case 0x3: subb_byte_indrd_data8(rd, data8); break;
+ case 0x4: cmp_byte_indrd_data8(rd, data8); break;
+ case 0x5: and_byte_indrd_data8(rd, data8); break;
+ case 0x6: or_byte_indrd_data8(rd, data8); break;
+ case 0x7: xor_byte_indrd_data8(rd, data8); break;
+ case 0x8: mov_byte_indrd_data8(rd, data8); break;
+ default: logerror("UNK_ALUOP.b [%s], #$%02x", m_regnames16[rd], data8); do_nop(); break;
+ }
+}
+void xa_cpu::add_byte_indrd_data8(u8 rd, u8 data8) { fatalerror( "ADD.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::addc_byte_indrd_data8(u8 rd, u8 data8){ fatalerror( "ADDC.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::sub_byte_indrd_data8(u8 rd, u8 data8) { fatalerror( "SUB.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::subb_byte_indrd_data8(u8 rd, u8 data8){ fatalerror( "SUBB.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::cmp_byte_indrd_data8(u8 rd, u8 data8) { u16 address = get_addr(rd); u8 rdval = rdat8(address); do_sub_8(rdval, data8); cy(3); }
+void xa_cpu::and_byte_indrd_data8(u8 rd, u8 data8) { u16 address = get_addr(rd); u8 rdval = rdat8(address); u8 result = do_and_8(rdval, data8); wdat8(address, result); cy(3); }
+void xa_cpu::or_byte_indrd_data8(u8 rd, u8 data8) { fatalerror( "OR.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::xor_byte_indrd_data8(u8 rd, u8 data8) { fatalerror( "XOR.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::mov_byte_indrd_data8(u8 rd, u8 data8) { fatalerror( "MOV.b [%s], #$%02x ([RD], DATA8)", m_regnames16[rd], data8 ); }
+
+// ------------------------------------------
+// ALUOP.b [Rd+], data8
+// ADD [Rd+], #data8 Add 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0000 iiii iiii
+// ADDC [Rd+], #data8 Add 8-bit imm data to reg-ind and autoinc w/ carry 3 5 1001 0011 0ddd 0001 iiii iiii
+// SUB [Rd+], #data8 Subtract 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0010 iiii iiii
+// SUBB [Rd+], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0011 iiii iiii
+// CMP [Rd+], #data8 Compare 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0100 iiii iiii
+// AND [Rd+], #data8 Logical AND 8-bit imm data to reg-ind and autoinc 3 5 1001 0011 0ddd 0101 iiii iiii
+// OR [Rd+], #data8 Logical OR 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0110 iiii iiii
+// XOR [Rd+], #data8 Logical XOR 8-bit imm data to reg-ind w/ autoinc 3 5 1001 0011 0ddd 0111 iiii iiii
+// MOV [Rd+], #data8 Move 8-bit imm data to reg-ind w/ autoinc 3 4 1001 0011 0ddd 1000 iiii iiii
+void xa_cpu::aluop_byte_indrdinc_data8(int alu_op, u8 rd, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrdinc_data8(rd, data8); break;
+ case 0x1: addc_byte_indrdinc_data8(rd, data8); break;
+ case 0x2: sub_byte_indrdinc_data8(rd, data8); break;
+ case 0x3: subb_byte_indrdinc_data8(rd, data8); break;
+ case 0x4: cmp_byte_indrdinc_data8(rd, data8); break;
+ case 0x5: and_byte_indrdinc_data8(rd, data8); break;
+ case 0x6: or_byte_indrdinc_data8(rd, data8); break;
+ case 0x7: xor_byte_indrdinc_data8(rd, data8); break;
+ case 0x8: mov_byte_indrdinc_data8(rd, data8); break;
+ default: logerror("UNK_ALUOP.b [%s+], #$%02x", m_regnames16[rd], data8); do_nop(); break;
+ }
+}
+void xa_cpu::add_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "ADD.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::addc_byte_indrdinc_data8(u8 rd, u8 data8){ fatalerror( "ADDC.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::sub_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "SUB.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::subb_byte_indrdinc_data8(u8 rd, u8 data8){ fatalerror( "SUBB.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::cmp_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "CMP.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::and_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "AND.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::or_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "OR.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::xor_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "XOR.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+void xa_cpu::mov_byte_indrdinc_data8(u8 rd, u8 data8) { fatalerror( "MOV.b [%s+], #$%02x ([RD+], DATA8)", m_regnames16[rd], data8 ); }
+
+// ------------------------------------------
+// ALUOP.b [Rd+offs8], data8
+// ADD [Rd+offset8], #data8 Add 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0000 oooo oooo iiii iiii
+// ADDC [Rd+offset8], #data8 Add 8-bit imm data to reg-ind w/ 8-bit offs and carry 4 6 1001 0100 0ddd 0001 oooo oooo iiii iiii
+// SUB [Rd+offset8], #data8 Subtract 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0010 oooo oooo iiii iiii
+// SUBB [Rd+offset8], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0011 oooo oooo iiii iiii
+// CMP [Rd+offset8], #data8 Compare 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0100 oooo oooo iiii iiii
+// AND [Rd+offset8], #data8 Logical AND 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0101 oooo oooo iiii iiii
+// OR [Rd+offset8], #data8 Logical OR 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0110 oooo oooo iiii iiii
+// XOR [Rd+offset8], #data8 Logical XOR 8-bit imm data to reg-ind w/ 8-bit offs 4 6 1001 0100 0ddd 0111 oooo oooo iiii iiii
+// MOV [Rd+offset8], #data8 Move 8-bit imm data to reg-ind w/ 8-bit offs 4 5 1001 0100 0ddd 1000 oooo oooo iiii iiii
+void xa_cpu::aluop_byte_rdoff8_data8(int alu_op, u8 rd, u8 offset8, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x1: addc_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x2: sub_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x3: subb_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x4: cmp_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x5: and_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x6: or_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x7: xor_byte_indrdoff8_data8(rd, offset8, data8); break;
+ case 0x8: mov_byte_indrdoff8_data8(rd, offset8, data8); break;
+ default: logerror("UNK_ALUOP.b [%s+#$%02x], #$%02x", m_regnames16[rd], offset8, data8); do_nop(); break;
+ }
+}
+void xa_cpu::add_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_add_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::addc_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8){ u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_addc_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::sub_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_sub_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::subb_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8){ u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_subb_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::cmp_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); do_sub_8(val, data8); cy(6); }
+void xa_cpu::and_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_and_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::or_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_or_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::xor_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_xor_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::mov_byte_indrdoff8_data8(u8 rd, u8 offset8, u8 data8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; do_nz_flags_8(data8); wdat8(address, data8); cy(5); }
+
+// ------------------------------------------
+// ALUOP.b [Rd+offs16], data8
+// ADD [Rd+offset16], #data8 Add 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0000 oooo oooo oooo oooo iiii iiii
+// ADDC [Rd+offset16], #data8 Add 8-bit imm data to reg-ind w/ 16-bit offs and carry 5 6 1001 0101 0ddd 0001 oooo oooo oooo oooo iiii iiii
+// SUB [Rd+offset16], #data8 Subtract 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0010 oooo oooo oooo oooo iiii iiii
+// SUBB [Rd+offset16], #data8 Subtract w/ borrow 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0011 oooo oooo oooo oooo iiii iiii
+// CMP [Rd+offset16], #data8 Compare 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0100 oooo oooo oooo oooo iiii iiii
+// AND [Rd+offset16], #data8 Logical AND 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0101 oooo oooo oooo oooo iiii iiii
+// OR [Rd+offset16], #data8 Logical OR 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0110 oooo oooo oooo oooo iiii iiii
+// XOR [Rd+offset16], #data8 Logical XOR 8-bit imm data to reg-ind w/ 16-bit offs 5 6 1001 0101 0ddd 0111 oooo oooo oooo oooo iiii iiii
+// MOV [Rd+offset16], #data8 Move 8-bit imm data to reg-ind w/ 16-bit offs 5 5 1001 0101 0ddd 1000 oooo oooo oooo oooo iiii iiii
+void xa_cpu::aluop_byte_rdoff16_data8(int alu_op, u8 rd, u16 offset16, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x1: addc_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x2: sub_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x3: subb_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x4: cmp_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x5: and_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x6: or_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x7: xor_byte_indrdoff16_data8(rd, offset16, data8); break;
+ case 0x8: mov_byte_indrdoff16_data8(rd, offset16, data8); break;
+ default: logerror("UNK_ALUOP.b [%s+#$%04x], #$%02d", m_regnames16[rd], offset16, data8); do_nop(); break;
+ }
+}
+void xa_cpu::add_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_add_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::addc_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8){ u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_addc_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::sub_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_sub_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::subb_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8){ u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_subb_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::cmp_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); do_sub_8(val, data8); cy(6); }
+void xa_cpu::and_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_and_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::or_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_or_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::xor_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u8 val = rdat8(address); u8 result = do_xor_8(val, data8); wdat8(address, result); cy(6); }
+void xa_cpu::mov_byte_indrdoff16_data8(u8 rd, u16 offset16, u8 data8) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; do_nz_flags_8(data8); wdat8(address, data8); cy(5); }
+
+// ------------------------------------------
+// ADD direct, #data8 Add 8-bit imm data to mem 4 4 1001 0110 0DDD 0000 DDDD DDDD iiii iiii
+// ADDC direct, #data8 Add 8-bit imm data to mem w/ carry 4 4 1001 0110 0DDD 0001 DDDD DDDD iiii iiii
+// SUB direct, #data8 Subtract 8-bit imm data to mem 4 4 1001 0110 0DDD 0010 DDDD DDDD iiii iiii
+// SUBB direct, #data8 Subtract w/ borrow 8-bit imm data to mem 4 4 1001 0110 0DDD 0011 DDDD DDDD iiii iiii
+// CMP direct, #data8 Compare 8-bit imm data to mem 4 4 1001 0110 0DDD 0100 DDDD DDDD iiii iiii
+// AND direct, #data8 Logical AND 8-bit imm data to mem 4 4 1001 0110 0DDD 0101 DDDD DDDD iiii iiii
+// OR direct, #data8 Logical OR 8-bit imm data to mem 4 4 1001 0110 0DDD 0110 DDDD DDDD iiii iiii
+// XOR direct, #data8 Logical XOR 8-bit imm data to mem 4 4 1001 0110 0DDD 0111 DDDD DDDD iiii iiii
+// MOV direct, #data8 Move 8-bit imm data to mem 4 3 1001 0110 0DDD 1000 DDDD DDDD iiii iiii
+void xa_cpu::aluop_byte_direct_data8(int alu_op, u16 direct, u8 data8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_direct_data8(direct, data8); break;
+ case 0x1: addc_byte_direct_data8(direct, data8); break;
+ case 0x2: sub_byte_direct_data8(direct, data8); break;
+ case 0x3: subb_byte_direct_data8(direct, data8); break;
+ case 0x4: cmp_byte_direct_data8(direct, data8); break;
+ case 0x5: and_byte_direct_data8(direct, data8); break;
+ case 0x6: or_byte_direct_data8(direct, data8); break;
+ case 0x7: xor_byte_direct_data8(direct, data8); break;
+ case 0x8: mov_byte_direct_data8(direct, data8); break;
+ default: logerror("UNK_ALUOP.b %s, #$%02x (DIRECT, DATA8)", get_directtext(direct), data8); do_nop(); break;
+ }
+}
+void xa_cpu::add_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); u8 result = do_add_8(val, data8); write_direct8(direct, result); cy(4); }
+void xa_cpu::addc_byte_direct_data8(u16 direct, u8 data8){ u8 val = read_direct8(direct); u8 result = do_addc_8(val, data8); write_direct8(direct, result); cy(4);}
+void xa_cpu::sub_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); u8 result = do_sub_8(val, data8); write_direct8(direct, result); cy(4); }
+void xa_cpu::subb_byte_direct_data8(u16 direct, u8 data8){ u8 val = read_direct8(direct); u8 result = do_subb_8(val, data8); write_direct8(direct, result); cy(4);}
+void xa_cpu::cmp_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); do_sub_8(val, data8); cy(4); }
+void xa_cpu::and_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); u8 result = do_and_8(val, data8); write_direct8(direct, result); cy(4); }
+void xa_cpu::or_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); u8 result = do_or_8(val, data8); write_direct8(direct, result); cy(4); }
+void xa_cpu::xor_byte_direct_data8(u16 direct, u8 data8) { u8 val = read_direct8(direct); u8 result = do_xor_8(val, data8); write_direct8(direct, result); cy(4); }
+void xa_cpu::mov_byte_direct_data8(u16 direct, u8 data8) { u8 result = data8; do_nz_flags_8(result); write_direct8(direct, result); cy(3); }
+
+// -----------------------------------------------
+// ALUOP.w Rd, data16
+// ADD Rd, #data16 Add 16-bit imm data to reg 4 3 1001 1001 dddd 0000 iiii iiii iiii iiii
+// ADDC Rd, #data16 Add 16-bit imm data to reg w/ carry 4 3 1001 1001 dddd 0001 iiii iiii iiii iiii
+// SUB Rd, #data16 Subtract 16-bit imm data to reg 4 3 1001 1001 dddd 0010 iiii iiii iiii iiii
+// SUBB Rd, #data16 Subtract w/ borrow 16-bit imm data to reg 4 3 1001 1001 dddd 0011 iiii iiii iiii iiii
+// CMP Rd, #data16 Compare 16-bit imm data to reg 4 3 1001 1001 dddd 0100 iiii iiii iiii iiii
+// AND Rd, #data16 Logical AND 16-bit imm data to reg 4 3 1001 1001 dddd 0101 iiii iiii iiii iiii
+// OR Rd, #data16 Logical OR 16-bit imm data to reg 4 3 1001 1001 dddd 0110 iiii iiii iiii iiii
+// XOR Rd, #data16 Logical XOR 16-bit imm data to reg 4 3 1001 1001 dddd 0111 iiii iiii iiii iiii
+// MOV Rd, #data16 Move 16-bit imm data to reg 4 3 1001 1001 dddd 1000 iiii iiii iiii iiii
+void xa_cpu::aluop_byte_rd_data16(int alu_op, u8 rd, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_data16(rd, data16); break;
+ case 0x1: addc_word_rd_data16(rd, data16); break;
+ case 0x2: sub_word_rd_data16(rd, data16); break;
+ case 0x3: subb_word_rd_data16(rd, data16); break;
+ case 0x4: cmp_word_rd_data16(rd, data16); break;
+ case 0x5: and_word_rd_data16(rd, data16); break;
+ case 0x6: or_word_rd_data16(rd, data16); break;
+ case 0x7: xor_word_rd_data16(rd, data16); break;
+ case 0x8: mov_word_rd_data16(rd, data16); break;
+ default: logerror("UNK_ALUOP.w %s, #$%04x (RD, DATA16)", m_regnames16[rd], data16); do_nop(); break;
+ }
+}
+void xa_cpu::add_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); u16 result = do_add_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::addc_word_rd_data16(u8 rd, u16 data16){ u16 rdval = gr16(rd); u16 result = do_addc_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::sub_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); u16 result = do_sub_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::subb_word_rd_data16(u8 rd, u16 data16){ u16 rdval = gr16(rd); u16 result = do_subb_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::cmp_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); do_sub_16(rdval, data16); cy(3); }
+void xa_cpu::and_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); u16 result = do_and_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::or_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); u16 result = do_or_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::xor_word_rd_data16(u8 rd, u16 data16) { u16 rdval = gr16(rd); u16 result = do_xor_16(rdval, data16); sr16(rd, result); cy(3); }
+void xa_cpu::mov_word_rd_data16(u8 rd, u16 data16) { u16 result = data16; do_nz_flags_16(result); sr16(rd, result); cy(3); }
+
+// -----------------------------------------------
+// ALUOP.w [Rd], data16
+// ADD [Rd], #data16 Add 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0000 iiii iiii iiii iiii
+// ADDC [Rd], #data16 Add 16-bit imm data to reg-ind w/ carry 4 4 1001 1010 0ddd 0001 iiii iiii iiii iiii
+// SUB [Rd], #data16 Subtract 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0010 iiii iiii iiii iiii
+// SUBB [Rd], #data16 Subtract w/ borrow 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0011 iiii iiii iiii iiii
+// CMP [Rd], #data16 Compare 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0100 iiii iiii iiii iiii
+// AND [Rd], #data16 Logical AND 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0101 iiii iiii iiii iiii
+// OR [Rd], #data16 Logical OR 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0110 iiii iiii iiii iiii
+// XOR [Rd], #data16 Logical XOR 16-bit imm data to reg-ind 4 4 1001 1010 0ddd 0111 iiii iiii iiii iiii
+// MOV [Rd], #data16 Move 16-bit imm data to reg-ind 4 3 1001 1010 0ddd 1000 iiii iiii iiii iiii
+void xa_cpu::aluop_byte_indrd_data16(int alu_op, u8 rd, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrd_data16(rd, data16); break;
+ case 0x1: addc_word_indrd_data16(rd, data16); break;
+ case 0x2: sub_word_indrd_data16(rd, data16); break;
+ case 0x3: subb_word_indrd_data16(rd, data16); break;
+ case 0x4: cmp_word_indrd_data16(rd, data16); break;
+ case 0x5: and_word_indrd_data16(rd, data16); break;
+ case 0x6: or_word_indrd_data16(rd, data16); break;
+ case 0x7: xor_word_indrd_data16(rd, data16); break;
+ case 0x8: mov_word_indrd_data16(rd, data16); break;
+ default: logerror("UNK_ALUOP.w [%s], #$%04x", m_regnames16[rd], data16); do_nop(); break;
+ }
+}
+void xa_cpu::add_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_add_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::addc_word_indrd_data16(u8 rd, u16 data16){ u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_addc_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::sub_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_sub_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::subb_word_indrd_data16(u8 rd, u16 data16){ u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_subb_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::cmp_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); do_sub_16(val, data16); cy(4); }
+void xa_cpu::and_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_and_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::or_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_or_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::xor_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); u16 val = rdat16(address); u16 result = do_xor_16(val, data16); wdat16(address, result); cy(4); }
+void xa_cpu::mov_word_indrd_data16(u8 rd, u16 data16) { u16 address = get_addr(rd); do_nz_flags_16(data16); wdat16(address, data16); cy(3); }
+
+// ALUOP.w [Rd+], data16
+// ADD [Rd+], #data16 Add 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0000 iiii iiii iiii iiii
+// ADDC [Rd+], #data16 Add 16-bit imm data to reg-ind and autoinc w/ carry 4 5 1001 1011 0ddd 0001 iiii iiii iiii iiii
+// SUB [Rd+], #data16 Subtract 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0010 iiii iiii iiii iiii
+// SUBB [Rd+], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0011 iiii iiii iiii iiii
+// CMP [Rd+], #data16 Compare 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0100 iiii iiii iiii iiii
+// AND [Rd+], #data16 Logical AND 16-bit imm data to reg-ind and autoinc 4 5 1001 1011 0ddd 0101 iiii iiii iiii iiii
+// OR [Rd+], #data16 Logical OR 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0110 iiii iiii iiii iiii
+// XOR [Rd+], #data16 Logical XOR 16-bit imm data to reg-ind w/ autoinc 4 5 1001 1011 0ddd 0111 iiii iiii iiii iiii
+// MOV [Rd+], #data16 Move 16-bit imm data to reg-ind w/ autoinc 4 4 1001 1011 0ddd 1000 iiii iiii iiii iiii
+void xa_cpu::aluop_byte_indrdinc_data16(int alu_op, u8 rd, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrdinc_data16(rd, data16); break;
+ case 0x1: addc_word_indrdinc_data16(rd, data16); break;
+ case 0x2: sub_word_indrdinc_data16(rd, data16); break;
+ case 0x3: subb_word_indrdinc_data16(rd, data16); break;
+ case 0x4: cmp_word_indrdinc_data16(rd, data16); break;
+ case 0x5: and_word_indrdinc_data16(rd, data16); break;
+ case 0x6: or_word_indrdinc_data16(rd, data16); break;
+ case 0x7: xor_word_indrdinc_data16(rd, data16); break;
+ case 0x8: mov_word_indrdinc_data16(rd, data16); break;
+ default: logerror("UNK_ALUOP.w [%s+], #$%04x", m_regnames16[rd], data16); do_nop(); break;
+ }
+}
+void xa_cpu::add_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "ADD.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::addc_word_indrdinc_data16(u8 rd, u16 data16){ fatalerror( "ADDC.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::sub_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "SUB.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::subb_word_indrdinc_data16(u8 rd, u16 data16){ fatalerror( "SUBB.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::cmp_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "CMP.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::and_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "AND.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::or_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "OR.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::xor_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "XOR.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+void xa_cpu::mov_word_indrdinc_data16(u8 rd, u16 data16) { fatalerror( "MOV.w [%s+], #$%04x ([RD+], DATA16)", m_regnames16[rd], data16); }
+
+// ALPOP.w [Rd+offs8], data16
+// ADD [Rd+offset8], #data16 Add 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0000 oooo oooo iiii iiii iiii iiii
+// ADDC [Rd+offset8], #data16 Add 16-bit imm data to reg-ind w/ 8-bit offs and carry 5 6 1001 1100 0ddd 0001 oooo oooo iiii iiii iiii iiii
+// SUB [Rd+offset8], #data16 Subtract 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0010 oooo oooo iiii iiii iiii iiii
+// SUBB [Rd+offset8], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0011 oooo oooo iiii iiii iiii iiii
+// CMP [Rd+offset8], #data16 Compare 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0100 oooo oooo iiii iiii iiii iiii
+// AND [Rd+offset8], #data16 Logical AND 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0101 oooo oooo iiii iiii iiii iiii
+// OR [Rd+offset8], #data16 Logical OR 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0110 oooo oooo iiii iiii iiii iiii
+// XOR [Rd+offset8], #data16 Logical XOR 16-bit imm data to reg-ind w/ 8-bit offs 5 6 1001 1100 0ddd 0111 oooo oooo iiii iiii iiii iiii
+// MOV [Rd+offset8], #data16 Move 16-bit imm data to reg-ind w/ 8-bit offs 5 5 1001 1100 0ddd 1000 oooo oooo iiii iiii iiii iiii
+void xa_cpu::aluop_byte_rdoff8_data16(int alu_op, u8 rd, u8 offset8, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x1: addc_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x2: sub_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x3: subb_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x4: cmp_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x5: and_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x6: or_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x7: xor_word_indrdoff8_data16(rd, offset8, data16); break;
+ case 0x8: mov_word_indrdoff8_data16(rd, offset8, data16); break;
+ default: logerror("UNK_ALUOP.w [%s+#$%02x], #$%04x", m_regnames16[rd], offset8, data16); do_nop(); break;
+ }
+}
+
+
+void xa_cpu::add_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_add_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::addc_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16){ u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_addc_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::sub_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_sub_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::subb_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16){ u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_subb_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::cmp_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); do_sub_16(val, data16); cy(6); }
+void xa_cpu::and_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_and_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::or_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_or_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::xor_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_xor_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::mov_word_indrdoff8_data16(u8 rd, u8 offset8, u16 data16) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; do_nz_flags_16(data16); wdat16(address, data16); cy(5); }
+
+// ALUOP.w [Rd+offs16], data16
+// ADD [Rd+offset16], #data16 Add 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0000 oooo oooo oooo oooo iiii iiii iiii iiii
+// ADDC [Rd+offset16], #data16 Add 16-bit imm data to reg-ind w/ 16-bit offs and carry 6 6 1001 1101 0ddd 0001 oooo oooo oooo oooo iiii iiii iiii iiii
+// SUB [Rd+offset16], #data16 Subtract 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0010 oooo oooo oooo oooo iiii iiii iiii iiii
+// SUBB [Rd+offset16], #data16 Subtract w/ borrow 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0011 oooo oooo oooo oooo iiii iiii iiii iiii
+// CMP [Rd+offset16], #data16 Compare 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0100 oooo oooo oooo oooo iiii iiii iiii iiii
+// AND [Rd+offset16], #data16 Logical AND 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0101 oooo oooo oooo oooo iiii iiii iiii iiii
+// OR [Rd+offset16], #data16 Logical OR 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0110 oooo oooo oooo oooo iiii iiii iiii iiii
+// XOR [Rd+offset16], #data16 Logical XOR 16-bit imm data to reg-ind w/ 16-bit offs 6 6 1001 1101 0ddd 0111 oooo oooo oooo oooo iiii iiii iiii iiii
+// MOV [Rd+offset16], #data16 Move 16-bit imm data to reg-ind w/ 16-bit offs 6 5 1001 1101 0ddd 1000 oooo oooo oooo oooo iiii iiii iiii iiii
+void xa_cpu::aluop_byte_rdoff16_data16(int alu_op, u8 rd, u16 offset16, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x1: addc_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x2: sub_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x3: subb_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x4: cmp_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x5: and_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x6: or_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x7: xor_word_indrdoff16_data16(rd, offset16, data16); break;
+ case 0x8: mov_word_indrdoff16_data16(rd, offset16, data16); break;
+ default: logerror("UNK_ALUOP.w [%s+#$%04x], #$%04x", m_regnames16[rd], offset16, data16); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_add_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::addc_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16){ u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_addc_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::sub_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_sub_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::subb_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16){ u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_subb_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::cmp_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); do_sub_16(val, data16); cy(6); }
+void xa_cpu::and_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_and_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::or_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_or_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::xor_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; u16 val = rdat16(address); u16 result = do_xor_16(val, data16); wdat16(address, result); cy(6); }
+void xa_cpu::mov_word_indrdoff16_data16(u8 rd, u16 offset16, u16 data16) { u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; do_nz_flags_16(data16); wdat16(address, data16); cy(5); }
+
+// ALUOP.w DIRECT, data16
+// ADD direct, #data16 Add 16-bit imm data to mem 5 4 1001 1110 0DDD 0000 DDDD DDDD iiii iiii iiii iiii
+// ADDC direct, #data16 Add 16-bit imm data to mem w/ carry 5 4 1001 1110 0DDD 0001 DDDD DDDD iiii iiii iiii iiii
+// SUB direct, #data16 Subtract 16-bit imm data to mem 5 4 1001 1110 0DDD 0010 DDDD DDDD iiii iiii iiii iiii
+// SUBB direct, #data16 Subtract w/ borrow 16-bit imm data to mem 5 4 1001 1110 0DDD 0011 DDDD DDDD iiii iiii iiii iiii
+// CMP direct, #data16 Compare 16-bit imm data to mem 5 4 1001 1110 0DDD 0100 DDDD DDDD iiii iiii iiii iiii
+// AND direct, #data16 Logical AND 16-bit imm data to mem 5 4 1001 1110 0DDD 0101 DDDD DDDD iiii iiii iiii iiii
+// OR direct, #data16 Logical OR 16-bit imm data to mem 5 4 1001 1110 0DDD 0110 DDDD DDDD iiii iiii iiii iiii
+// XOR direct, #data16 Logical XOR 16-bit imm data to mem 5 4 1001 1110 0DDD 0111 DDDD DDDD iiii iiii iiii iiii
+// MOV direct, #data16 Move 16-bit imm data to mem 5 3 1001 1110 0DDD 1000 DDDD DDDD iiii iiii iiii iiii
+void xa_cpu::aluop_byte_direct_data16(int alu_op, u16 direct, u16 data16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_direct_data16(direct, data16); break;
+ case 0x1: addc_word_direct_data16(direct, data16); break;
+ case 0x2: sub_word_direct_data16(direct, data16); break;
+ case 0x3: subb_word_direct_data16(direct, data16); break;
+ case 0x4: cmp_word_direct_data16(direct, data16); break;
+ case 0x5: and_word_direct_data16(direct, data16); break;
+ case 0x6: or_word_direct_data16(direct, data16); break;
+ case 0x7: xor_word_direct_data16(direct, data16); break;
+ case 0x8: mov_word_direct_data16(direct, data16); break;
+ default: logerror("UNK_ALUOP.w %s, #$%04x", get_directtext(direct), data16); do_nop(); break;
+ }
+}
+void xa_cpu::add_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); u16 result = do_add_16(val, data16); write_direct16(direct, result); cy(4); }
+void xa_cpu::addc_word_direct_data16(u16 direct, u16 data16){ u16 val = read_direct16(direct); u16 result = do_addc_16(val, data16); write_direct16(direct, result); cy(4);}
+void xa_cpu::sub_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); u16 result = do_sub_16(val, data16); write_direct16(direct, result); cy(4); }
+void xa_cpu::subb_word_direct_data16(u16 direct, u16 data16){ u16 val = read_direct16(direct); u16 result = do_subb_16(val, data16); write_direct16(direct, result); cy(4);}
+void xa_cpu::cmp_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); do_sub_16(val, data16); cy(4); }
+void xa_cpu::and_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); u16 result = do_and_16(val, data16); write_direct16(direct, result); cy(4); }
+void xa_cpu::or_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); u16 result = do_or_16(val, data16); write_direct16(direct, result); cy(4); }
+void xa_cpu::xor_word_direct_data16(u16 direct, u16 data16) { u16 val = read_direct16(direct); u16 result = do_xor_16(val, data16); write_direct16(direct, result); cy(4); }
+void xa_cpu::mov_word_direct_data16(u16 direct, u16 data16) { u16 result = data16; do_nz_flags_16(result); write_direct16(direct, result); cy(3); }
+
+// ------------------------------------------
+// ------------------------------------------
+// ------------------------------------------
+
+
+// ALUOP.w Rd, Rs
+// ALUOP.b Rd, Rs
+// ADD Rd, Rs Add regs direct 2 3 0000 S001 dddd ssss
+// ADDC Rd, Rs Add regs direct w/ carry 2 3 0001 S001 dddd ssss
+// SUB Rd, Rs Subtract regs direct 2 3 0010 S001 dddd ssss
+// SUBB Rd, Rs Subtract w/ borrow regs direct 2 3 0011 S001 dddd ssss
+// CMP Rd, Rs Compare dest and src regs 2 3 0100 S001 dddd ssss
+// AND Rd, Rs Logical AND regs direct 2 3 0101 S001 dddd ssss
+// OR Rd, Rs Logical OR regs 2 3 0110 S001 dddd ssss
+// XOR Rd, Rs Logical XOR regs 2 3 0111 S001 dddd ssss
+// MOV Rd, Rs Move reg to reg 2 3 1000 S001 dddd ssss
+void xa_cpu::aluop_word_rd_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_rs(rd, rs); break;
+ case 0x1: addc_word_rd_rs(rd, rs); break;
+ case 0x2: sub_word_rd_rs(rd, rs); break;
+ case 0x3: subb_word_rd_rs(rd, rs); break;
+ case 0x4: cmp_word_rd_rs(rd, rs); break;
+ case 0x5: and_word_rd_rs(rd, rs); break;
+ case 0x6: or_word_rd_rs(rd, rs); break;
+ case 0x7: xor_word_rd_rs(rd, rs); break;
+ case 0x8: mov_word_rd_rs(rd, rs); break;
+ default: fatalerror("UNK_ALUOP.w %s, %s", m_regnames16[rd], m_regnames16[rs]); // ALUOP.w Rd, Rs
+ }
+}
+void xa_cpu::aluop_byte_rd_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_rs(rd, rs); break;
+ case 0x1: addc_byte_rd_rs(rd, rs); break;
+ case 0x2: sub_byte_rd_rs(rd, rs); break;
+ case 0x3: subb_byte_rd_rs(rd, rs); break;
+ case 0x4: cmp_byte_rd_rs(rd, rs); break;
+ case 0x5: and_byte_rd_rs(rd, rs); break;
+ case 0x6: or_byte_rd_rs(rd, rs); break;
+ case 0x7: xor_byte_rd_rs(rd, rs); break;
+ case 0x8: mov_byte_rd_rs(rd, rs); break;
+ default: fatalerror("UNK_ALUOP.b %s, %s", m_regnames8[rd], m_regnames8[rs]); // ALUOP.b Rd, Rs
+ }
+}
+
+void xa_cpu::add_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_add_16(rdval, rsval); sr16(rd, result); cy(3);}
+void xa_cpu::addc_word_rd_rs(u8 rd, u8 rs){ u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_addc_16(rdval, rsval); sr16(rd, result); cy(3);}
+void xa_cpu::sub_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_sub_16(rdval, rsval); sr16(rd, result); cy(3);}
+void xa_cpu::subb_word_rd_rs(u8 rd, u8 rs){ u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_subb_16(rdval, rsval); sr16(rd, result); cy(3);}
+void xa_cpu::cmp_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); do_sub_16(rdval, rsval); cy(3); }
+void xa_cpu::and_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_and_16(rdval, rsval); sr16(rd, result); cy(3); }
+void xa_cpu::or_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_or_16(rdval, rsval); sr16(rd, result); cy(3); }
+void xa_cpu::xor_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); u16 result = do_xor_16(rdval, rsval); sr16(rd, result); cy(3);}
+void xa_cpu::mov_word_rd_rs(u8 rd, u8 rs) { u16 val = gr16(rs); do_nz_flags_16(val); sr16(rd, val); cy(3); }
+
+void xa_cpu::add_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_add_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::addc_byte_rd_rs(u8 rd, u8 rs){ u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_addc_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::sub_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_sub_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::subb_byte_rd_rs(u8 rd, u8 rs){ u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_subb_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::cmp_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); do_sub_8(rdval, rsval); cy(3);}
+void xa_cpu::and_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_and_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::or_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_or_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::xor_byte_rd_rs(u8 rd, u8 rs) { u8 rdval = gr8(rd); u8 rsval = gr8(rs); u8 result = do_xor_8(rdval, rsval); sr8(rd, result); cy(3); }
+void xa_cpu::mov_byte_rd_rs(u8 rd, u8 rs) { u8 val = gr8(rs); do_nz_flags_8(val); sr8(rd, val); cy(3);}
+
+// ALUOP.w Rd, [Rs]
+// ALUOP.b Rd, [Rs]
+// ADD Rd, [Rs] Add reg-ind to reg 2 4 0000 S010 dddd 0sss
+// ADDC Rd, [Rs] Add reg-ind to reg w/ carry 2 4 0001 S010 dddd 0sss
+// SUB Rd, [Rs] Subtract reg-ind to reg 2 4 0010 S010 dddd 0sss
+// SUBB Rd, [Rs] Subtract w/ borrow reg-ind to reg 2 4 0011 S010 dddd 0sss
+// CMP Rd, [Rs] Compare reg-ind w/ reg 2 4 0100 S010 dddd 0sss
+// AND Rd, [Rs] Logical AND reg-ind to reg 2 4 0101 S010 dddd 0sss
+// OR Rd, [Rs] Logical OR reg-ind to reg 2 4 0110 S010 dddd 0sss
+// XOR Rd, [Rs] Logical XOR reg-ind to reg 2 4 0111 S010 dddd 0sss
+// MOV Rd, [Rs] Move reg-ind to reg 2 3 1000 S010 dddd 0sss
+void xa_cpu::aluop_word_rd_indrs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_indrs(rd, rs); break;
+ case 0x1: addc_word_rd_indrs(rd, rs); break;
+ case 0x2: sub_word_rd_indrs(rd, rs); break;
+ case 0x3: subb_word_rd_indrs(rd, rs); break;
+ case 0x4: cmp_word_rd_indrs(rd, rs); break;
+ case 0x5: and_word_rd_indrs(rd, rs); break;
+ case 0x6: or_word_rd_indrs(rd, rs); break;
+ case 0x7: xor_word_rd_indrs(rd, rs); break;
+ case 0x8: mov_word_rd_indrs(rd, rs); break;
+ default: fatalerror("UNK_ALUOP.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]); // ALUOP.w Rd, [Rs]
+ }
+}
+void xa_cpu::aluop_byte_rd_indrs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_indrs(rd, rs); break;
+ case 0x1: addc_byte_rd_indrs(rd, rs); break;
+ case 0x2: sub_byte_rd_indrs(rd, rs); break;
+ case 0x3: subb_byte_rd_indrs(rd, rs); break;
+ case 0x4: cmp_byte_rd_indrs(rd, rs); break;
+ case 0x5: and_byte_rd_indrs(rd, rs); break;
+ case 0x6: or_byte_rd_indrs(rd, rs); break;
+ case 0x7: xor_byte_rd_indrs(rd, rs); break;
+ case 0x8: mov_byte_rd_indrs(rd, rs); break;
+ default: fatalerror("UNK_ALUOP.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]); // ALUOP.b Rd, [Rs]
+ }
+}
+void xa_cpu::add_word_rd_indrs(u8 rd, u8 rs) { fatalerror("ADD.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::addc_word_rd_indrs(u8 rd, u8 rs){ fatalerror("ADDC.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::sub_word_rd_indrs(u8 rd, u8 rs) { fatalerror("SUB.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::subb_word_rd_indrs(u8 rd, u8 rs){ fatalerror("SUBB.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_word_rd_indrs(u8 rd, u8 rs) { fatalerror("CMP.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::and_word_rd_indrs(u8 rd, u8 rs) { fatalerror("AND.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::or_word_rd_indrs(u8 rd, u8 rs) { fatalerror("OR.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::xor_word_rd_indrs(u8 rd, u8 rs) { fatalerror("XOR.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::mov_word_rd_indrs(u8 rd, u8 rs) { u16 address = get_addr(rs); u16 val = rdat16(address); do_nz_flags_16(val); sr16(rd, val); cy(3); }
+
+void xa_cpu::add_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("ADD.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::addc_byte_rd_indrs(u8 rd, u8 rs){ fatalerror("ADDC.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::sub_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("SUB.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::subb_byte_rd_indrs(u8 rd, u8 rs){ fatalerror("SUBB.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("CMP.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::and_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("AND.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::or_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("OR.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::xor_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("XOR.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::mov_byte_rd_indrs(u8 rd, u8 rs) { u16 address = get_addr(rs); u8 val = rdat8(address); do_nz_flags_8(val); sr8(rd, val); cy(3); }
+
+
+// ALUOP.w [Rd], Rs
+// ALUOP.b [Rd], Rs
+// ADD [Rd], Rs Add reg to reg-ind 2 4 0000 S010 ssss 1ddd
+// ADDC [Rd], Rs Add reg to reg-ind w/ carry 2 4 0001 S010 ssss 1ddd
+// SUB [Rd], Rs Subtract reg to reg-ind 2 4 0010 S010 ssss 1ddd
+// SUBB [Rd], Rs Subtract w/ borrow reg to reg-ind 2 4 0011 S010 ssss 1ddd
+// CMP [Rd], Rs Compare reg w/ reg-ind 2 4 0100 S010 ssss 1ddd
+// AND [Rd], Rs Logical AND reg to reg-ind 2 4 0101 S010 ssss 1ddd
+// OR [Rd], Rs Logical OR reg to reg-ind 2 4 0110 S010 ssss 1ddd
+// XOR [Rd], Rs Logical XOR reg to reg-ind 2 4 0111 S010 ssss 1ddd
+// MOV [Rd], Rs Move reg to reg-ind 2 3 1000 S010 ssss 1ddd
+void xa_cpu::aluop_word_indrd_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrd_rs(rd, rs); break;
+ case 0x1: addc_word_indrd_rs(rd, rs); break;
+ case 0x2: sub_word_indrd_rs(rd, rs); break;
+ case 0x3: subb_word_indrd_rs(rd, rs); break;
+ case 0x4: cmp_word_indrd_rs(rd, rs); break;
+ case 0x5: and_word_indrd_rs(rd, rs); break;
+ case 0x6: or_word_indrd_rs(rd, rs); break;
+ case 0x7: xor_word_indrd_rs(rd, rs); break;
+ case 0x8: mov_word_indrd_rs(rd, rs); break;
+ default: logerror("UNK_ALUOP.w [%s], %s", m_regnames16[rd], m_regnames16[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::aluop_byte_indrd_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrd_rs(rd, rs); break;
+ case 0x1: addc_byte_indrd_rs(rd, rs); break;
+ case 0x2: sub_byte_indrd_rs(rd, rs); break;
+ case 0x3: subb_byte_indrd_rs(rd, rs); break;
+ case 0x4: cmp_byte_indrd_rs(rd, rs); break;
+ case 0x5: and_byte_indrd_rs(rd, rs); break;
+ case 0x6: or_byte_indrd_rs(rd, rs); break;
+ case 0x7: xor_byte_indrd_rs(rd, rs); break;
+ case 0x8: mov_byte_indrd_rs(rd, rs); break;
+ default: logerror("UNK_ALUOP.b [%s], %s", m_regnames16[rd], m_regnames8[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_indrd_rs(u8 rd, u8 rs) { fatalerror("ADD.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::addc_word_indrd_rs(u8 rd, u8 rs){ fatalerror("ADDC.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::sub_word_indrd_rs(u8 rd, u8 rs) { fatalerror("SUB.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::subb_word_indrd_rs(u8 rd, u8 rs){ fatalerror("SUBB.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_word_indrd_rs(u8 rd, u8 rs) { fatalerror("CMP.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::and_word_indrd_rs(u8 rd, u8 rs) { fatalerror("AND.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::or_word_indrd_rs(u8 rd, u8 rs) { fatalerror("OR.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::xor_word_indrd_rs(u8 rd, u8 rs) { fatalerror("XOR.w [%s], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::mov_word_indrd_rs(u8 rd, u8 rs) { u16 val = gr16(rs); do_nz_flags_16(val); u16 addr = get_addr(rd); wdat16(addr, val); cy(3); }
+
+void xa_cpu::add_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("ADD.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::addc_byte_indrd_rs(u8 rd, u8 rs){ fatalerror("ADDC.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::sub_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("SUB.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::subb_byte_indrd_rs(u8 rd, u8 rs){ fatalerror("SUBB.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::cmp_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("CMP.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::and_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("AND.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::or_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("OR.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::xor_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("XOR.b [%s], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::mov_byte_indrd_rs(u8 rd, u8 rs) { u8 val = gr8(rs); do_nz_flags_8(val); u16 addr = get_addr(rd); wdat8(addr, val); cy(3); }
+
+// ALUOP.w Rd, [Rs+]
+// ALUOP.b Rd, [Rs+]
+// ADD Rd, [Rs+] Add reg-ind w/ autoinc to reg 2 5 0000 S011 dddd 0sss
+// ADDC Rd, [Rs+] Add reg-ind w/ autoinc to reg w/ carry 2 5 0001 S011 dddd 0sss
+// SUB Rd, [Rs+] Subtract reg-ind w/ autoinc to reg 2 5 0010 S011 dddd 0sss
+// SUBB Rd, [Rs+] Subtract w/ borrow reg-ind w/ autoinc to reg 2 5 0011 S011 dddd 0sss
+// CMP Rd, [Rs+] Compare autoinc reg-ind w/ reg 2 5 0100 S011 dddd 0sss
+// AND Rd, [Rs+] Logical AND reg-ind w/ autoinc to reg 2 5 0101 S011 dddd 0sss
+// OR Rd, [Rs+] Logical OR reg-ind w/ autoinc to reg 2 5 0110 S011 dddd 0sss
+// XOR Rd, [Rs+] Logical XOR reg-ind w/ autoinc to reg 2 5 0111 S011 dddd 0sss
+// MOV Rd, [Rs+] Move reg-ind w/ autoinc to reg 2 4 1000 S011 dddd 0sss
+void xa_cpu::aluop_word_rd_indrsinc(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_indrsinc(rd, rs); break;
+ case 0x1: addc_word_rd_indrsinc(rd, rs); break;
+ case 0x2: sub_word_rd_indrsinc(rd, rs); break;
+ case 0x3: subb_word_rd_indrsinc(rd, rs); break;
+ case 0x4: cmp_word_rd_indrsinc(rd, rs); break;
+ case 0x5: and_word_rd_indrsinc(rd, rs); break;
+ case 0x6: or_word_rd_indrsinc(rd, rs); break;
+ case 0x7: xor_word_rd_indrsinc(rd, rs); break;
+ case 0x8: mov_word_rd_indrsinc(rd, rs); break;
+ default: logerror("UNK_ALUOP.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]); do_nop(); break;
+ }
+}
+void xa_cpu::aluop_byte_rd_indrsinc(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_indrsinc(rd, rs); break;
+ case 0x1: addc_byte_rd_indrsinc(rd, rs); break;
+ case 0x2: sub_byte_rd_indrsinc(rd, rs); break;
+ case 0x3: subb_byte_rd_indrsinc(rd, rs); break;
+ case 0x4: cmp_byte_rd_indrsinc(rd, rs); break;
+ case 0x5: and_byte_rd_indrsinc(rd, rs); break;
+ case 0x6: or_byte_rd_indrsinc(rd, rs); break;
+ case 0x7: xor_byte_rd_indrsinc(rd, rs); break;
+ case 0x8: mov_byte_rd_indrsinc(rd, rs); break;
+ default: logerror("UNK_ALUOP.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]); do_nop(); break;
+ }
+}
+void xa_cpu::add_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("ADD.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::addc_word_rd_indrsinc(u8 rd, u8 rs){ fatalerror("ADDC.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::sub_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("SUB.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::subb_word_rd_indrsinc(u8 rd, u8 rs){ fatalerror("SUBB.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("CMP.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::and_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("AND.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::or_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("OR.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::xor_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("XOR.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::mov_word_rd_indrsinc(u8 rd, u8 rs) { fatalerror("MOV.w %s, [%s+]", m_regnames16[rd], m_regnames16[rs]);}
+
+void xa_cpu::add_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("ADD.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::addc_byte_rd_indrsinc(u8 rd, u8 rs){ fatalerror("ADDC.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::sub_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("SUB.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::subb_byte_rd_indrsinc(u8 rd, u8 rs){ fatalerror("SUBB.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("CMP.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::and_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("AND.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::or_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("OR.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::xor_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("XOR.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+void xa_cpu::mov_byte_rd_indrsinc(u8 rd, u8 rs) { fatalerror("MOV.b %s, [%s+]", m_regnames8[rd], m_regnames16[rs]);}
+
+// ALUOP.w [Rd+], Rs
+// ALUOP.b [Rd+], Rs
+// ADD [Rd+], Rs Add reg-ind w/ autoinc to reg 2 5 0000 S011 ssss 1ddd
+// ADDC [Rd+], Rs Add reg-ind w/ autoinc to reg w/ carry 2 5 0001 S011 ssss 1ddd
+// SUB [Rd+], Rs Subtract reg-ind w/ autoinc to reg 2 5 0010 S011 ssss 1ddd
+// SUBB [Rd+], Rs Subtract w/ borrow reg-ind w/ autoinc to reg 2 5 0011 S011 ssss 1ddd
+// CMP [Rd+], Rs Compare reg w/ autoinc reg-ind 2 5 0100 S011 ssss 1ddd
+// AND [Rd+], Rs Logical AND reg-ind w/ autoinc to reg 2 5 0101 S011 ssss 1ddd
+// OR [Rd+], Rs Logical OR reg-ind w/ autoinc to reg 2 5 0110 S011 ssss 1ddd
+// XOR [Rd+], Rs Logical XOR reg-ind w/ autoinc to reg 2 5 0111 S011 ssss 1ddd
+// MOV [Rd+], Rs Move reg-ind w/ autoinc to reg 2 4 1000 S011 ssss 1ddd
+void xa_cpu::aluop_word_indrdinc_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_indrdinc_rs(rd, rs); break;
+ case 0x1: addc_word_indrdinc_rs(rd, rs); break;
+ case 0x2: sub_word_indrdinc_rs(rd, rs); break;
+ case 0x3: subb_word_indrdinc_rs(rd, rs); break;
+ case 0x4: cmp_word_indrdinc_rs(rd, rs); break;
+ case 0x5: and_word_indrdinc_rs(rd, rs); break;
+ case 0x6: or_word_indrdinc_rs(rd, rs); break;
+ case 0x7: xor_word_indrdinc_rs(rd, rs); break;
+ case 0x8: mov_word_indrdinc_rs(rd, rs); break;
+ default: logerror("UNK_ALUOP.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::aluop_byte_indrdinc_rs(int alu_op, u8 rd, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_indrdinc_rs(rd, rs); break;
+ case 0x1: addc_byte_indrdinc_rs(rd, rs); break;
+ case 0x2: sub_byte_indrdinc_rs(rd, rs); break;
+ case 0x3: subb_byte_indrdinc_rs(rd, rs); break;
+ case 0x4: cmp_byte_indrdinc_rs(rd, rs); break;
+ case 0x5: and_byte_indrdinc_rs(rd, rs); break;
+ case 0x6: or_byte_indrdinc_rs(rd, rs); break;
+ case 0x7: xor_byte_indrdinc_rs(rd, rs); break;
+ case 0x8: mov_byte_indrdinc_rs(rd, rs); break;
+ default: logerror("UNK_ALUOP.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("ADD.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::addc_word_indrdinc_rs(u8 rd, u8 rs){ fatalerror("ADDC.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::sub_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("SUB.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::subb_word_indrdinc_rs(u8 rd, u8 rs){ fatalerror("SUBB.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::cmp_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("CMP.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::and_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("AND.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::or_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("OR.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::xor_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("XOR.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+void xa_cpu::mov_word_indrdinc_rs(u8 rd, u8 rs) { fatalerror("MOV.w [%s+], %s", m_regnames16[rd], m_regnames16[rs]);}
+
+void xa_cpu::add_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("ADD.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::addc_byte_indrdinc_rs(u8 rd, u8 rs){ fatalerror("ADDC.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::sub_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("SUB.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::subb_byte_indrdinc_rs(u8 rd, u8 rs){ fatalerror("SUBB.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::cmp_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("CMP.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::and_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("AND.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::or_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("OR.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::xor_byte_indrdinc_rs(u8 rd, u8 rs) { fatalerror("XOR.b [%s+], %s", m_regnames16[rd], m_regnames8[rs]);}
+void xa_cpu::mov_byte_indrdinc_rs(u8 rd, u8 rs) { u16 address = get_addr(rd); u8 result = gr8(rs); wdat8(address, result); address++; do_nz_flags_8(result); set_addr(rd, address); cy(4); }
+
+
+// ALUOP.w Rd, [Rs+off8]
+// ALUOP.b Rd, [Rs+off8]
+// ADD Rd, [Rs+offset8] Add reg-ind w/ 8-bit offs to reg 3 6 0000 S100 dddd 0sss oooo oooo
+// ADDC Rd, [Rs+offset8] Add reg-ind w/ 8-bit offs to reg w/ carry 3 6 0001 S100 dddd 0sss oooo oooo
+// SUB Rd, [Rs+offset8] Subtract reg-ind w/ 8-bit offs to reg 3 6 0010 S100 dddd 0sss oooo oooo
+// SUBB Rd, [Rs+offset8] Subtract w/ borrow reg-ind w/ 8-bit offs to reg 3 6 0011 S100 dddd 0sss oooo oooo
+// CMP Rd, [Rs+offset8] Compare reg-ind w/ 8-bit offs w/ reg 3 6 0100 S100 dddd 0sss oooo oooo
+// AND Rd, [Rs+offset8] Logical AND reg-ind w/ 8-bit offs to reg 3 6 0101 S100 dddd 0sss oooo oooo
+// OR Rd, [Rs+offset8] Logical OR reg-ind w/ 8-bit offs to reg 3 6 0110 S100 dddd 0sss oooo oooo
+// XOR Rd, [Rs+offset8] Logical XOR reg-ind w/ 8-bit offs to reg 3 6 0111 S100 dddd 0sss oooo oooo
+// MOV Rd, [Rs+offset8] Move reg-ind w/ 8-bit offs to reg 3 5 1000 S100 dddd 0sss oooo oooo
+void xa_cpu::aluop_word_rd_rsoff8(int alu_op, u8 rd, u8 rs, u8 offset8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x1: addc_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x2: sub_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x3: subb_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x4: cmp_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x5: and_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x6: or_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x7: xor_word_rd_rsoff8(rd, rs, offset8); break;
+ case 0x8: mov_word_rd_rsoff8(rd, rs, offset8); break;
+ default: logerror("UNK_ALUOP.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8); do_nop(); break;
+ }
+}
+void xa_cpu::aluop_byte_rd_rsoff8(int alu_op, u8 rd, u8 rs, u8 offset8)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x1: addc_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x2: sub_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x3: subb_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x4: cmp_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x5: and_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x6: or_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x7: xor_byte_rd_rsoff8(rd, rs, offset8); break;
+ case 0x8: mov_byte_rd_rsoff8(rd, rs, offset8); break;
+ default: logerror("UNK_ALUOP.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("ADD.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::addc_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8){ fatalerror("ADDC.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::sub_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("SUB.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::subb_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8){ fatalerror("SUBB.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::cmp_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("CMP.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::and_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("AND.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::or_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("OR.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::xor_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("XOR.w %s, [%s+#$%02x]", m_regnames16[rd], m_regnames16[rs], offset8);}
+void xa_cpu::mov_word_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rs) + fulloffset; u16 val = rdat16(address); do_nz_flags_16(val); sr16(rd, val); cy(5); }
+
+void xa_cpu::add_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("ADD.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::addc_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8){ fatalerror("ADDC.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::sub_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("SUB.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::subb_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8){ fatalerror("SUBB.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::cmp_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("CMP.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::and_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("AND.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::or_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("OR.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::xor_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { fatalerror("XOR.b %s, [%s+#$%02x]", m_regnames8[rd], m_regnames16[rs], offset8);}
+void xa_cpu::mov_byte_rd_rsoff8(u8 rd, u8 rs, u8 offset8) { u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rs) + fulloffset; u8 val = rdat8(address); do_nz_flags_8(val); sr8(rd, val); cy(5); }
+
+// ALUOP.w [Rd+off8], Rs
+// ALUOP.b [Rd+off8], Rs
+// ADD [Rd+offset8], Rs Add reg to reg-ind w/ 8-bit offs 3 6 0000 S100 ssss 1ddd oooo oooo
+// ADDC [Rd+offset8], Rs Add reg to reg-ind w/ 8-bit offs w/ carry 3 6 0001 S100 ssss 1ddd oooo oooo
+// SUB [Rd+offset8], Rs Subtract reg to reg-ind w/ 8-bit offs 3 6 0010 S100 ssss 1ddd oooo oooo
+// SUBB [Rd+offset8], Rs Subtract w/ borrow reg to reg-ind w/ 8-bit offs 3 6 0011 S100 ssss 1ddd oooo oooo
+// CMP [Rd+offset8], Rs Compare reg w/ reg-ind w/ 8-bit offs 3 6 0100 S100 ssss 1ddd oooo oooo
+// AND [Rd+offset8], Rs Logical AND reg to reg-ind w/ 8-bit offs 3 6 0101 S100 ssss 1ddd oooo oooo
+// OR [Rd+offset8], Rs Logical OR reg to reg-ind w/ 8-bit offs 3 6 0110 S100 ssss 1ddd oooo oooo
+// XOR [Rd+offset8], Rs Logical XOR reg to reg-ind w/ 8-bit offs 3 6 0111 S100 ssss 1ddd oooo oooo
+// MOV [Rd+offset8], Rs Move reg to reg-ind w/ 8-bit offs 3 5 1000 S100 ssss 1ddd oooo oooo
+void xa_cpu::aluop_word_rdoff8_rs(int alu_op, u8 rd, u8 offset8, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x1: addc_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x2: sub_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x3: subb_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x4: cmp_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x5: and_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x6: or_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x7: xor_word_rdoff8_rs(rd, offset8, rs); break;
+ case 0x8: mov_word_rdoff8_rs(rd, offset8, rs); break;
+ default: logerror("UNK_ALUOP.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]); do_nop(); break;
+ }
+}
+void xa_cpu::aluop_byte_rdoff8_rs(int alu_op, u8 rd, u8 offset8, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x1: addc_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x2: sub_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x3: subb_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x4: cmp_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x5: and_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x6: or_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x7: xor_byte_rdoff8_rs(rd, offset8, rs); break;
+ case 0x8: mov_byte_rdoff8_rs(rd, offset8, rs); break;
+ default: logerror("UNK_ALUOP.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("ADD.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::addc_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs){ fatalerror("ADDC.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::sub_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("SUB.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::subb_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs){ fatalerror("SUBB.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::cmp_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("CMP.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::and_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("AND.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::or_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("OR.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::xor_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("XOR.w [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames16[rs]);}
+void xa_cpu::mov_word_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { u16 val = gr16(rs); u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; do_nz_flags_16(val); wdat16(address, val); cy(5); }
+
+void xa_cpu::add_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("ADD.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::addc_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs){ fatalerror("ADDC.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::sub_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("SUB.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::subb_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs){ fatalerror("SUBB.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::cmp_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("CMP.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::and_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("AND.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::or_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("OR.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::xor_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { fatalerror("XOR.b [%s+#$%02x], %s", m_regnames16[rd], offset8, m_regnames8[rs]);}
+void xa_cpu::mov_byte_rdoff8_rs(u8 rd, u8 offset8, u8 rs) { u8 val = gr8(rs); u16 fulloffset = util::sext(offset8, 8); u16 address = get_addr(rd) + fulloffset; do_nz_flags_8(val); wdat8(address, val); cy(5); }
+
+
+// ALUOP.w Rd, [Rs+off16]
+// ALUOP.b Rd, [Rs+off16]
+// ADD Rd, [Rs+offset16] Add reg-ind w/ 16-bit offs to reg 4 6 0000 S101 dddd 0sss oooo oooo oooo oooo
+// ADDC Rd, [Rs+offset16] Add reg-ind w/ 16-bit offs to reg w/ carry 4 6 0001 S101 dddd 0sss oooo oooo oooo oooo
+// SUB Rd, [Rs+offset16] Subtract reg-ind w/ 16-bit offs to reg 4 6 0010 S101 dddd 0sss oooo oooo oooo oooo
+// SUBB Rd, [Rs+offset16] Subtract w/ borrow reg-ind w/ 16-bit offs to reg 4 6 0011 S101 dddd 0sss oooo oooo oooo oooo
+// CMP Rd, [Rs+offset16] Compare reg-ind w/ 16-bit offs w/ reg 4 6 0100 S101 dddd 0sss oooo oooo oooo oooo
+// AND Rd, [Rs+offset16] Logical AND reg-ind w/ 16-bit offs to reg 4 6 0101 S101 dddd 0sss oooo oooo oooo oooo
+// OR Rd, [Rs+offset16] Logical OR reg-ind w/ 16-bit offs to reg 4 6 0110 S101 dddd 0sss oooo oooo oooo oooo
+// XOR Rd, [Rs+offset16] Logical XOR reg-ind w/ 16-bit offs to reg 4 6 0111 S101 dddd 0sss oooo oooo oooo oooo
+// MOV Rd, [Rs+offset16] Move reg-ind w/ 16-bit offs to reg 4 5 1000 S101 dddd 0sss oooo oooo oooo oooo
+void xa_cpu::aluop_word_rsoff16(int alu_op, u8 rd, u8 rs, u16 offset16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x1: addc_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x2: sub_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x3: subb_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x4: cmp_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x5: and_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x6: or_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x7: xor_word_rd_rsoff16(rd, rs, offset16); break;
+ case 0x8: mov_word_rd_rsoff16(rd, rs, offset16); break;
+ default: logerror("UNK_ALUOP.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16); do_nop(); break;
+ }
+}
+void xa_cpu::aluop_byte_rsoff16(int alu_op, u8 rd, u8 rs, u16 offset16)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x1: addc_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x2: sub_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x3: subb_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x4: cmp_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x5: and_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x6: or_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x7: xor_byte_rd_rsoff16(rd, rs, offset16); break;
+ case 0x8: mov_byte_rd_rsoff16(rd, rs, offset16); break;
+ default: logerror("UNK_ALUOP.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("ADD.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::addc_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16){ fatalerror("ADDC.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::sub_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("SUB.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::subb_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16){ fatalerror("SUBB.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::cmp_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("CMP.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::and_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("AND.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::or_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("OR.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::xor_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("XOR.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+void xa_cpu::mov_word_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("MOV.w %s, [%s+#$%04x]", m_regnames16[rd], m_regnames16[rs], offset16);}
+
+void xa_cpu::add_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("ADD.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::addc_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16){ fatalerror("ADDC.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::sub_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("SUB.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::subb_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16){ fatalerror("SUBB.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::cmp_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("CMP.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::and_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("AND.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::or_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("OR.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::xor_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("XOR.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+void xa_cpu::mov_byte_rd_rsoff16(u8 rd, u8 rs, u16 offset16) { fatalerror("MOV.b %s, [%s+#$%04x]", m_regnames8[rd], m_regnames16[rs], offset16);}
+
+// ALUOP.w [Rd+off16], Rs
+// ALUOP.b [Rd+off16], Rs
+// ADD [Rd+offset16], Rs Add reg to reg-ind w/ 16-bit offs 4 6 0000 S101 ssss 1ddd oooo oooo oooo oooo
+// ADDC [Rd+offset16], Rs Add reg to reg-ind w/ 16-bit offs w/ carry 4 6 0001 S101 ssss 1ddd oooo oooo oooo oooo
+// SUB [Rd+offset16], Rs Subtract reg to reg-ind w/ 16-bit offs 4 6 0010 S101 ssss 1ddd oooo oooo oooo oooo
+// SUBB [Rd+offset16], Rs Subtract w/ borrow reg to reg-ind w/ 16-bit offs 4 6 0011 S101 ssss 1ddd oooo oooo oooo oooo
+// CMP [Rd+offset16], Rs Compare reg w/ reg-ind w/ 16-bit offs 4 6 0100 S101 ssss 1ddd oooo oooo oooo oooo
+// AND [Rd+offset16], Rs Logical AND reg to reg-ind w/ 16-bit offs 4 6 0101 S101 ssss 1ddd oooo oooo oooo oooo
+// OR [Rd+offset16], Rs Logical OR reg to reg-ind w/ 16-bit offs 4 6 0110 S101 ssss 1ddd oooo oooo oooo oooo
+// XOR [Rd+offset16], Rs Logical XOR reg to reg-ind w/ 16-bit offs 4 6 0111 S101 ssss 1ddd oooo oooo oooo oooo
+// MOV [Rd+offset16], Rs Move reg to reg-ind w/ 16-bit offs 4 5 1000 S101 ssss 1ddd oooo oooo oooo oooo
+void xa_cpu::aluop_word_rdoff16_rs(int alu_op, u8 rd, u16 offset16, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x1: addc_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x2: sub_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x3: subb_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x4: cmp_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x5: and_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x6: or_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x7: xor_word_rdoff16_rs(rd, offset16, rs); break;
+ case 0x8: mov_word_rdoff16_rs(rd, offset16, rs); break;
+ default: logerror("UNK_ALUOP.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]); do_nop(); break;
+ }
+}
+void xa_cpu::aluop_byte_rdoff16_rs(int alu_op, u8 rd, u16 offset16, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x1: addc_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x2: sub_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x3: subb_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x4: cmp_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x5: and_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x6: or_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x7: xor_byte_rdoff16_rs(rd, offset16, rs); break;
+ case 0x8: mov_byte_rdoff16_rs(rd, offset16, rs); break;
+ default: logerror("UNK_ALUOP.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("ADD.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::addc_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs){ fatalerror("ADDC.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::sub_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("SUB.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::subb_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs){ fatalerror("SUBB.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::cmp_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("CMP.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::and_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("AND.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::or_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("OR.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::xor_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("XOR.w [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames16[rs]);}
+void xa_cpu::mov_word_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { u16 val = gr16(rs); u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; do_nz_flags_16(val); wdat16(address, val); cy(5); }
+
+void xa_cpu::add_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("ADD.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::addc_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs){ fatalerror("ADDC.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::sub_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("SUB.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::subb_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs){ fatalerror("SUBB.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::cmp_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("CMP.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::and_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("AND.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::or_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("OR.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::xor_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { fatalerror("XOR.b [%s+#$%04x], %s", m_regnames16[rd], offset16, m_regnames8[rs]);}
+void xa_cpu::mov_byte_rdoff16_rs(u8 rd, u16 offset16, u8 rs) { u8 val = gr16(rs); u16 fulloffset = offset16; u16 address = get_addr(rd) + fulloffset; do_nz_flags_8(val); wdat8(address, val); cy(5); }
+
+// ALUOP.w Rd, Direct
+// ALUOP.b Rd, Direct
+// ADD Rd, direct Add mem to reg 3 4 0000 S110 dddd 0DDD DDDD DDDD
+// ADDC Rd, direct Add mem to reg w/ carry 3 4 0001 S110 dddd 0DDD DDDD DDDD
+// SUB Rd, direct Subtract mem to reg 3 4 0010 S110 dddd 0DDD DDDD DDDD
+// SUBB Rd, direct Subtract w/ borrow mem to reg 3 4 0011 S110 dddd 0DDD DDDD DDDD
+// CMP Rd, direct Compare mem w/ reg 3 4 0100 S110 dddd 0DDD DDDD DDDD
+// AND Rd, direct Logical AND mem to reg 3 4 0101 S110 dddd 0DDD DDDD DDDD
+// OR Rd, direct Logical OR mem to reg 3 4 0110 S110 dddd 0DDD DDDD DDDD
+// XOR Rd, direct Logical XOR mem to reg 3 4 0111 S110 dddd 0DDD DDDD DDDD
+// MOV Rd, direct Move mem to reg 3 4 1000 S110 dddd 0DDD DDDD DDDD
+void xa_cpu::aluop_word_rd_direct(int alu_op, u8 rd, u16 direct)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_rd_direct(rd, direct); break;
+ case 0x1: addc_word_rd_direct(rd, direct); break;
+ case 0x2: sub_word_rd_direct(rd, direct); break;
+ case 0x3: subb_word_rd_direct(rd, direct); break;
+ case 0x4: cmp_word_rd_direct(rd, direct); break;
+ case 0x5: and_word_rd_direct(rd, direct); break;
+ case 0x6: or_word_rd_direct(rd, direct); break;
+ case 0x7: xor_word_rd_direct(rd, direct); break;
+ case 0x8: mov_word_rd_direct(rd, direct); break;
+ default: logerror("UNK_ALUOP.w %s, %s", m_regnames16[rd], get_directtext(direct)); do_nop(); break;
+ }
+}
+
+void xa_cpu::aluop_byte_rd_direct(int alu_op, u8 rd, u16 direct)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_rd_direct(rd, direct); break;
+ case 0x1: addc_byte_rd_direct(rd, direct); break;
+ case 0x2: sub_byte_rd_direct(rd, direct); break;
+ case 0x3: subb_byte_rd_direct(rd, direct); break;
+ case 0x4: cmp_byte_rd_direct(rd, direct); break;
+ case 0x5: and_byte_rd_direct(rd, direct); break;
+ case 0x6: or_byte_rd_direct(rd, direct); break;
+ case 0x7: xor_byte_rd_direct(rd, direct); break;
+ case 0x8: mov_byte_rd_direct(rd, direct); break;
+ default: logerror("UNK_ALUOP.b %s, %s", m_regnames8[rd], get_directtext(direct)); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_add_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::addc_word_rd_direct(u8 rd, u16 direct){ u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_addc_16(rdval, val); sr16(rd, result); cy(4);}
+void xa_cpu::sub_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_sub_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::subb_word_rd_direct(u8 rd, u16 direct){ u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_subb_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::cmp_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); do_sub_16(rdval, val); cy(4); }
+void xa_cpu::and_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_and_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::or_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_or_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::xor_word_rd_direct(u8 rd, u16 direct) { u16 rdval = gr16(rd); u16 val = read_direct16(direct); u16 result = do_xor_16(rdval, val); sr16(rd, result); cy(4); }
+void xa_cpu::mov_word_rd_direct(u8 rd, u16 direct) { u16 val = read_direct16(direct); do_nz_flags_16(val); sr16(rd, val); cy(4);}
+
+void xa_cpu::add_byte_rd_direct(u8 rd, u16 direct) { fatalerror("ADD.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::addc_byte_rd_direct(u8 rd, u16 direct){ fatalerror("ADDC.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::sub_byte_rd_direct(u8 rd, u16 direct) { fatalerror("SUB.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::subb_byte_rd_direct(u8 rd, u16 direct){ fatalerror("SUBB.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::cmp_byte_rd_direct(u8 rd, u16 direct) { u8 rdval = gr8(rd); u8 val = read_direct8(direct); do_sub_8(rdval, val); cy(4); }
+void xa_cpu::and_byte_rd_direct(u8 rd, u16 direct) { fatalerror("AND.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::or_byte_rd_direct(u8 rd, u16 direct) { fatalerror("OR.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::xor_byte_rd_direct(u8 rd, u16 direct) { fatalerror("XOR.b %s, %s", m_regnames8[rd], get_directtext(direct));}
+void xa_cpu::mov_byte_rd_direct(u8 rd, u16 direct) { u8 val = read_direct8(direct); do_nz_flags_8(val); sr8(rd, val); cy(4); }
+
+// ALUOP.w Direct, Rs
+// ALUOP.b Direct, Rs
+// ADD direct, Rs Add reg to mem 3 4 0000 S110 ssss 1DDD DDDD DDDD
+// ADDC direct, Rs Add reg to mem w/ carry 3 4 0001 S110 ssss 1DDD DDDD DDDD
+// SUB direct, Rs Subtract reg to mem 3 4 0010 S110 ssss 1DDD DDDD DDDD
+// SUBB direct, Rs Subtract w/ borrow reg to mem 3 4 0011 S110 ssss 1DDD DDDD DDDD
+// CMP direct, Rs Compare reg w/ mem 3 4 0100 S110 ssss 1DDD DDDD DDDD
+// AND direct, Rs Logical AND reg to mem 3 4 0101 S110 ssss 1DDD DDDD DDDD
+// OR direct, Rs Logical OR reg to mem 3 4 0110 S110 ssss 1DDD DDDD DDDD
+// XOR direct, Rs Logical XOR reg to mem 3 4 0111 S110 ssss 1DDD DDDD DDDD
+// MOV direct, Rs Move reg to mem 3 4 1000 S110 ssss 1DDD DDDD DDDD
+
+void xa_cpu::aluop_word_direct_rs(int alu_op, u16 direct, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_word_direct_rs(direct, rs); break;
+ case 0x1: addc_word_direct_rs(direct, rs); break;
+ case 0x2: sub_word_direct_rs(direct, rs); break;
+ case 0x3: subb_word_direct_rs(direct, rs); break;
+ case 0x4: cmp_word_direct_rs(direct, rs); break;
+ case 0x5: and_word_direct_rs(direct, rs); break;
+ case 0x6: or_word_direct_rs(direct, rs); break;
+ case 0x7: xor_word_direct_rs(direct, rs); break;
+ case 0x8: mov_word_direct_rs(direct, rs); break;
+ default: logerror("UNK_ALUOP.w %s, %s", get_directtext(direct), m_regnames16[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::aluop_byte_direct_rs(int alu_op, u16 direct, u8 rs)
+{
+ switch (alu_op)
+ {
+ case 0x0: add_byte_direct_rs(direct, rs); break;
+ case 0x1: addc_byte_direct_rs(direct, rs); break;
+ case 0x2: sub_byte_direct_rs(direct, rs); break;
+ case 0x3: subb_byte_direct_rs(direct, rs); break;
+ case 0x4: cmp_byte_direct_rs(direct, rs); break;
+ case 0x5: and_byte_direct_rs(direct, rs); break;
+ case 0x6: or_byte_direct_rs(direct, rs); break;
+ case 0x7: xor_byte_direct_rs(direct, rs); break;
+ case 0x8: mov_byte_direct_rs(direct, rs); break;
+ default: logerror("UNK_ALUOP.b %s, %s", get_directtext(direct), m_regnames8[rs]); do_nop(); break;
+ }
+}
+
+void xa_cpu::add_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_add_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::addc_word_direct_rs(u16 direct, u8 rs){ u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_addc_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::sub_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_sub_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::subb_word_direct_rs(u16 direct, u8 rs){ u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_subb_16(directval, val); write_direct16(direct, result); cy(4) ; }
+void xa_cpu::cmp_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); do_sub_16(directval, val); cy(4); }
+void xa_cpu::and_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_and_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::or_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_or_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::xor_word_direct_rs(u16 direct, u8 rs) { u16 directval = read_direct16(direct); u16 val = gr16(rs); u16 result = do_xor_16(directval, val); write_direct16(direct, result); cy(4); }
+void xa_cpu::mov_word_direct_rs(u16 direct, u8 rs) { u16 val = gr16(rs); do_nz_flags_16(val); write_direct16(direct, val); cy(4); }
+
+void xa_cpu::add_byte_direct_rs(u16 direct, u8 rs) { fatalerror("ADD.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::addc_byte_direct_rs(u16 direct, u8 rs){ fatalerror("ADDC.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::sub_byte_direct_rs(u16 direct, u8 rs) { fatalerror("SUB.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::subb_byte_direct_rs(u16 direct, u8 rs){ fatalerror("SUBB.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::cmp_byte_direct_rs(u16 direct, u8 rs) { u8 directval = read_direct8(direct); u8 val = gr8(rs); do_sub_8(directval, val); cy(4); }
+void xa_cpu::and_byte_direct_rs(u16 direct, u8 rs) { fatalerror("AND.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::or_byte_direct_rs(u16 direct, u8 rs) { fatalerror("OR.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::xor_byte_direct_rs(u16 direct, u8 rs) { fatalerror("XOR.b %s, %s", get_directtext(direct), m_regnames8[rs]);}
+void xa_cpu::mov_byte_direct_rs(u16 direct, u8 rs) { u8 val = gr8(rs); do_nz_flags_8(val); write_direct8(direct, val); cy(4); }
+
+///////////////////////////////////////////////////////
+
+// MOVS Rd, #data4 Move 4-bit sign-extended imm data to reg 2 3 1011 S001 dddd iiii
+void xa_cpu::movs_word_rd_data4(u8 rd, u8 data4) { u16 data = util::sext(data4, 4); sr16(rd, data); do_nz_flags_16(data); cy(3); }
+void xa_cpu::movs_byte_rd_data4(u8 rd, u8 data4) { u8 data = util::sext(data4, 4); sr8(rd, data); do_nz_flags_8(data); cy(3); }
+// ADDS Rd, #data4 Add 4-bit signed imm data to reg 2 3 1010 S001 dddd iiii
+void xa_cpu::adds_word_rd_data4(u8 rd, u8 data4) { u16 data = util::sext(data4, 4); u16 regval = gr16(rd); regval += data; do_nz_flags_16(regval); sr16(rd, regval); cy(3); }
+void xa_cpu::adds_byte_rd_data4(u8 rd, u8 data4) { u8 data = util::sext(data4, 4); u8 regval = gr8(rd); regval += data; do_nz_flags_8(regval); sr8(rd, regval); cy(3); }
+
+// MOVS [Rd], #data4 Move 4-bit sign-extended imm data to reg-ind 2 3 1011 S010 0ddd iiii
+void xa_cpu::movs_word_indrd_data4(u8 rd, u8 data4){ u16 data = util::sext(data4, 4); u16 address = get_addr(rd); wdat16(address, data); do_nz_flags_16(data); cy(3); }
+void xa_cpu::movs_byte_indrd_data4(u8 rd, u8 data4){ u8 data = util::sext(data4, 4); u16 address = get_addr(rd); wdat8(address, data); do_nz_flags_8(data); cy(3); }
+// ADDS [Rd], #data4 Add 4-bit signed imm data to reg-ind 2 4 1010 S010 0ddd iiii
+void xa_cpu::adds_word_indrd_data4(u8 rd, u8 data4){ u16 data = util::sext(data4, 4); u16 address = get_addr(rd); u16 rdval = rdat16(address); u16 result = do_add_16(rdval, data); wdat16(address, result); cy(4); }
+void xa_cpu::adds_byte_indrd_data4(u8 rd, u8 data4){ u8 data = util::sext(data4, 4); u16 address = get_addr(rd); u8 rdval = rdat8(address); u8 result = do_add_8(rdval, data); wdat8(address, result); cy(4); }
+
+// MOVS [Rd+], #data4 Move 4-bit sign-extended imm data to reg-ind w/ autoinc 2 4 1011 S011 0ddd iiii
+void xa_cpu::movs_word_indrdinc_data4(u8 rd, u8 data4) { u16 data = util::sext(data4, 4); u16 address = get_addr(rd); wdat16(address, data); address += 2; do_nz_flags_16(data); set_addr(rd, address); cy(4); }
+void xa_cpu::movs_byte_indrdinc_data4(u8 rd, u8 data4) { u8 data = util::sext(data4, 4); u16 address = get_addr(rd); wdat8(address, data); address++; do_nz_flags_8(data); set_addr(rd, address); cy(4); }
+// ADDS [Rd+], #data4 Add 4-bit signed imm data to reg-ind w/ autoinc 2 5 1010 S011 0ddd iiii
+void xa_cpu::adds_word_indrdinc_data4(u8 rd, u8 data4){ fatalerror("ADDS.w [%s+], %s", m_regnames16[rd], show_expanded_data4(data4, 1)); }
+void xa_cpu::adds_byte_indrdinc_data4(u8 rd, u8 data4){ fatalerror("ADDS.b [%s+], %s", m_regnames16[rd], show_expanded_data4(data4, 0)); }
+
+// MOVS [Rd+offset8], #data4 Move reg-ind w/ 8-bit offs to 4-bit sign-extended imm data 3 5 1011 S100 0ddd iiii oooo oooo
+void xa_cpu::movs_word_indrdoff8_data4(u8 rd, u8 off8, u8 data4) { u16 data = util::sext(data4, 4); u16 fulloffset = util::sext(off8, 8); u16 address = get_addr(rd) + fulloffset; wdat16(address, data); do_nz_flags_16(data); cy(5); }
+void xa_cpu::movs_byte_indrdoff8_data4(u8 rd, u8 off8, u8 data4){ u8 data = util::sext(data4, 4); u16 fulloffset = util::sext(off8, 8); u16 address = get_addr(rd) + fulloffset; wdat8(address, data); do_nz_flags_8(data); cy(5); }
+// ADDS [Rd+offset8], #data4 Add reg-ind w/ 8-bit offs to 4-bit signed imm data 3 6 1010 S100 0ddd iiii oooo oooo
+void xa_cpu::adds_word_indrdoff8_data4(u8 rd, u8 off8, u8 data4){ u16 data = util::sext(data4, 4); u16 fulloffset = util::sext(off8, 8); u16 address = get_addr(rd) + fulloffset; u16 rdval = rdat16(address); u16 result = do_add_16(rdval, data); wdat16(address, result); cy(4); }
+void xa_cpu::adds_byte_indrdoff8_data4(u8 rd, u8 off8, u8 data4){ u8 data = util::sext(data4, 4); u16 fulloffset = util::sext(off8, 8); u16 address = get_addr(rd) + fulloffset; u8 rdval = rdat8(address); u8 result = do_add_8(rdval, data); wdat8(address, result); cy(4); }
+
+// MOVS [Rd+offset16], #data4 Move reg-ind w/ 16-bit offs to 4-bit sign-extended imm data 4 5 1011 S101 0ddd iiii oooo oooo oooo oooo
+void xa_cpu::movs_word_indrdoff16_data4(u8 rd, u16 off16, u8 data4){ fatalerror("MOVS.w [%s+$%04x], %s", m_regnames16[rd], off16, show_expanded_data4(data4, 1)); }
+void xa_cpu::movs_byte_indrdoff16_data4(u8 rd, u16 off16, u8 data4){ fatalerror("MOVS.b [%s+$%04x], %s", m_regnames16[rd], off16, show_expanded_data4(data4, 0)); }
+// ADDS [Rd+offset16], #data4 Add reg-ind w/ 16-bit offs to 4-bit signed imm data 4 6 1010 S101 0ddd iiii oooo oooo oooo oooo
+void xa_cpu::adds_word_indrdoff16_data4(u8 rd, u16 off16, u8 data4){ fatalerror("ADDS.w [%s+$%04x], %s", m_regnames16[rd], off16, show_expanded_data4(data4, 1)); }
+void xa_cpu::adds_byte_indrdoff16_data4(u8 rd, u16 off16, u8 data4){ fatalerror("ADDS.b [%s+$%04x], %s", m_regnames16[rd], off16, show_expanded_data4(data4, 0)); }
+
+// MOVS direct, #data4 Move 4-bit sign-extended imm data to mem 3 3 1011 S110 0DDD iiii DDDD DDDD
+void xa_cpu::movs_word_direct_data4(u16 direct, u8 data4) { u16 data = util::sext(data4, 4); do_nz_flags_16(data); write_direct16(direct, data); cy(3); }
+void xa_cpu::movs_byte_direct_data4(u16 direct, u8 data4) { u8 data = util::sext(data4, 4); do_nz_flags_8(data); write_direct8(direct, data); cy(3); }
+// ADDS direct, #data4 Add 4-bit signed imm data to mem 3 4 1010 S110 0DDD iiii DDDD DDDD
+void xa_cpu::adds_word_direct_data4(u16 direct, u8 data4){ fatalerror("ADDS.w %s, %s\n", get_directtext(direct), show_expanded_data4(data4, 0)); }
+void xa_cpu::adds_byte_direct_data4(u16 direct, u8 data4){ u8 directval = read_direct8(direct); u8 data = util::sext(data4, 4); directval += data; do_nz_flags_8(directval); write_direct8(direct, directval); cy(4); }
+
+// CALL rel16 Relative call (range +/- 64K) 3 7/4(PZ) 1100 0101 rrrr rrrr rrrr rrrr
+void xa_cpu::call_rel16(u16 rel16) { if (m_pagezeromode) { push_word_to_stack(m_pc); set_pc_in_current_page(expand_rel16(rel16)); cy(4); } else { cy(7); fatalerror("CALL rel16 not in pagezero mode"); } }
+
+// BCC rel8 Branch if the carry flag is clear 2 6t/3nt 1111 0000 rrrr rrrr
+void xa_cpu::bcc_rel8(u8 rel8) { if (get_c_flag() == 0) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BCS rel8 Branch if the carry flag is set 2 6t/3nt 1111 0001 rrrr rrrr
+void xa_cpu::bcs_rel8(u8 rel8) { if (get_c_flag()) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BNE rel8 Branch if the zero flag is not set 2 6t/3nt 1111 0010 rrrr rrrr
+void xa_cpu::bne_rel8(u8 rel8) { if (get_z_flag() == 0) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BEQ rel8 Branch if the zero flag is set 2 6t/3nt 1111 0011 rrrr rrrr
+void xa_cpu::beq_rel8(u8 rel8) { if (get_z_flag()) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BNV rel8 Branch if overflow flag is clear 2 6t/3nt 1111 0100 rrrr rrrr
+void xa_cpu::bnv_rel8(u8 rel8) { fatalerror("BNV %04x\n", expand_rel8(rel8)); }
+// BOV rel8 Branch if overflow flag is set 2 6t/3nt 1111 0101 rrrr rrrr
+void xa_cpu::bov_rel8(u8 rel8) { fatalerror("BOV %04x\n", expand_rel8(rel8)); }
+// BPL rel8 Branch if the negative flag is clear 2 6t/3nt 1111 0110 rrrr rrrr
+void xa_cpu::bpl_rel8(u8 rel8) { fatalerror("BPL %04x\n", expand_rel8(rel8)); }
+// BMI rel8 Branch if the negative flag is set 2 6t/3nt 1111 0111 rrrr rrrr
+void xa_cpu::bmi_rel8(u8 rel8) { fatalerror("BMI %04x\n", expand_rel8(rel8)); }
+// BG rel8 Branch if greater than (unsigned) 2 6t/3nt 1111 1000 rrrr rrrr
+void xa_cpu::bg_rel8(u8 rel8) { fatalerror("BG %04x\n", expand_rel8(rel8)); }
+// BL rel8 Branch if less than or equal to (unsigned) 2 6t/3nt 1111 1001 rrrr rrrr
+void xa_cpu::bl_rel8(u8 rel8) { fatalerror("BL %04x\n", expand_rel8(rel8)); }
+// BGE rel8 Branch if greater than or equal to (signed) 2 6t/3nt 1111 1010 rrrr rrrr
+void xa_cpu::bge_rel8(u8 rel8) { fatalerror("BGE %04x\n", expand_rel8(rel8)); }
+// BLT rel8 Branch if less than (signed) 2 6t/3nt 1111 1011 rrrr rrrr
+void xa_cpu::blt_rel8(u8 rel8) { if (get_n_flag() ^ get_v_flag()) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BGT rel8 Branch if greater than (signed) 2 6t/3nt 1111 1100 rrrr rrrr
+void xa_cpu::bgt_rel8(u8 rel8) { if ((get_z_flag() | get_n_flag()) ^ get_v_flag()) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); } else { cy(3); } }
+// BLE rel8 Branch if less than or equal to (signed) 2 6t/3nt 1111 1101 rrrr rrrr
+void xa_cpu::ble_rel8(u8 rel8) { fatalerror("BLE %04x\n", expand_rel8(rel8)); }
+// BR rel8 Short unconditional branch 2 6 1111 1110 rrrr rrrr
+void xa_cpu::br_rel8(u8 rel8) { set_pc_in_current_page(expand_rel8(rel8)); cy(6); }
+
+// immediate shifts
+
+// ASL Rd, #data4 Logical left shift reg by the 4-bit imm value 2 a* 1101 SS01 dddd iiii
+void xa_cpu::asl_byte_rd_imm4(u8 rd, u8 amount) { fatalerror("ASL.b %s, %d", m_regnames8[rd], amount); }
+void xa_cpu::asl_word_rd_imm4(u8 rd, u8 amount) { u16 fullreg = gr16(rd); fullreg = asl32_helper(fullreg, amount); sr16(rd, fullreg); }
+// ASL Rd, #data5 Logical left shift reg by the 5-bit imm value 2 a* 1101 1101 dddi iiii
+void xa_cpu::asl_dword_rd_imm5(u8 rd, u8 amount) { u32 fullreg = gr32(rd); fullreg = asl32_helper(fullreg, amount); sr32(rd, fullreg); }
+
+// ASR Rd, #data4 Arithmetic shift right reg by the 4-bit imm count 2 a* 1101 SS10 dddd iiii
+void xa_cpu::asr_byte_rd_imm4(u8 rd, u8 amount) { fatalerror("ASR.b %s, %d", m_regnames8[rd], amount); }
+void xa_cpu::asr_word_rd_imm4(u8 rd, u8 amount) { fatalerror("ASR.w %s, %d", m_regnames16[rd], amount); }
+// ASR Rd, #data5 Arithmetic shift right reg by the 5-bit imm count 2 a* 1101 1110 dddi iiii
+void xa_cpu::asr_dword_rd_imm5(u8 rd, u8 amount) { fatalerror("ASR.dw %s, %d", m_regnames16[rd], amount); }
+
+// LSR Rd, #data4 Logical right shift reg by the 4-bit imm value 2 a* 1101 SS00 dddd iiii
+void xa_cpu::lsr_byte_rd_imm4(u8 rd, u8 amount) { fatalerror("LSR.b %s, %d", m_regnames8[rd], amount); }
+void xa_cpu::lsr_word_rd_imm4(u8 rd, u8 amount) { u16 fullreg = gr16(rd); fullreg = lsr32_helper(fullreg, amount); sr16(rd, fullreg); }
+// LSR Rd, #data5 Logical right shift reg by the 4-bit imm value 2 a* 1101 1100 dddi iiii
+void xa_cpu::lsr_dword_rd_imm5(u8 rd, u8 amount) { u32 fullreg = gr32(rd); fullreg = lsr32_helper(fullreg, amount); sr32(rd, fullreg); }
+
+// register form shifts
+
+//ASL Rd, Rs Logical left shift dest reg by the value in the src reg 2 a* 1100 SS01 dddd ssss
+void xa_cpu::asl_byte_rd_rs(u8 rd, u8 rs) { fatalerror("ASL.b %s, %d", m_regnames8[rd], m_regnames8[rs]); }
+void xa_cpu::asl_word_rd_rs(u8 rd, u8 rs) { fatalerror("ASL.w %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+void xa_cpu::asl_dword_rd_rs(u8 rd, u8 rs) { u32 fullreg = gr32(rd); u8 amount = gr8(rs); fullreg = lsr32_helper(fullreg, amount); sr32(rd, fullreg); cy(7); }
+
+// ASR Rd, Rs Arithmetic shift right dest reg by the count in the src 2 a* 1100 SS10 dddd ssss
+void xa_cpu::asr_byte_rd_rs(u8 rd, u8 rs) { fatalerror("ASR.b %s, %d", m_regnames8[rd], m_regnames8[rs]); }
+void xa_cpu::asr_word_rd_rs(u8 rd, u8 rs) { fatalerror("ASR.w %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+void xa_cpu::asr_dword_rd_rs(u8 rd, u8 rs) { fatalerror("ASR.dw %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+
+// LSR Rd, Rs Logical right shift dest reg by the value in the src reg 2 a* 1100 SS00 dddd ssss
+void xa_cpu::lsr_byte_rd_rs(u8 rd, u8 rs) { fatalerror("LSR.b %s, %d", m_regnames8[rd], m_regnames8[rs]); }
+void xa_cpu::lsr_word_rd_rs(u8 rd, u8 rs) { fatalerror("LSR.w %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+void xa_cpu::lsr_dword_rd_rs(u8 rd, u8 rs) { fatalerror("LSR.dw %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+
+// NORM Rd, Rs Logical shift left dest reg by the value in the src reg until MSB set 2 a* 1100 SS11 dddd ssss
+void xa_cpu::norm_byte_rd_rs(u8 rd, u8 rs) { fatalerror("NORM.b %s, %d", m_regnames8[rd], m_regnames8[rs]); }
+void xa_cpu::norm_word_rd_rs(u8 rd, u8 rs) { fatalerror("NORM.w %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+void xa_cpu::norm_dword_rd_rs(u8 rd, u8 rs) { fatalerror("NORM.dw %s, %d", m_regnames16[rd], m_regnames8[rs]); }
+
+
+//MULU.b Rd, Rs
+void xa_cpu::mulu_byte_rd_rs(u8 rd, u8 rs) { fatalerror( "MULU.b %s, %s", m_regnames8[rd], m_regnames8[rs]); }
+//DIVU.b Rd, Rs
+void xa_cpu::divu_byte_rd_rs(u8 rd, u8 rs) { fatalerror( "DIVU.b %s, %s", m_regnames8[rd], m_regnames8[rs]); }
+//MULU.w Rd, Rs
+void xa_cpu::mulu_word_rd_rs(u8 rd, u8 rs) { fatalerror( "MULU.w %s, %s", m_regnames16[rd], m_regnames16[rs]); }
+//DIVU.w Rd, Rs
+void xa_cpu::divu_word_rd_rs(u8 rd, u8 rs) { fatalerror( "DIVU.w %s, %s", m_regnames16[rd], m_regnames16[rs]); }
+// MUL.w Rd, Rs
+void xa_cpu::mul_word_rd_rs(u8 rd, u8 rs) { fatalerror( "MUL.w %s, %s", m_regnames16[rd], m_regnames16[rs]); }
+// DIV.w Rd, Rs
+void xa_cpu::div_word_rd_rs(u8 rd, u8 rs) { fatalerror( "DIV.w %s, %s", m_regnames16[rd], m_regnames16[rs]); }
+
+//DIV.w Rd, #data8
+void xa_cpu::div_word_rd_data8(u8 rd, u8 data8) { fatalerror( "DIV.w %s, #$%02x", m_regnames8[rd], data8); }
+//DIVU.b Rd, #data8
+void xa_cpu::divu_byte_rd_data8(u8 rd, u8 data8) { fatalerror( "DIVU.b %s, #$%02x", m_regnames8[rd], data8); }
+//DIVU.w Rd, #data8
+void xa_cpu::divu_word_rd_data8(u8 rd, u8 data8) { fatalerror( "DIVU.w %s, #$%02x", m_regnames8[rd], data8); }
+//MULU.b Rd, #data8
+void xa_cpu::mulu_byte_rd_data8(u8 rd, u8 data8) { fatalerror( "MULU.b %s, #$%02x", m_regnames8[rd], data8); }
+
+//MULU.w Rd, #data16
+void xa_cpu::mulu_word_rd_data16(u8 rd, u16 data16) { fatalerror( "MULU.w %s, #$%04x", m_regnames16[rd], data16); }
+// DIVU.d Rd, #data16 32X16 unsigned double reg divide w/ imm word 4 22 1110 1001 ddd0 0001 iiii iiii iiii iiii
+void xa_cpu::divu_dword_rd_data16(u8 rd, u16 data16) { fatalerror( "DIVU.d %s, #$%04x", m_regnames16[rd], data16); }
+//MUL.w Rd, #data16
+void xa_cpu::mul_word_rd_data16(u8 rd, u16 data16) { fatalerror( "MUL.w %s, #$%04x", m_regnames16[rd], data16); }
+//DIV.d Rd, #data16
+void xa_cpu::div_dword_rd_data16(u8 rd, u16 data16) { fatalerror( "DIV.d %s, #$%04x", m_regnames16[rd], data16); }
+
+// DIVU.d Rd, Rs 32X16 unsigned double reg divide 2 22 1110 1101 ddd0 ssss
+void xa_cpu::divu_dword_rd_rs(u8 rd, u8 rs)
+{
+ u32 fullval = gr32(rd);
+ u16 rsval = gr16(rs);
+
+ if (rsval)
+ {
+ u32 result = fullval / rsval;
+ u32 remainder = fullval % rsval;
+
+ if (result & 0xffff0000)
+ set_v_flag();
+ else
+ clear_v_flag();
+
+ // are z and n based on the 32-bit result, or 16 bit result?
+ result &= 0xffff;
+
+ if (result == 0x0000)
+ set_z_flag();
+ else
+ clear_n_flag();
+
+ if (result & 0x8000)
+ set_n_flag();
+ else
+ clear_n_flag();
+
+ sr16(rd, result);
+ sr16(rd + 1, remainder);
+ }
+ else
+ {
+ set_v_flag();
+ logerror("%s divide by zero\n", machine().describe_context());
+ }
+
+ clear_c_flag();
+
+ cy(22);
+}
+//DIV.d Rd, Rs
+void xa_cpu::div_dword_rd_rs(u8 rd, u8 rs) { fatalerror( "DIV.d %s, %s", m_regnames16[rd], m_regnames16[rs]); }
+
+// CLR bit Clear bit 3 4 0000 1000 0000 00bb bbbb bbbb
+void xa_cpu::clr_bit(u16 bit) { set_bit_8_helper(bit, 0); cy(4); }
+// SETB bit Sets the bit specified 3 4 0000 1000 0001 00bb bbbb bbbb
+void xa_cpu::setb_bit(u16 bit) { set_bit_8_helper(bit, 1); cy(4); }
+// MOV C, bit Move bit to the carry flag 3 4 0000 1000 0010 00bb bbbb bbbb
+void xa_cpu::mov_c_bit(u16 bit) { fatalerror( "MOV C, %s", get_bittext(bit) ); }
+// MOV bit, C Move carry to bit 3 4 0000 1000 0011 00bb bbbb bbbb
+void xa_cpu::mov_bit_c(u16 bit) { fatalerror( "MOV %s, C", get_bittext(bit) ); }
+// ANL C, bit Logical AND bit to carry 3 4 0000 1000 0100 00bb bbbb bbbb
+void xa_cpu::anl_c_bit(u16 bit) { fatalerror( "ANL C, %s", get_bittext(bit) ); }
+// ANL C, /bit Logical AND complement of a bit to carry 3 4 0000 1000 0101 00bb bbbb bbbb
+void xa_cpu::anl_c_notbit(u16 bit) { fatalerror( "ANL C, /%s", get_bittext(bit) ); }
+// ORL C, bit Logical OR a bit to carry 3 4 0000 1000 0110 00bb bbbb bbbb
+void xa_cpu::orl_c_bit(u16 bit) { fatalerror( "ORL C, %s", get_bittext(bit) ); }
+// ORL C, /bit Logical OR complement of a bit to carry 3 4 0000 1000 0111 00bb bbbb bbbb
+void xa_cpu::orl_c_notbit(u16 bit) { fatalerror( "ORL C, /%s", get_bittext(bit) ); }
+
+// LEA Rd, Rs+offset8 Load 16-bit effective address w/ 8-bit offs to reg 3 3 0100 0000 0ddd 0sss oooo oooo
+void xa_cpu::lea_word_rd_rs_off8(u8 rd, u8 rs, u8 offs8) { fatalerror("LEA %s, %s+#$%02x", m_regnames16[rd], m_regnames16[rs], offs8); }
+
+// LEA Rd, Rs+offset16 Load 16-bit effective address w/ 16-bit offs to reg 4 3 0100 1000 0ddd 0sss oooo oooo oooo oooo
+void xa_cpu::lea_word_rd_rs_off16(u8 rd, u8 rs, u16 offs16) { fatalerror( "LEA %s, %s+#$%04x", m_regnames16[rd], m_regnames16[rs], offs16); }
+
+// XCH Rd, [Rs] Exchange contents of a reg-ind address w/ a reg 2 6 0101 S000 dddd 0sss
+void xa_cpu::xch_word_rd_indrs(u8 rd, u8 rs) { fatalerror("XCH.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]); }
+void xa_cpu::xch_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("XCH.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]); }
+
+// XCH Rd, Rs Exchange contents of two regs 2 5 0110 S000 dddd ssss
+void xa_cpu::xch_word_rd_rs(u8 rd, u8 rs) { u16 rdval = gr16(rd); u16 rsval = gr16(rs); sr16(rd, rsval); sr16(rs, rdval); cy(5); }
+void xa_cpu::xch_byte_rd_rs(u8 rd, u8 rs) { fatalerror("XCH.b %s, %s", m_regnames8[rd], m_regnames8[rs]); }
+
+// MOVC Rd, [Rs+] Move data from WS:Rs address of code mem to reg w/ autoinc 2 4 1000 S000 dddd 0sss
+void xa_cpu::movc_word_rd_indrsinc(u8 rd, u8 rs) { u16 address = get_addr(rs); u16 data = m_program->read_word(address); address+=2; set_addr(rs, address); do_nz_flags_16(data); sr16(rd, data); cy(4); }
+void xa_cpu::movc_byte_rd_indrsinc(u8 rd, u8 rs) { u16 address = get_addr(rs); u8 data = m_program->read_byte(address); address++; set_addr(rs, address); do_nz_flags_8(data); sr8(rd, data); cy(4); }
+
+// DJNZ Rd,rel8 Decrement reg and jump if not zero 3 8t/5nt 1000 S111 dddd 1000 rrrr rrrr
+void xa_cpu::djnz_word_rd_rel8(u8 rd, u8 rel8) { u16 regval = gr16(rd); regval--; do_nz_flags_16(regval); sr16(rd, regval); if (get_z_flag() == 0) { set_pc_in_current_page(expand_rel8(rel8)); cy(8); } else { cy(5); } }
+void xa_cpu::djnz_byte_rd_rel8(u8 rd, u8 rel8) { fatalerror("DJNZ.b %s, $%04x", m_regnames8[rd], expand_rel8(rel8)); }
+
+// POPU direct Pop the mem content (b/w) from the user stack 3 5 1000 S111 0000 0DDD DDDD DDDD
+void xa_cpu::popu_word_direct(u16 direct) { fatalerror("POPU.w %s", get_directtext(direct)); }
+void xa_cpu::popu_byte_direct(u16 direct) { fatalerror("POPU.b %s", get_directtext(direct)); }
+// POP direct Pop the mem content (b/w) from the current stack 3 5 1000 S111 0001 0DDD DDDD DDDD
+void xa_cpu::pop_word_direct(u16 direct) { fatalerror("POP.w %s", get_directtext(direct)); }
+void xa_cpu::pop_byte_direct(u16 direct) { fatalerror("POP.b %s", get_directtext(direct)); }
+// PUSHU direct Push the mem content (b/w) onto the user stack 3 5 1000 S111 0010 0DDD DDDD DDDD
+void xa_cpu::pushu_word_direct(u16 direct) { fatalerror("PUSHU.w %s", get_directtext(direct)); }
+void xa_cpu::pushu_byte_direct(u16 direct) { fatalerror("PUSHU.b %s", get_directtext(direct)); }
+// PUSH direct Push the mem content (b/w) onto the current stack 3 5 1000 S111 0011 0DDD DDDD DDDD
+void xa_cpu::push_word_direct(u16 direct) { fatalerror("PUSH.w %s", get_directtext(direct)); }
+void xa_cpu::push_byte_direct(u16 direct) { fatalerror("PUSH.b %s", get_directtext(direct)); }
+
+// MOV [Rd+], [Rs+] Move reg-ind to reg-ind, both pointers autoinc 2 6 1001 S000 0ddd 0sss
+void xa_cpu::mov_word_indrdinc_indrsinc(u8 rd, u8 rs) { fatalerror("MOV.w [%s+], [%s+]", m_regnames16[rd], m_regnames16[rs]); }
+void xa_cpu::mov_byte_indrdinc_indrsinc(u8 rd, u8 rs) { fatalerror("MOV.b [%s+], [%s+]", m_regnames16[rd], m_regnames16[rs]); }
+
+// DA Rd Decimal Adjust byte reg 2 4 1001 0000 dddd 1000
+void xa_cpu::da_rd(u8 rd) { fatalerror( "DA %s", m_regnames8[rd]); }
+// SEXT Rd Sign extend last operation to reg 2 3 1001 S000 dddd 1001
+void xa_cpu::sext_word_rd(u8 rd) { if(m_nflag) sr16(rd, 0xffff); else sr16(rd, 0); cy(2); }
+void xa_cpu::sext_byte_rd(u8 rd) { if(m_nflag) sr8(rd, 0xff); else sr8(rd, 0); cy(2); }
+// CPL Rd Complement (ones complement) reg 2 3 1001 S000 dddd 1010
+void xa_cpu::cpl_word_rd(u8 rd) { u16 rdval = gr16(rd); u16 result = rdval ^ 0xffff; do_nz_flags_16(result); sr16(rd, result); cy(3); }
+void xa_cpu::cpl_byte_rd(u8 rd) { fatalerror("CPL.b %s", m_regnames8[rd]); }
+// NEG Rd Negate (twos complement) reg 2 3 1001 S000 dddd 1011
+void xa_cpu::neg_word_rd(u8 rd) { fatalerror("NEG.w %sx", m_regnames16[rd]); }
+void xa_cpu::neg_byte_rd(u8 rd) { fatalerror("NEG.b %sx", m_regnames8[rd]); }
+// MOVC A, [A+PC] Move data from code mem to the accumulator ind w/ PC 2 6 1001 0000 0100 1100
+void xa_cpu::movc_a_apc() { fatalerror( "MOVC A, [A+PC]"); }
+// MOVC A, [A+DPTR] Move data from code mem to the accumulator ind w/ DPTR 2 6 1001 0000 0100 1110
+void xa_cpu::movc_a_adptr() { fatalerror( "MOVC A, [A+DPTR]"); }
+// MOV Rd, USP Move User Stack Pointer to reg (system mode only) 2 3 1001 0000 dddd 1111
+void xa_cpu::mov_rd_usp(u8 rd) { fatalerror( "MOV %s, USP", m_regnames16[rd]); }
+// MOV USP, Rs Move reg to User Stack Pointer (system mode only) 2 3 1001 1000 ssss 1111
+void xa_cpu::mov_usp_rs(u8 rs) { fatalerror( "MOV USP, %s", m_regnames16[rs]); }
+
+//JB bit,rel8 Jump if bit set 4 10t/6nt 1001 0111 1000 00bb bbbb bbbb rrrr rrrr
+void xa_cpu::jb_bit_rel8(u16 bit, u8 rel8) { fatalerror( "JB %s, $%02x", get_bittext(bit), expand_rel8(rel8) ); }
+//JNB bit,rel8 Jump if bit not set 4 10t/6nt 1001 0111 1010 00bb bbbb bbbb rrrr rrrr
+void xa_cpu::jnb_bit_rel8(u16 bit, u8 rel8) { fatalerror( "JNB %s, $%02x", get_bittext(bit), expand_rel8(rel8) ); }
+//JBC bit,rel8 Jump if bit set and then clear the bit 4 11t/7nt 1001 0111 1100 00bb bbbb bbbb rrrr rrrr
+void xa_cpu::jbc_bit_rel8(u16 bit, u8 rel8) { fatalerror( "JBC %s, $%02x", get_bittext(bit), expand_rel8(rel8) ); }
+
+// MOV direct, direct Move mem to mem 4 4 1001 S111 0DDD 0ddd DDDD DDDD dddd dddd
+void xa_cpu::mov_word_direct_direct(u16 direct_d, u16 direct_s) { fatalerror("MOV.w %s, %s", get_directtext(direct_d), get_directtext(direct_s)); }
+void xa_cpu::mov_byte_direct_direct(u16 direct_d, u16 direct_s) { u8 val = read_direct8(direct_s); do_nz_flags_8(val); write_direct8(direct_d, val); cy(4); }
+
+// XCH Rd, direct Exchange contents of mem w/ a reg 3 6 1010 S000 dddd 1DDD DDDD DDDD
+void xa_cpu::xch_word_rd_direct(u8 rd, u16 direct) { fatalerror("XCH.w %s, %s", m_regnames16[rd], get_directtext(direct)); }
+void xa_cpu::xch_byte_rd_direct(u8 rd, u16 direct) { fatalerror("XCH.b %s, %s", m_regnames8[rd], get_directtext(direct)); }
+
+// MOV direct, [Rs] Move reg-ind to mem 3 4 1010 S000 1sss 0DDD DDDD DDDD
+void xa_cpu::mov_word_direct_indrs(u16 direct, u8 rs) { fatalerror("MOV.w %s, [%s]", get_directtext(direct), m_regnames16[rs]); }
+void xa_cpu::mov_byte_direct_indrs(u16 direct, u8 rs) { fatalerror("MOV.b %s, [%s]", get_directtext(direct), m_regnames16[rs]); }
+
+// MOV [Rd], direct Move mem to reg-ind 3 4 1010 S000 0ddd 0DDD DDDD DDDD
+void xa_cpu::mov_word_indrd_direct(u8 rd, u16 direct) { fatalerror("MOV.w [%s], %s", m_regnames16[rd], get_directtext(direct)); }
+void xa_cpu::mov_byte_indrd_direct(u8 rd, u16 direct) { fatalerror("MOV.b [%s], %s", m_regnames16[rd], get_directtext(direct)); }
+
+// MOVX [Rd], Rs Move external data from reg to mem 2 6 1010 S111 ssss 1ddd
+void xa_cpu::movx_word_indrd_rs(u8 rd, u8 rs) { fatalerror("MOVX.w [%s], %s", m_regnames16[rd], m_regnames16[rs]); }
+void xa_cpu::movx_byte_indrd_rs(u8 rd, u8 rs) { fatalerror("MOVX.b [%s], %s", m_regnames16[rd], m_regnames8[rs]); }
+
+// MOVX Rd, [Rs] Move external data from mem to reg 2 6 1010 S111 dddd 0sss
+void xa_cpu::movx_word_rd_indrs(u8 rd, u8 rs) { fatalerror("MOVX.w %s, [%s]", m_regnames16[rd], m_regnames16[rs]); }
+void xa_cpu::movx_byte_rd_indrs(u8 rd, u8 rs) { fatalerror("MOVX.b %s, [%s]", m_regnames8[rd], m_regnames16[rs]); }
+
+// RR Rd, #data4 Rotate right reg by the 4-bit imm value 2 a* 1011 S000 dddd iiii
+void xa_cpu::rr_word_rd_data4(u8 rd, u8 data4) { fatalerror("RR.w %s, %d", m_regnames16[rd], data4); }
+void xa_cpu::rr_byte_rd_data4(u8 rd, u8 data4) { fatalerror("RR.b %s, %d", m_regnames8[rd], data4); }
+
+// RRC Rd, #data4 Rotate right reg though carry by the 4-bit imm value 2 a* 1011 S111 dddd iiii
+void xa_cpu::rrc_word_rd_data4(u8 rd, u8 data4) { fatalerror("RRC.w %s, %d", m_regnames16[rd], data4); }
+void xa_cpu::rrc_byte_rd_data4(u8 rd, u8 data4) { fatalerror("RRC.b %s, %d", m_regnames8[rd], data4); }
+
+// RL Rd, #data4 Rotate left reg by the 4-bit imm value 2 a* 1101 S011 dddd iiii
+void xa_cpu::rl_word_rd_data4(u8 rd, u8 data4) { fatalerror("RL.w %d, %d", m_regnames16[rd], data4); }
+void xa_cpu::rl_byte_rd_data4(u8 rd, u8 data4) { fatalerror("RL.b %d, %d", m_regnames8[rd], data4); }
+
+// RLC Rd, #data4 Rotate left reg though carry by the 4-bit imm value 2 a* 1101 S111 dddd iiii
+void xa_cpu::rlc_word_rd_data4(u8 rd, u8 data4) { fatalerror( "RLC.w Rd, %d", m_regnames16[rd], data4); }
+void xa_cpu::rlc_byte_rd_data4(u8 rd, u8 data4) { fatalerror( "RLC.b Rd, %d", m_regnames8[rd], data4); }
+
+// FCALL addr24 Far call (full 24-bit address space) 4 12/8(PZ) 1100 0100 aaaa aaaa AAAA AAAA AAAA AAAA
+void xa_cpu::fcall_addr24(u32 addr24) { fatalerror("FCALL $%06x", addr24); }
+
+// CALL [Rs] Subroutine call ind w/ a reg 2 8/5(PZ) 1100 0110 0000 0sss
+void xa_cpu::call_indrs(u8 rs) { fatalerror("CALL [%s]", m_regnames16[rs]); }
+
+// FJMP addr24 Far jump (full 24-bit address space) 4 6 1101 0100 aaaa aaaa AAAA AAAA AAAA AAAA
+void xa_cpu::fjmp_addr24(u32 addr24) { fatalerror( "FJMP $%06x", addr24); }
+
+// JMP rel16 Long unconditional branch 3 6 1101 0101 rrrr rrrr rrrr rrrr
+void xa_cpu::jmp_rel16(u16 rel16) { m_pc = expand_rel16(rel16); cy(6); }
+
+// DJNZ direct,rel8 Decrement mem and jump if not zero 4 9t/5nt 1110 S010 0000 1DDD DDDD DDDD rrrr rrrr
+void xa_cpu::djnz_word_direct_rel8(u16 direct, u8 rel8) { fatalerror("DJNZ.w %s, $%04x", get_directtext(direct), expand_rel8(rel8)); }
+void xa_cpu::djnz_byte_direct_rel8(u16 direct, u8 rel8) { fatalerror("DJNZ.b %s, $%04x", get_directtext(direct), expand_rel8(rel8)); }
+
+// CJNE Rd,direct,rel8 Compare dir byte to reg and jump if not equal 4 10t/7nt 1110 S010 dddd 0DDD DDDD DDDD rrrr rrrr
+void xa_cpu::cjne_word_rd_direct_rel8(u8 rd, u16 direct, u8 rel8) { fatalerror("CJNE.w %s, %s, $%04x", m_regnames16[rd], get_directtext(direct), expand_rel8(rel8)); }
+void xa_cpu::cjne_byte_rd_direct_rel8(u8 rd, u16 direct, u8 rel8) { fatalerror("CJNE.b %s, %s, $%04x", m_regnames8[rd], get_directtext(direct), expand_rel8(rel8)); }
+
+// CJNE [Rd],#data8,rel8 Compare imm word to reg-ind and jump if not equal 4 10t/7nt 1110 0011 0ddd 1000 rrrr rrrr iiii iiii
+void xa_cpu::cjne_indrd_data8_rel8(u8 rd, u8 data8, u8 rel8) { fatalerror( "CJNE [%s], #$%02x, $%04x", m_regnames16[rd], data8, expand_rel8(rel8));}
+
+// CJNE Rd,#data8,rel8 Compare imm byte to reg and jump if not equal 4 9t/6nt 1110 0011 dddd 0000 rrrr rrrr iiii iiii
+void xa_cpu::cjne_rd_data8_rel8(u8 rd, u8 data8, u8 rel8) { u8 regval = gr8(rd); do_cjne_8_helper(regval, data8); if (!get_z_flag()) { set_pc_in_current_page(expand_rel8(rel8)); cy(9); } else { cy(6); } }
+
+// CJNE [Rd],#data16,rel8 Compare imm word to reg-ind and jump if not equal 5 10t/7nt 1110 1011 0ddd 1000 rrrr rrrr iiii iiii iiii iiii
+void xa_cpu::cjne_indrd_data16_rel8(u8 rd, u16 data16, u8 rel8) { fatalerror( "CJNE [%s], #$%04x, $%04x", m_regnames16[rd], data16, expand_rel8(rel8));}
+
+// CJNE Rd,#data16,rel8 Compare imm word to reg and jump if not equal 5 9t/6nt 1110 1011 dddd 0000 rrrr rrrr iiii iiii iiii iiii
+void xa_cpu::cjne_rd_data16_rel8(u8 rd, u16 data16, u8 rel8) { fatalerror( "CJNE %s, #$%04x, $%04x", m_regnames8[rd], data16, expand_rel8(rel8)); }
+
+// RESET Causes a hardware Reset (same as external Reset) 2 18 1101 0110 0001 0000
+void xa_cpu::reset() { fatalerror( "RESET"); }
+
+// TRAP #data4 Causes 1 of 16 hardware traps to be executed 2 23/19(PZ) 1101 0110 0011 tttt
+void xa_cpu::trap_data4(u8 data4) { fatalerror( "TRAP %d", data4); }
+
+// JMP [A+DPTR] Jump ind relative to the DPTR 2 5 1101 0110 0100 0110
+void xa_cpu::jmp_ind_adptr() { fatalerror( "JMP [A+DPTR]"); }
+
+// JMP [[Rs+]] Jump double-ind to the address (pointer to a pointer) 2 8 1101 0110 0110 0sss
+void xa_cpu::jmp_dblindrs(u8 rs) { fatalerror( "JMP [[%s+]]", m_regnames16[rs]); }
+
+// JMP [Rs] Jump ind to the address in the reg (64K) 2 7 1101 0110 0111 0sss
+void xa_cpu::jmp_indrs(u8 rs) { fatalerror( "JMP [%s]", m_regnames16[rs]); }
+
+// RET Return from subroutine 2 8/6(PZ) 1101 0110 1000 0000
+void xa_cpu::ret() {
+ if (m_pagezeromode)
+ {
+ u16 addr = pull_word_from_stack();
+ set_pc_in_current_page(addr);
+ cy(6);
+ }
+ else
+ {
+ cy(8);
+ fatalerror("RET not in pagezero mode");
+ }
+}
+
+// RETI Return from interrupt 2 10/8(PZ) 1101 0110 1001 0000
+void xa_cpu::reti()
+{
+ if (m_pagezeromode)
+ {
+ // probably wrong order
+ m_pc = pull_word_from_system_stack();
+ m_PSWL = pull_word_from_system_stack();
+ m_PSWH = pull_word_from_system_stack();
+ sfr_PSWL_w(m_PSWL);
+ sfr_PSWH_w(m_PSWH);
+ cy(8);
+ m_in_interrupt = 0;
+
+ }
+ else
+ {
+ fatalerror("RETI when not in page zero mode\n");
+ }
+}
+
+// JZ rel8 Jump if accumulator equals zero 2 6t/3nt 1110 1100 rrrr rrrr
+void xa_cpu::jz_rel8(u8 rel8) { fatalerror( "JZ $%04x", expand_rel8(rel8)); }
+
+// JNZ rel8 Jump if accumulator not equal zero 2 6t/3nt 1110 1110 rrrr rrrr
+void xa_cpu::jnz_rel8(u8 rel8) { fatalerror( "JNZ $%04x", expand_rel8(rel8)); }
+
+// PUSH Rlist Push regs (b/w) onto the current stack 2 b* 0H00 S111 LLLL LLLL
+void xa_cpu::push_word_rlist(u8 bitfield, int h) { cy(2); push_word_reglist(bitfield, h, false); }
+void xa_cpu::push_byte_rlist(u8 bitfield, int h) { cy(2); push_byte_reglist(bitfield, h, false); }
+
+// PUSHU Rlist Push regs (b/w) from the user stack 2 b* 0H01 S111 LLLL LLLL
+void xa_cpu::pushu_word_rlist(u8 bitfield, int h) { fatalerror("PUSHU.w %s", get_word_reglist(bitfield)); }
+void xa_cpu::pushu_byte_rlist(u8 bitfield, int h) { push_byte_reglist(bitfield, h, true); }
+
+// POP Rlist Pop regs (b/w) from the current stack 2 c* 0H10 S111 LLLL LLLL
+void xa_cpu::pop_word_rlist(u8 bitfield, int h) { cy(2); pull_word_reglist(bitfield, h, false); }
+void xa_cpu::pop_byte_rlist(u8 bitfield, int h) { cy(2); pull_byte_reglist(bitfield, h, false); }
+
+// POPU Rlist Pop regs (b/w) from the user stack 2 c* 0H11 S111 LLLL LLLL
+void xa_cpu::popu_word_rlist(u8 bitfield, int h) { fatalerror("POPU.w %s", get_word_reglist(bitfield)); }
+void xa_cpu::popu_byte_rlist(u8 bitfield, int h) { cy(2); pull_byte_reglist(bitfield, h, true); }
diff --git a/src/devices/cpu/xa/xadasm.cpp b/src/devices/cpu/xa/xadasm.cpp
index c8eaf2d5e91..96bb39d2350 100644
--- a/src/devices/cpu/xa/xadasm.cpp
+++ b/src/devices/cpu/xa/xadasm.cpp
@@ -6,54 +6,54 @@
const xa_dasm::op_func xa_dasm::s_instruction[256] =
{
-// group 0
-&xa_dasm::d_nop, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_push_rlist,
-&xa_dasm::d_bitgroup, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_push_rlist,
+// group 0
+&xa_dasm::d_nop, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_push_rlist,
+&xa_dasm::d_bitgroup, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_add, &xa_dasm::d_push_rlist,
// group 1
-&xa_dasm::d_illegal, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_pushu_rlist,
-&xa_dasm::d_illegal, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_pushu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_pushu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_addc, &xa_dasm::d_pushu_rlist,
// group 2
-&xa_dasm::d_illegal, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_pop_rlist,
-&xa_dasm::d_illegal, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_pop_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_pop_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_sub, &xa_dasm::d_pop_rlist,
// group 3
-&xa_dasm::d_illegal, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_popu_rlist,
-&xa_dasm::d_illegal, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_popu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_popu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_subb, &xa_dasm::d_popu_rlist,
// group 4
-&xa_dasm::d_lea_offset8, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_push_rlist,
-&xa_dasm::d_lea_offset16, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_push_rlist,
+&xa_dasm::d_lea_offset8, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_push_rlist,
+&xa_dasm::d_lea_offset16, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_cmp, &xa_dasm::d_push_rlist,
// group 5
-&xa_dasm::d_xch_type1, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_pushu_rlist,
-&xa_dasm::d_xch_type1, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_pushu_rlist,
+&xa_dasm::d_xch_type1, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_pushu_rlist,
+&xa_dasm::d_xch_type1, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_and, &xa_dasm::d_pushu_rlist,
// group 6
-&xa_dasm::d_xch_type2, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_pop_rlist,
-&xa_dasm::d_xch_type2, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_pop_rlist,
+&xa_dasm::d_xch_type2, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_pop_rlist,
+&xa_dasm::d_xch_type2, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_or, &xa_dasm::d_pop_rlist,
// group 7
-&xa_dasm::d_illegal, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_popu_rlist,
-&xa_dasm::d_illegal, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_popu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_popu_rlist,
+&xa_dasm::d_illegal, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_xor, &xa_dasm::d_popu_rlist,
// group 8
-&xa_dasm::d_movc_rd_rsinc, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_pushpop_djnz_subgroup,
-&xa_dasm::d_movc_rd_rsinc, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_pushpop_djnz_subgroup,
+&xa_dasm::d_movc_rd_rsinc, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_pushpop_djnz_subgroup,
+&xa_dasm::d_movc_rd_rsinc, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_mov, &xa_dasm::d_pushpop_djnz_subgroup,
// group 9
-&xa_dasm::d_g9_subgroup, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_jb_mov_subgroup,
-&xa_dasm::d_g9_subgroup, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_jb_mov_subgroup,
+&xa_dasm::d_g9_subgroup, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_jb_mov_subgroup,
+&xa_dasm::d_g9_subgroup, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_alu, &xa_dasm::d_jb_mov_subgroup,
// group a
-&xa_dasm::d_movdir, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_movx_subgroup,
-&xa_dasm::d_movdir, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_movx_subgroup,
+&xa_dasm::d_movdir, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_movx_subgroup,
+&xa_dasm::d_movdir, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_adds, &xa_dasm::d_movx_subgroup,
// group b
-&xa_dasm::d_rr, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_rrc,
-&xa_dasm::d_rr, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_rrc,
+&xa_dasm::d_rr, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_rrc,
+&xa_dasm::d_rr, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_movs, &xa_dasm::d_rrc,
// group c
-&xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm, &xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm,
-&xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm, &xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm,
+&xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm, &xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm,
+&xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm, &xa_dasm::d_lsr_fc, &xa_dasm::d_asl_c, &xa_dasm::d_asr_c, &xa_dasm::d_norm,
// group d
-&xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rl, &xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rlc,
-&xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rl, &xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rlc,
+&xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rl, &xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rlc,
+&xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rl, &xa_dasm::d_lsr_fj, &xa_dasm::d_asl_j, &xa_dasm::d_asr_j, &xa_dasm::d_rlc,
// group e
-&xa_dasm::d_mulu_b, &xa_dasm::d_divu_b, &xa_dasm::d_djnz_cjne, &xa_dasm::d_cjne_d8, &xa_dasm::d_mulu_w, &xa_dasm::d_divu_w, &xa_dasm::d_mul_w, &xa_dasm::d_div_w,
-&xa_dasm::d_div_data8, &xa_dasm::d_div_d16,&xa_dasm::d_djnz_cjne, &xa_dasm::d_cjne_d16, &xa_dasm::d_jz_rel8,&xa_dasm::d_divu_d, &xa_dasm::d_jnz_rel8, &xa_dasm::d_div_d,
+&xa_dasm::d_mulu_b, &xa_dasm::d_divu_b, &xa_dasm::d_djnz_cjne, &xa_dasm::d_cjne_d8, &xa_dasm::d_mulu_w, &xa_dasm::d_divu_w, &xa_dasm::d_mul_w, &xa_dasm::d_div_w,
+&xa_dasm::d_div_data8, &xa_dasm::d_div_d16,&xa_dasm::d_djnz_cjne, &xa_dasm::d_cjne_d16, &xa_dasm::d_jz_rel8,&xa_dasm::d_divu_d, &xa_dasm::d_jnz_rel8, &xa_dasm::d_div_d,
// group f
-&xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch,
-&xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_bkpt,
+&xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch,
+&xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_branch, &xa_dasm::d_bkpt,
};
// SFR names
@@ -68,13 +68,13 @@ const xa_dasm::mem_info xa_dasm::default_names[] = {
{ 0x411, "TSTAT" },
{ 0x418, "T2CON" },
{ 0x419, "T2MOD" },
- { 0x41F, "WDCON" },
- { 0x420, "S0CON" },
- { 0x421, "S0STAT" },
+ { 0x41F, "WDCON" },
+ { 0x420, "S0CON" },
+ { 0x421, "S0STAT" },
{ 0x424, "S1CON" },
- { 0x425, "S1STAT" },
+ { 0x425, "S1STAT" },
{ 0x426, "IEL" },
- { 0x427, "IEH" },
+ { 0x427, "IEH" },
{ 0x42A, "SWR" },
{ 0x430, "P0" },
{ 0x431, "P1" },
@@ -105,22 +105,22 @@ const xa_dasm::mem_info xa_dasm::default_names[] = {
{ 0x462, "S0ADEN" },
{ 0x464, "S1BUF" },
{ 0x465, "S1ADDR" },
- { 0x466, "S1ADEN" },
+ { 0x466, "S1ADEN" },
{ 0x468, "BTRL" },
{ 0x469, "BTRH" },
{ 0x46A, "BCR" },
{ 0x470, "P0CFGA" },
{ 0x471, "P1CFGA" },
{ 0x472, "P2CFGA" },
- { 0x473, "P3CFGA" },
+ { 0x473, "P3CFGA" },
{ 0x47A, "SWE" },
{ 0x4A0, "IPA0" },
{ 0x4A1, "IPA1" },
- { 0x4A2, "IPA2" },
+ { 0x4A2, "IPA2" },
{ 0x4A3, "IPA3" },
{ 0x4A4, "IPA4" },
- { 0x4A5, "IPA5" },
- { 0x4F0, "P0CFGB" },
+ { 0x4A5, "IPA5" },
+ { 0x4F0, "P0CFGB" },
{ 0x4F1, "P1CFGB" },
{ 0x4F2, "P2CFGB" },
{ 0x4F3, "P3CFGB" },
@@ -183,10 +183,10 @@ int xa_dasm::d_illegal(XA_DASM_PARAMS)
int xa_dasm::handle_shift(XA_DASM_PARAMS, int shift_type)
{
- int size = op & 0x0c;
+ int size = (op & 0x0c) >> 2;
const u8 op2 = opcodes.r8(pc++);
u8 data, rd;
- if (size == 0x0c)
+ if (size == 0x03)
{
data = op2 & 0x1f;
rd = (op2 & 0xe0) >> 4;
@@ -199,11 +199,11 @@ int xa_dasm::handle_shift(XA_DASM_PARAMS, int shift_type)
if (size == 0x00)
{
- util::stream_format(stream, "%s%s %s, %d", m_shifts[shift_type], m_dwparamsizes[size >> 2], m_regnames8[rd], data);
+ util::stream_format(stream, "%s%s %s, %d", m_shifts[shift_type], m_dwparamsizes[size], m_regnames8[rd], data);
}
else
{
- util::stream_format(stream, "%s%s %s, %d", m_shifts[shift_type], m_dwparamsizes[size >> 2], m_regnames16[rd], data);
+ util::stream_format(stream, "%s%s %s, %d", m_shifts[shift_type], m_dwparamsizes[size], m_regnames16[rd], data);
}
return 2;
@@ -327,7 +327,7 @@ int xa_dasm::handle_alu_type0(XA_DASM_PARAMS, int alu_op)
-int xa_dasm::handle_alu_type1(XA_DASM_PARAMS, uint8_t op2)
+int xa_dasm::handle_alu_type1(XA_DASM_PARAMS, u8 op2)
{
int alu_op = op2 & 0x0f;
switch (op & 0x0f)
@@ -563,7 +563,7 @@ int xa_dasm::handle_pushpop_rlist(XA_DASM_PARAMS, int type)
if (bit)
{
- util::stream_format(stream, "%s%s", firstbit ? "" : ",", m_regnames8[i + h ? 8 : 0]);
+ util::stream_format(stream, "%s%s", firstbit ? "" : ",", m_regnames8[i + (h ? 8 : 0)]);
firstbit = false;
}
}
@@ -605,15 +605,15 @@ int xa_dasm::d_bitgroup(XA_DASM_PARAMS)
switch (op2 & 0xf0)
{
- case 0x00: util::stream_format(stream, "CLR %s", get_bittext(bit) ); break;
+ case 0x00: util::stream_format(stream, "CLR %s", get_bittext(bit) ); break;
case 0x10: util::stream_format(stream, "SETB %s", get_bittext(bit) ); break;
- case 0x20: util::stream_format(stream, "MOV C, %s", get_bittext(bit) ); break;
+ case 0x20: util::stream_format(stream, "MOV C, %s", get_bittext(bit) ); break;
case 0x30: util::stream_format(stream, "MOV %s, C", get_bittext(bit) ); break;
case 0x40: util::stream_format(stream, "ANL C, %s", get_bittext(bit) ); break;
case 0x50: util::stream_format(stream, "ANL C, /%s", get_bittext(bit) ); break;
case 0x60: util::stream_format(stream, "ORL C, %s", get_bittext(bit) ); break;
case 0x70: util::stream_format(stream, "ORL C, /%s", get_bittext(bit) ); break;
- default: util::stream_format(stream, "illegal bit op %s", get_bittext(bit) ); break;
+ default: util::stream_format(stream, "illegal bit op %s", get_bittext(bit) ); break;
}
return 3;
}
@@ -793,7 +793,7 @@ int xa_dasm::d_xch_type1(XA_DASM_PARAMS)
const char** regnames = size ? m_regnames16 : m_regnames8;
const u8 rd = (op2 & 0xf0) >> 4;
const u8 rs = (op2 & 0x07);
- util::stream_format(stream, "XCH %s, [%s]", regnames[rd], m_regnames16[rs]);
+ util::stream_format(stream, "XCH%s %s, [%s]", size ? ".w" : ".b", regnames[rd], m_regnames16[rs]);
return 2;
}
@@ -809,7 +809,7 @@ AND Rd, [Rs+] Logical AND reg-ind w/ autoinc to reg
AND [Rd+], Rs Logical AND reg-ind w/ autoinc to reg 2 5 0101 S011 ssss 1ddd
AND direct, Rs Logical AND reg to mem 3 4 0101 S110 ssss 1DDD DDDD DDDD
AND Rd, direct Logical AND mem to reg 3 4 0101 S110 dddd 0DDD DDDD DDDD
-*/
+*/
int xa_dasm::d_and(XA_DASM_PARAMS)
{
return handle_alu_type0(XA_CALL_PARAMS, 5);
@@ -828,7 +828,7 @@ int xa_dasm::d_xch_type2(XA_DASM_PARAMS)
const u8 rd = (op2 & 0xf0) >> 4;
const u8 rs = (op2 & 0x0f);
- util::stream_format(stream, "XCH %s, %s", regnames[rd], regnames[rs]);
+ util::stream_format(stream, "XCH%s %s, %s", size ? ".w" : ".b", regnames[rd], regnames[rs]);
return 2;
}
@@ -1029,12 +1029,12 @@ int xa_dasm::d_g9_subgroup(XA_DASM_PARAMS)
if (!size)
{
int rd = (op2 & 0xf0) >> 4;
- util::stream_format(stream, "MOV %s, USP", m_regnames16[rd]);
+ util::stream_format(stream, "MOV %s, USP", m_regnames16[rd]);
}
else
{
int rs = (op2 & 0xf0) >> 4;
- util::stream_format(stream, "MOV USP, %s", m_regnames16[rs]);
+ util::stream_format(stream, "MOV USP, %s", m_regnames16[rs]);
}
return 2;
}
@@ -1204,7 +1204,9 @@ int xa_dasm::d_jb_mov_subgroup(XA_DASM_PARAMS)
{
int direct_dst = ((op2 & 0x70) << 4) | op3;
int direct_src = ((op2 & 0x07) << 8) | op4;
- util::stream_format(stream, "MOV %s, %s", get_directtext(direct_dst), get_directtext(direct_src));
+ int size = op & 0x08;
+
+ util::stream_format(stream, "MOV%s %s, %s", size ? ".w" : ".b", get_directtext(direct_dst), get_directtext(direct_src));
}
return 4;
@@ -1244,7 +1246,7 @@ int xa_dasm::d_movdir(XA_DASM_PARAMS)
{
const u8 rd = op2 & (0x70) >> 4;
util::stream_format(stream, "MOV%s [%s], %s", size ? ".w" : ".b", m_regnames16[rd], get_directtext(direct));
- return 3;
+ return 3;
}
}
@@ -1293,7 +1295,7 @@ int xa_dasm::d_movx_subgroup(XA_DASM_PARAMS)
/*
RR Rd, #data4 Rotate right reg by the 4-bit imm value 2 a* 1011 S000 dddd iiii
-*/
+*/
int xa_dasm::d_rr(XA_DASM_PARAMS)
{
const u8 op2 = opcodes.r8(pc++);
@@ -1374,8 +1376,8 @@ CALL rel16 Relative call (range +/- 64K)
*/
int xa_dasm::d_asl_c(XA_DASM_PARAMS)
{
- int size = op & 0x0c;
- if (size == 0x04)
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
{
const u8 op2 = opcodes.r8(pc++);
const u8 op3 = opcodes.r8(pc++);
@@ -1391,7 +1393,7 @@ int xa_dasm::d_asl_c(XA_DASM_PARAMS)
const char** regnames = ((size != 0) ? m_regnames16 : m_regnames8);
const u8 rd = (op2 & 0xf0) >> 4;
const u8 rs = (op2 & 0x0f);
- util::stream_format(stream, "ASL %s, %s", regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param? (check 03D4 in superkds)
+ util::stream_format(stream, "ASL%s %s, %s", m_dwparamsizes[size], regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param? (check 03D4 in superkds)
return 2;
}
return 1;
@@ -1400,11 +1402,11 @@ int xa_dasm::d_asl_c(XA_DASM_PARAMS)
/*
ASR Rd, Rs Arithmetic shift right dest reg by the count in the src 2 a* 1100 SS10 dddd ssss
CALL [Rs] Subroutine call ind w/ a reg 2 8/5(PZ) 1100 0110 0000 0sss
-*/
+*/
int xa_dasm::d_asr_c(XA_DASM_PARAMS)
{
- int size = op & 0x0c;
- if (size == 0x04)
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
{
const u8 op2 = opcodes.r8(pc++);
const u8 rs = op2 & 0x07;
@@ -1417,7 +1419,7 @@ int xa_dasm::d_asr_c(XA_DASM_PARAMS)
const char** regnames = ((size != 0) ? m_regnames16 : m_regnames8);
const u8 rd = (op2 & 0xf0) >> 4;
const u8 rs = (op2 & 0x0f);
- util::stream_format(stream, "ASR %s, %s", regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param?
+ util::stream_format(stream, "ASR%s %s, %s", m_dwparamsizes[size], regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param?
return 2;
}
return 1;
@@ -1428,8 +1430,8 @@ NORM Rd, Rs Logical shift left dest reg by the value in the src
*/
int xa_dasm::d_norm(XA_DASM_PARAMS)
{
- int size = op & 0x0c;
- if (size == 0x04)
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
{
const u8 op2 = opcodes.r8(pc++);
util::stream_format(stream, "illegal %02x", op2);
@@ -1441,8 +1443,7 @@ int xa_dasm::d_norm(XA_DASM_PARAMS)
int rd = (op2 & 0xf0) >> 4;
int rs = (op2 & 0x0f);
const char** regnames = ((size != 0) ? m_regnames16 : m_regnames8);
- // doesn't have a #data5 mode like the other shifts?
- util::stream_format(stream, "NORM%s %s, %s", m_dwparamsizes[size >> 2], regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param?
+ util::stream_format(stream, "NORM%s %s, %s", m_dwparamsizes[size], regnames[rd], m_regnames8[rs]); // m_regnames8 or regnames for last param?
return 2;
}
return 2;
@@ -1457,8 +1458,8 @@ FJMP addr24 Far jump (full 24-bit address space)
*/
int xa_dasm::d_lsr_fj(XA_DASM_PARAMS)
{
- int size = op & 0x0c;
- if (size == 0x04)
+ int size = (op & 0x0c) >> 2;
+ if (size == 0x01)
{
const u8 op2 = opcodes.r8(pc++);
const u8 op3 = opcodes.r8(pc++);
@@ -1574,17 +1575,20 @@ int xa_dasm::d_djnz_cjne(XA_DASM_PARAMS)
const u8 op2 = opcodes.r8(pc++);
const u8 op3 = opcodes.r8(pc++);
const u8 op4 = opcodes.r8(pc++);
+ int size = op & 0x08;
+
int address = pc + ((s8)op4)*2;
address &= ~1; // must be word aligned
const u16 direct = ((op2 & 0x07) << 8) | op3;
if (op2 & 0x08)
{
- util::stream_format(stream, "DJNZ %s, $%04x", get_directtext(direct), address);
+ util::stream_format(stream, "DJNZ%s %s, $%04x", size ? ".w" : ".b", get_directtext(direct), address);
}
else
{
int rd = (op2 & 0xf0) >> 4;
- util::stream_format(stream, "CJNE %s, %s, $%04x", m_regnames16[rd], get_directtext(direct), address);
+ const char** regnames = size ? m_regnames16 : m_regnames8;
+ util::stream_format(stream, "CJNE%s %s, %s, $%04x", size ? ".w" : ".b", regnames[rd], get_directtext(direct), address);
}
return 4;
}
@@ -1662,10 +1666,10 @@ int xa_dasm::d_div_w(XA_DASM_PARAMS)
}
/*
-DIV.w Rd, #data8 16x8 signed divide reg w/ imm word 3 14 1110 1000 dddd 1011 iiii iiii
+MULU.b Rd, #data8 8X8 unsigned multiply of 8-bit imm data w/ reg 3 12 1110 1000 dddd 0000 iiii iiii
DIVU.b Rd, #data8 8X8 unsigned reg divide w/ imm byte 3 12 1110 1000 dddd 0001 iiii iiii
DIVU.w Rd, #data8 16X8 unsigned reg divide w/ imm byte 3 12 1110 1000 dddd 0011 iiii iiii
-MULU.b Rd, #data8 8X8 unsigned multiply of 8-bit imm data w/ reg 3 12 1110 1000 dddd 0000 iiii iiii
+DIV.w Rd, #data8 16x8 signed divide reg w/ imm word 3 14 1110 1000 dddd 1011 iiii iiii
*/
int xa_dasm::d_div_data8(XA_DASM_PARAMS)
{
@@ -1706,8 +1710,8 @@ int xa_dasm::d_div_data8(XA_DASM_PARAMS)
/*
MULU.w Rd, #data16 16X16 unsigned multiply 16-bit imm data w/ reg 4 12 1110 1001 dddd 0000 iiii iiii iiii iiii
-MUL.w Rd, #data16 16X16 signed multiply 16-bit imm data w/ reg 4 12 1110 1001 dddd 1000 iiii iiii iiii iiii
DIVU.d Rd, #data16 32X16 unsigned double reg divide w/ imm word 4 22 1110 1001 ddd0 0001 iiii iiii iiii iiii
+MUL.w Rd, #data16 16X16 signed multiply 16-bit imm data w/ reg 4 12 1110 1001 dddd 1000 iiii iiii iiii iiii
DIV.d Rd, #data16 32x16 signed double reg divide w/ imm word 4 24 1110 1001 ddd0 1001 iiii iiii iiii iiii
*/
int xa_dasm::d_div_d16(XA_DASM_PARAMS)
@@ -1790,12 +1794,12 @@ int xa_dasm::d_cjne_d8(XA_DASM_PARAMS)
if (op2 & 0x08)
{
const u8 rd = (op2 & 0x70) >> 4;
- util::stream_format(stream, "CJNE [%d], #$%02x, $%04x", m_regnames16[rd], op4, address);
+ util::stream_format(stream, "CJNE [%s], #$%02x, $%04x", m_regnames16[rd], op4, address);
}
else
{
const u8 rd = (op2 & 0xf0) >> 4;
- util::stream_format(stream, "CJNE %d, #$%02x, $%04x", m_regnames8[rd], op4, address);
+ util::stream_format(stream, "CJNE %s, #$%02x, $%04x", m_regnames8[rd], op4, address);
}
return 4;
}
diff --git a/src/devices/cpu/xa/xadasm.h b/src/devices/cpu/xa/xadasm.h
index a2c211e10f5..7cb8380c086 100644
--- a/src/devices/cpu/xa/xadasm.h
+++ b/src/devices/cpu/xa/xadasm.h
@@ -6,7 +6,7 @@
#pragma once
-#define XA_DASM_PARAMS uint8_t op, std::ostream& stream, offs_t pc, const data_buffer& opcodes, const data_buffer& params
+#define XA_DASM_PARAMS u8 op, std::ostream& stream, offs_t pc, const data_buffer& opcodes, const data_buffer& params
#define XA_CALL_PARAMS op, stream, pc, opcodes, params
class xa_dasm : public util::disasm_interface
@@ -39,7 +39,7 @@ private:
const char* m_regnames16[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal" };
const char* m_regnames8[16] = { "R0L", "R0H", "R1L", "R1H", "R2L", "R2H", "R3L", "R3H", "R4L", "R4H", "R5L", "R5H", "R6L", "R6H", "R7L", "R7H"};
- const char* m_aluops[16] = { "ADD", "ADDC", "SUB", "SUBC", "CMP", "AND", "OR", "XOR", "MOV", "illegal ALU 0x09", "illegal ALU 0x0a", "illegal ALU 0x0b", "illegal ALU 0x0c", "illegal ALU 0x0d", "illegal ALU 0x0e", "illegal ALU 0x0f"};
+ const char* m_aluops[16] = { "ADD", "ADDC", "SUB", "SUBB", "CMP", "AND", "OR", "XOR", "MOV", "illegal ALU 0x09", "illegal ALU 0x0a", "illegal ALU 0x0b", "illegal ALU 0x0c", "illegal ALU 0x0d", "illegal ALU 0x0e", "illegal ALU 0x0f"};
const char* m_branches[15] = { "BCC", "BCS", "BNE", "BEQ", "BNV", "BOV", "BPL", "BMI", "BG", "BL", "BGE", "BLT", "BGT", "BLE", "BR" };
const char* m_addsmovs[2] = { "ADDS", "MOVS" };
const char* m_pushpull[4] = { "PUSH", "PUSHU", "POP", "POPU" };
@@ -51,7 +51,7 @@ private:
std::string show_expanded_data4(u16 data4, int size);
int handle_alu_type0(XA_DASM_PARAMS, int alu_op);
- int handle_alu_type1(XA_DASM_PARAMS, uint8_t op2);
+ int handle_alu_type1(XA_DASM_PARAMS, u8 op2);
int handle_pushpop_rlist(XA_DASM_PARAMS, int type);
int handle_adds_movs(XA_DASM_PARAMS, int which);
int handle_shift(XA_DASM_PARAMS, int shift_type);