aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/arch/M680X
diff options
context:
space:
mode:
Diffstat (limited to 'capstone/arch/M680X')
-rw-r--r--capstone/arch/M680X/M680XDisassembler.c2318
-rw-r--r--capstone/arch/M680X/M680XDisassembler.h17
-rw-r--r--capstone/arch/M680X/M680XDisassemblerInternals.h57
-rw-r--r--capstone/arch/M680X/M680XInstPrinter.c360
-rw-r--r--capstone/arch/M680X/M680XInstPrinter.h25
-rw-r--r--capstone/arch/M680X/M680XModule.c77
-rw-r--r--capstone/arch/M680X/M680XModule.h12
-rw-r--r--capstone/arch/M680X/cpu12.inc335
-rw-r--r--capstone/arch/M680X/hcs08.inc60
-rw-r--r--capstone/arch/M680X/hd6301.inc15
-rw-r--r--capstone/arch/M680X/hd6309.inc259
-rw-r--r--capstone/arch/M680X/insn_props.inc367
-rw-r--r--capstone/arch/M680X/m6800.inc277
-rw-r--r--capstone/arch/M680X/m6801.inc39
-rw-r--r--capstone/arch/M680X/m6805.inc277
-rw-r--r--capstone/arch/M680X/m6808.inc91
-rw-r--r--capstone/arch/M680X/m6809.inc352
-rw-r--r--capstone/arch/M680X/m6811.inc105
18 files changed, 5043 insertions, 0 deletions
diff --git a/capstone/arch/M680X/M680XDisassembler.c b/capstone/arch/M680X/M680XDisassembler.c
new file mode 100644
index 000000000..0d7a8864f
--- /dev/null
+++ b/capstone/arch/M680X/M680XDisassembler.c
@@ -0,0 +1,2318 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+/* ======================================================================== */
+/* ================================ INCLUDES ============================== */
+/* ======================================================================== */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../../cs_priv.h"
+#include "../../utils.h"
+
+#include "../../MCInst.h"
+#include "../../MCInstrDesc.h"
+#include "../../MCRegisterInfo.h"
+#include "M680XInstPrinter.h"
+#include "M680XDisassembler.h"
+#include "M680XDisassemblerInternals.h"
+
+#ifdef CAPSTONE_HAS_M680X
+
+#ifndef DECL_SPEC
+#ifdef _MSC_VER
+#define DECL_SPEC __cdecl
+#else
+#define DECL_SPEC
+#endif // _MSC_VER
+#endif // DECL_SPEC
+
+/* ======================================================================== */
+/* ============================ GENERAL DEFINES =========================== */
+/* ======================================================================== */
+
+/* ======================================================================== */
+/* =============================== PROTOTYPES ============================= */
+/* ======================================================================== */
+
+typedef enum insn_hdlr_id {
+ illgl_hid,
+ rel8_hid,
+ rel16_hid,
+ imm8_hid,
+ imm16_hid,
+ imm32_hid,
+ dir_hid,
+ ext_hid,
+ idxX_hid,
+ idxY_hid,
+ idx09_hid,
+ inh_hid,
+ rr09_hid,
+ rbits_hid,
+ bitmv_hid,
+ tfm_hid,
+ opidx_hid,
+ opidxdr_hid,
+ idxX0_hid,
+ idxX16_hid,
+ imm8rel_hid,
+ idxS_hid,
+ idxS16_hid,
+ idxXp_hid,
+ idxX0p_hid,
+ idx12_hid,
+ idx12s_hid,
+ rr12_hid,
+ loop_hid,
+ index_hid,
+ imm8i12x_hid,
+ imm16i12x_hid,
+ exti12x_hid,
+ HANDLER_ID_ENDING,
+} insn_hdlr_id;
+
+// Access modes for the first 4 operands. If there are more than
+// four operands they use the same access mode as the 4th operand.
+//
+// u: unchanged
+// r: (r)read access
+// w: (w)write access
+// m: (m)odify access (= read + write)
+//
+typedef enum e_access_mode {
+
+ uuuu,
+ rrrr,
+ wwww,
+ rwww,
+ rrrm,
+ rmmm,
+ wrrr,
+ mrrr,
+ mwww,
+ mmmm,
+ mwrr,
+ mmrr,
+ wmmm,
+ rruu,
+ muuu,
+ ACCESS_MODE_ENDING,
+} e_access_mode;
+
+// Access type values are compatible with enum cs_ac_type:
+typedef enum e_access {
+ UNCHANGED = CS_AC_INVALID,
+ READ = CS_AC_READ,
+ WRITE = CS_AC_WRITE,
+ MODIFY = (CS_AC_READ | CS_AC_WRITE),
+} e_access;
+
+/* Properties of one instruction in PAGE1 (without prefix) */
+typedef struct inst_page1 {
+ unsigned insn : 9; // A value of type m680x_insn
+ unsigned handler_id1 : 6; // Type insn_hdlr_id, first instr. handler id
+ unsigned handler_id2 : 6; // Type insn_hdlr_id, second instr. handler id
+} inst_page1;
+
+/* Properties of one instruction in any other PAGE X */
+typedef struct inst_pageX {
+ unsigned opcode : 8; // The opcode byte
+ unsigned insn : 9; // A value of type m680x_insn
+ unsigned handler_id1 : 6; // Type insn_hdlr_id, first instr. handler id
+ unsigned handler_id2 : 6; // Type insn_hdlr_id, second instr. handler id
+} inst_pageX;
+
+typedef struct insn_props {
+ unsigned group : 4;
+ unsigned access_mode : 5; // A value of type e_access_mode
+ unsigned reg0 : 5; // A value of type m680x_reg
+ unsigned reg1 : 5; // A value of type m680x_reg
+ bool cc_modified : 1;
+ bool update_reg_access : 1;
+} insn_props;
+
+#include "m6800.inc"
+#include "m6801.inc"
+#include "hd6301.inc"
+#include "m6811.inc"
+#include "cpu12.inc"
+#include "m6805.inc"
+#include "m6808.inc"
+#include "hcs08.inc"
+#include "m6809.inc"
+#include "hd6309.inc"
+
+#include "insn_props.inc"
+
+//////////////////////////////////////////////////////////////////////////////
+
+// M680X instuctions have 1 up to 8 bytes (CPU12: MOVW IDX2,IDX2).
+// A reader is needed to read a byte or word from a given memory address.
+// See also X86 reader(...)
+static bool read_byte(const m680x_info *info, uint8_t *byte, uint16_t address)
+{
+ if (address < info->offset ||
+ (uint32_t)(address - info->offset) >= info->size)
+ // out of code buffer range
+ return false;
+
+ *byte = info->code[address - info->offset];
+
+ return true;
+}
+
+static bool read_byte_sign_extended(const m680x_info *info, int16_t *word,
+ uint16_t address)
+{
+ if (address < info->offset ||
+ (uint32_t)(address - info->offset) >= info->size)
+ // out of code buffer range
+ return false;
+
+ *word = (int16_t) info->code[address - info->offset];
+
+ if (*word & 0x80)
+ *word |= 0xFF00;
+
+ return true;
+}
+
+static bool read_word(const m680x_info *info, uint16_t *word, uint16_t address)
+{
+ if (address < info->offset ||
+ (uint32_t)(address + 1 - info->offset) >= info->size)
+ // out of code buffer range
+ return false;
+
+ *word = (uint16_t)info->code[address - info->offset] << 8;
+ *word |= (uint16_t)info->code[address + 1 - info->offset];
+
+ return true;
+}
+
+static bool read_sdword(const m680x_info *info, int32_t *sdword,
+ uint16_t address)
+{
+ if (address < info->offset ||
+ (uint32_t)(address + 3 - info->offset) >= info->size)
+ // out of code buffer range
+ return false;
+
+ *sdword = (uint32_t)info->code[address - info->offset] << 24;
+ *sdword |= (uint32_t)info->code[address + 1 - info->offset] << 16;
+ *sdword |= (uint32_t)info->code[address + 2 - info->offset] << 8;
+ *sdword |= (uint32_t)info->code[address + 3 - info->offset];
+
+ return true;
+}
+
+// For PAGE2 and PAGE3 opcodes when using an an array of inst_page1 most
+// entries have M680X_INS_ILLGL. To avoid wasting memory an inst_pageX is
+// used which contains the opcode. Using a binary search for the right opcode
+// is much faster (= O(log n) ) in comparison to a linear search ( = O(n) ).
+static int binary_search(const inst_pageX *const inst_pageX_table,
+ size_t table_size, unsigned int opcode)
+{
+ // As part of the algorithm last may get negative.
+ // => signed integer has to be used.
+ int first = 0;
+ int last = (int)table_size - 1;
+ int middle = (first + last) / 2;
+
+ while (first <= last) {
+ if (inst_pageX_table[middle].opcode < opcode) {
+ first = middle + 1;
+ }
+ else if (inst_pageX_table[middle].opcode == opcode) {
+ return middle; /* item found */
+ }
+ else
+ last = middle - 1;
+
+ middle = (first + last) / 2;
+ }
+
+ if (first > last)
+ return -1; /* item not found */
+
+ return -2;
+}
+
+void M680X_get_insn_id(cs_struct *handle, cs_insn *insn, unsigned int id)
+{
+ const m680x_info *const info = (const m680x_info *)handle->printer_info;
+ const cpu_tables *cpu = info->cpu;
+ uint8_t insn_prefix = (id >> 8) & 0xff;
+ // opcode is the first instruction byte without the prefix.
+ uint8_t opcode = id & 0xff;
+ int index;
+ int i;
+
+ insn->id = M680X_INS_ILLGL;
+
+ for (i = 0; i < ARR_SIZE(cpu->pageX_prefix); ++i) {
+ if (cpu->pageX_table_size[i] == 0 ||
+ (cpu->inst_pageX_table[i] == NULL))
+ break;
+
+ if (cpu->pageX_prefix[i] == insn_prefix) {
+ index = binary_search(cpu->inst_pageX_table[i],
+ cpu->pageX_table_size[i], opcode);
+ insn->id = (index >= 0) ?
+ cpu->inst_pageX_table[i][index].insn :
+ M680X_INS_ILLGL;
+ return;
+ }
+ }
+
+ if (insn_prefix != 0)
+ return;
+
+ insn->id = cpu->inst_page1_table[id].insn;
+
+ if (insn->id != M680X_INS_ILLGL)
+ return;
+
+ // Check if opcode byte is present in an overlay table
+ for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
+ if (cpu->overlay_table_size[i] == 0 ||
+ (cpu->inst_overlay_table[i] == NULL))
+ break;
+
+ if ((index = binary_search(cpu->inst_overlay_table[i],
+ cpu->overlay_table_size[i],
+ opcode)) >= 0) {
+ insn->id = cpu->inst_overlay_table[i][index].insn;
+ return;
+ }
+ }
+}
+
+static void add_insn_group(cs_detail *detail, m680x_group_type group)
+{
+ if (detail != NULL &&
+ (group != M680X_GRP_INVALID) && (group != M680X_GRP_ENDING))
+ detail->groups[detail->groups_count++] = (uint8_t)group;
+}
+
+static bool exists_reg_list(uint16_t *regs, uint8_t count, m680x_reg reg)
+{
+ uint8_t i;
+
+ for (i = 0; i < count; ++i) {
+ if (regs[i] == (uint16_t)reg)
+ return true;
+ }
+
+ return false;
+}
+
+static void add_reg_to_rw_list(MCInst *MI, m680x_reg reg, e_access access)
+{
+ cs_detail *detail = MI->flat_insn->detail;
+
+ if (detail == NULL || (reg == M680X_REG_INVALID))
+ return;
+
+ switch (access) {
+ case MODIFY:
+ if (!exists_reg_list(detail->regs_read,
+ detail->regs_read_count, reg))
+ detail->regs_read[detail->regs_read_count++] =
+ (uint16_t)reg;
+
+ // intentionally fall through
+
+ case WRITE:
+ if (!exists_reg_list(detail->regs_write,
+ detail->regs_write_count, reg))
+ detail->regs_write[detail->regs_write_count++] =
+ (uint16_t)reg;
+
+ break;
+
+ case READ:
+ if (!exists_reg_list(detail->regs_read,
+ detail->regs_read_count, reg))
+ detail->regs_read[detail->regs_read_count++] =
+ (uint16_t)reg;
+
+ break;
+
+ case UNCHANGED:
+ default:
+ break;
+ }
+}
+
+static void update_am_reg_list(MCInst *MI, m680x_info *info, cs_m680x_op *op,
+ e_access access)
+{
+ if (MI->flat_insn->detail == NULL)
+ return;
+
+ switch (op->type) {
+ case M680X_OP_REGISTER:
+ add_reg_to_rw_list(MI, op->reg, access);
+ break;
+
+ case M680X_OP_INDEXED:
+ add_reg_to_rw_list(MI, op->idx.base_reg, READ);
+
+ if (op->idx.base_reg == M680X_REG_X &&
+ info->cpu->reg_byte_size[M680X_REG_H])
+ add_reg_to_rw_list(MI, M680X_REG_H, READ);
+
+
+ if (op->idx.offset_reg != M680X_REG_INVALID)
+ add_reg_to_rw_list(MI, op->idx.offset_reg, READ);
+
+ if (op->idx.inc_dec) {
+ add_reg_to_rw_list(MI, op->idx.base_reg, WRITE);
+
+ if (op->idx.base_reg == M680X_REG_X &&
+ info->cpu->reg_byte_size[M680X_REG_H])
+ add_reg_to_rw_list(MI, M680X_REG_H, WRITE);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static const e_access g_access_mode_to_access[4][15] = {
+ {
+ UNCHANGED, READ, WRITE, READ, READ, READ, WRITE, MODIFY,
+ MODIFY, MODIFY, MODIFY, MODIFY, WRITE, READ, MODIFY,
+ },
+ {
+ UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
+ WRITE, MODIFY, WRITE, MODIFY, MODIFY, READ, UNCHANGED,
+ },
+ {
+ UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
+ WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
+ },
+ {
+ UNCHANGED, READ, WRITE, WRITE, MODIFY, MODIFY, READ, READ,
+ WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
+ },
+};
+
+static e_access get_access(int operator_index, e_access_mode access_mode)
+{
+ int idx = (operator_index > 3) ? 3 : operator_index;
+
+ return g_access_mode_to_access[idx][access_mode];
+}
+
+static void build_regs_read_write_counts(MCInst *MI, m680x_info *info,
+ e_access_mode access_mode)
+{
+ cs_m680x *m680x = &info->m680x;
+ int i;
+
+ if (MI->flat_insn->detail == NULL || (!m680x->op_count))
+ return;
+
+ for (i = 0; i < m680x->op_count; ++i) {
+
+ e_access access = get_access(i, access_mode);
+ update_am_reg_list(MI, info, &m680x->operands[i], access);
+ }
+}
+
+static void add_operators_access(MCInst *MI, m680x_info *info,
+ e_access_mode access_mode)
+{
+ cs_m680x *m680x = &info->m680x;
+ int offset = 0;
+ int i;
+
+ if (MI->flat_insn->detail == NULL || (!m680x->op_count) ||
+ (access_mode == uuuu))
+ return;
+
+ for (i = 0; i < m680x->op_count; ++i) {
+ e_access access;
+
+ // Ugly fix: MULD has a register operand, an immediate operand
+ // AND an implicitly changed register W
+ if (info->insn == M680X_INS_MULD && (i == 1))
+ offset = 1;
+
+ access = get_access(i + offset, access_mode);
+ m680x->operands[i].access = access;
+ }
+}
+
+typedef struct insn_to_changed_regs {
+ m680x_insn insn;
+ e_access_mode access_mode;
+ m680x_reg regs[10];
+} insn_to_changed_regs;
+
+static void set_changed_regs_read_write_counts(MCInst *MI, m680x_info *info)
+{
+ //TABLE
+#define EOL M680X_REG_INVALID
+ static const insn_to_changed_regs changed_regs[] = {
+ { M680X_INS_BSR, mmmm, { M680X_REG_S, EOL } },
+ { M680X_INS_CALL, mmmm, { M680X_REG_S, EOL } },
+ {
+ M680X_INS_CWAI, mrrr, {
+ M680X_REG_S, M680X_REG_PC, M680X_REG_U,
+ M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
+ M680X_REG_D, M680X_REG_CC, EOL
+ },
+ },
+ { M680X_INS_DAA, mrrr, { M680X_REG_A, EOL } },
+ {
+ M680X_INS_DIV, mmrr, {
+ M680X_REG_A, M680X_REG_H, M680X_REG_X, EOL
+ }
+ },
+ {
+ M680X_INS_EDIV, mmrr, {
+ M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
+ }
+ },
+ {
+ M680X_INS_EDIVS, mmrr, {
+ M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
+ }
+ },
+ { M680X_INS_EMACS, mrrr, { M680X_REG_X, M680X_REG_Y, EOL } },
+ { M680X_INS_EMAXM, rrrr, { M680X_REG_D, EOL } },
+ { M680X_INS_EMINM, rrrr, { M680X_REG_D, EOL } },
+ { M680X_INS_EMUL, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
+ { M680X_INS_EMULS, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
+ { M680X_INS_ETBL, wmmm, { M680X_REG_A, M680X_REG_B, EOL } },
+ { M680X_INS_FDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
+ { M680X_INS_IDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
+ { M680X_INS_IDIVS, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
+ { M680X_INS_JSR, mmmm, { M680X_REG_S, EOL } },
+ { M680X_INS_LBSR, mmmm, { M680X_REG_S, EOL } },
+ { M680X_INS_MAXM, rrrr, { M680X_REG_A, EOL } },
+ { M680X_INS_MINM, rrrr, { M680X_REG_A, EOL } },
+ {
+ M680X_INS_MEM, mmrr, {
+ M680X_REG_X, M680X_REG_Y, M680X_REG_A, EOL
+ }
+ },
+ { M680X_INS_MUL, mmmm, { M680X_REG_A, M680X_REG_B, EOL } },
+ { M680X_INS_MULD, mwrr, { M680X_REG_D, M680X_REG_W, EOL } },
+ { M680X_INS_PSHA, rmmm, { M680X_REG_A, M680X_REG_S, EOL } },
+ { M680X_INS_PSHB, rmmm, { M680X_REG_B, M680X_REG_S, EOL } },
+ { M680X_INS_PSHC, rmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
+ { M680X_INS_PSHD, rmmm, { M680X_REG_D, M680X_REG_S, EOL } },
+ { M680X_INS_PSHH, rmmm, { M680X_REG_H, M680X_REG_S, EOL } },
+ { M680X_INS_PSHX, rmmm, { M680X_REG_X, M680X_REG_S, EOL } },
+ { M680X_INS_PSHY, rmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
+ { M680X_INS_PULA, wmmm, { M680X_REG_A, M680X_REG_S, EOL } },
+ { M680X_INS_PULB, wmmm, { M680X_REG_B, M680X_REG_S, EOL } },
+ { M680X_INS_PULC, wmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
+ { M680X_INS_PULD, wmmm, { M680X_REG_D, M680X_REG_S, EOL } },
+ { M680X_INS_PULH, wmmm, { M680X_REG_H, M680X_REG_S, EOL } },
+ { M680X_INS_PULX, wmmm, { M680X_REG_X, M680X_REG_S, EOL } },
+ { M680X_INS_PULY, wmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
+ {
+ M680X_INS_REV, mmrr, {
+ M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
+ }
+ },
+ {
+ M680X_INS_REVW, mmmm, {
+ M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
+ }
+ },
+ { M680X_INS_RTC, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
+ {
+ M680X_INS_RTI, mwww, {
+ M680X_REG_S, M680X_REG_CC, M680X_REG_B,
+ M680X_REG_A, M680X_REG_DP, M680X_REG_X,
+ M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
+ EOL
+ },
+ },
+ { M680X_INS_RTS, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
+ { M680X_INS_SEX, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
+ { M680X_INS_SEXW, rwww, { M680X_REG_W, M680X_REG_D, EOL } },
+ {
+ M680X_INS_SWI, mmrr, {
+ M680X_REG_S, M680X_REG_PC, M680X_REG_U,
+ M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC,
+ EOL
+ }
+ },
+ {
+ M680X_INS_SWI2, mmrr, {
+ M680X_REG_S, M680X_REG_PC, M680X_REG_U,
+ M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC,
+ EOL
+ },
+ },
+ {
+ M680X_INS_SWI3, mmrr, {
+ M680X_REG_S, M680X_REG_PC, M680X_REG_U,
+ M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC,
+ EOL
+ },
+ },
+ { M680X_INS_TBL, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
+ {
+ M680X_INS_WAI, mrrr, {
+ M680X_REG_S, M680X_REG_PC, M680X_REG_X,
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC,
+ EOL
+ }
+ },
+ {
+ M680X_INS_WAV, rmmm, {
+ M680X_REG_A, M680X_REG_B, M680X_REG_X,
+ M680X_REG_Y, EOL
+ }
+ },
+ {
+ M680X_INS_WAVR, rmmm, {
+ M680X_REG_A, M680X_REG_B, M680X_REG_X,
+ M680X_REG_Y, EOL
+ }
+ },
+ };
+
+ int i, j;
+
+ if (MI->flat_insn->detail == NULL)
+ return;
+
+ for (i = 0; i < ARR_SIZE(changed_regs); ++i) {
+ if (info->insn == changed_regs[i].insn) {
+ e_access_mode access_mode = changed_regs[i].access_mode;
+
+ for (j = 0; changed_regs[i].regs[j] != EOL; ++j) {
+ e_access access;
+
+ m680x_reg reg = changed_regs[i].regs[j];
+
+ if (!info->cpu->reg_byte_size[reg]) {
+ if (info->insn != M680X_INS_MUL)
+ continue;
+
+ // Hack for M68HC05: MUL uses reg. A,X
+ reg = M680X_REG_X;
+ }
+
+ access = get_access(j, access_mode);
+ add_reg_to_rw_list(MI, reg, access);
+ }
+ }
+ }
+
+#undef EOL
+}
+
+typedef struct insn_desc {
+ uint32_t opcode;
+ m680x_insn insn;
+ insn_hdlr_id hid[2];
+ uint16_t insn_size;
+} insn_desc;
+
+// If successfull return the additional byte size needed for M6809
+// indexed addressing mode (including the indexed addressing post_byte).
+// On error return -1.
+static int get_indexed09_post_byte_size(const m680x_info *info,
+ uint16_t address)
+{
+ uint8_t ir = 0;
+ uint8_t post_byte;
+
+ // Read the indexed addressing post byte.
+ if (!read_byte(info, &post_byte, address))
+ return -1;
+
+ // Depending on the indexed addressing mode more bytes have to be read.
+ switch (post_byte & 0x9F) {
+ case 0x87:
+ case 0x8A:
+ case 0x8E:
+ case 0x8F:
+ case 0x90:
+ case 0x92:
+ case 0x97:
+ case 0x9A:
+ case 0x9E:
+ return -1; // illegal indexed post bytes
+
+ case 0x88: // n8,R
+ case 0x8C: // n8,PCR
+ case 0x98: // [n8,R]
+ case 0x9C: // [n8,PCR]
+ if (!read_byte(info, &ir, address + 1))
+ return -1;
+ return 2;
+
+ case 0x89: // n16,R
+ case 0x8D: // n16,PCR
+ case 0x99: // [n16,R]
+ case 0x9D: // [n16,PCR]
+ if (!read_byte(info, &ir, address + 2))
+ return -1;
+ return 3;
+
+ case 0x9F: // [n]
+ if ((post_byte & 0x60) != 0 ||
+ !read_byte(info, &ir, address + 2))
+ return -1;
+ return 3;
+ }
+
+ // Any other indexed post byte is valid and
+ // no additional bytes have to be read.
+ return 1;
+}
+
+// If successfull return the additional byte size needed for CPU12
+// indexed addressing mode (including the indexed addressing post_byte).
+// On error return -1.
+static int get_indexed12_post_byte_size(const m680x_info *info,
+ uint16_t address, bool is_subset)
+{
+ uint8_t ir;
+ uint8_t post_byte;
+
+ // Read the indexed addressing post byte.
+ if (!read_byte(info, &post_byte, address))
+ return -1;
+
+ // Depending on the indexed addressing mode more bytes have to be read.
+ if (!(post_byte & 0x20)) // n5,R
+ return 1;
+
+ switch (post_byte & 0xe7) {
+ case 0xe0:
+ case 0xe1: // n9,R
+ if (is_subset)
+ return -1;
+
+ if (!read_byte(info, &ir, address))
+ return -1;
+ return 2;
+
+ case 0xe2: // n16,R
+ case 0xe3: // [n16,R]
+ if (is_subset)
+ return -1;
+
+ if (!read_byte(info, &ir, address + 1))
+ return -1;
+ return 3;
+
+ case 0xe4: // A,R
+ case 0xe5: // B,R
+ case 0xe6: // D,R
+ case 0xe7: // [D,R]
+ default: // n,-r n,+r n,r- n,r+
+ break;
+ }
+
+ return 1;
+}
+
+// Check for M6809/HD6309 TFR/EXG instruction for valid register
+static bool is_tfr09_reg_valid(const m680x_info *info, uint8_t reg_nibble)
+{
+ if (info->cpu->tfr_reg_valid != NULL)
+ return info->cpu->tfr_reg_valid[reg_nibble];
+
+ return true; // e.g. for the M6309 all registers are valid
+}
+
+// Check for CPU12 TFR/EXG instruction for valid register
+static bool is_exg_tfr12_post_byte_valid(const m680x_info *info,
+ uint8_t post_byte)
+{
+ return !(post_byte & 0x08);
+}
+
+static bool is_tfm_reg_valid(const m680x_info *info, uint8_t reg_nibble)
+{
+ // HD6809 TFM instruction: Only register X,Y,U,S,D is allowed
+ return reg_nibble <= 4;
+}
+
+// If successfull return the additional byte size needed for CPU12
+// loop instructions DBEQ/DBNE/IBEQ/IBNE/TBEQ/TBNE (including the post byte).
+// On error return -1.
+static int get_loop_post_byte_size(const m680x_info *info, uint16_t address)
+{
+ uint8_t post_byte;
+ uint8_t rr;
+
+ if (!read_byte(info, &post_byte, address))
+ return -1;
+
+ // According to documentation bit 3 is don't care and not checked here.
+ if ((post_byte >= 0xc0) ||
+ ((post_byte & 0x07) == 2) || ((post_byte & 0x07) == 3))
+ return -1;
+
+ if (!read_byte(info, &rr, address + 1))
+ return -1;
+
+ return 2;
+}
+
+// If successfull return the additional byte size needed for HD6309
+// bit move instructions BAND/BEOR/BIAND/BIEOR/BIOR/BOR/LDBT/STBT
+// (including the post byte).
+// On error return -1.
+static int get_bitmv_post_byte_size(const m680x_info *info, uint16_t address)
+{
+ uint8_t post_byte;
+ uint8_t rr;
+
+ if (!read_byte(info, &post_byte, address))
+ return -1;
+
+ if ((post_byte & 0xc0) == 0xc0)
+ return -1; // Invalid register specified
+ else {
+ if (!read_byte(info, &rr, address + 1))
+ return -1;
+ }
+
+ return 2;
+}
+
+static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
+ insn_desc *insn_description)
+{
+ int i;
+ bool retval = true;
+ uint16_t size = 0;
+ int sz;
+
+ for (i = 0; i < 2; i++) {
+ uint8_t ir = 0;
+ bool is_subset = false;
+
+ switch (insn_description->hid[i]) {
+
+ case imm32_hid:
+ if ((retval = read_byte(info, &ir, address + size + 3)))
+ size += 4;
+ break;
+
+ case ext_hid:
+ case imm16_hid:
+ case rel16_hid:
+ case imm8rel_hid:
+ case opidxdr_hid:
+ case idxX16_hid:
+ case idxS16_hid:
+ if ((retval = read_byte(info, &ir, address + size + 1)))
+ size += 2;
+ break;
+
+ case rel8_hid:
+ case dir_hid:
+ case rbits_hid:
+ case imm8_hid:
+ case idxX_hid:
+ case idxXp_hid:
+ case idxY_hid:
+ case idxS_hid:
+ case index_hid:
+ if ((retval = read_byte(info, &ir, address + size)))
+ size++;
+ break;
+
+ case illgl_hid:
+ case inh_hid:
+ case idxX0_hid:
+ case idxX0p_hid:
+ case opidx_hid:
+ retval = true;
+ break;
+
+ case idx09_hid:
+ sz = get_indexed09_post_byte_size(info, address + size);
+ if (sz >= 0)
+ size += sz;
+ else
+ retval = false;
+ break;
+
+ case idx12s_hid:
+ is_subset = true;
+
+ // intentionally fall through
+
+ case idx12_hid:
+ sz = get_indexed12_post_byte_size(info,
+ address + size, is_subset);
+ if (sz >= 0)
+ size += sz;
+ else
+ retval = false;
+ break;
+
+ case exti12x_hid:
+ case imm16i12x_hid:
+ sz = get_indexed12_post_byte_size(info,
+ address + size, false);
+ if (sz >= 0) {
+ size += sz;
+ if ((retval = read_byte(info, &ir,
+ address + size + 1)))
+ size += 2;
+ } else
+ retval = false;
+ break;
+
+ case imm8i12x_hid:
+ sz = get_indexed12_post_byte_size(info,
+ address + size, false);
+ if (sz >= 0) {
+ size += sz;
+ if ((retval = read_byte(info, &ir,
+ address + size)))
+ size++;
+ } else
+ retval = false;
+ break;
+
+ case tfm_hid:
+ if ((retval = read_byte(info, &ir, address + size))) {
+ size++;
+ retval = is_tfm_reg_valid(info, (ir >> 4) & 0x0F) &&
+ is_tfm_reg_valid(info, ir & 0x0F);
+ }
+ break;
+
+ case rr09_hid:
+ if ((retval = read_byte(info, &ir, address + size))) {
+ size++;
+ retval = is_tfr09_reg_valid(info, (ir >> 4) & 0x0F) &&
+ is_tfr09_reg_valid(info, ir & 0x0F);
+ }
+ break;
+
+ case rr12_hid:
+ if ((retval = read_byte(info, &ir, address + size))) {
+ size++;
+ retval = is_exg_tfr12_post_byte_valid(info, ir);
+ }
+ break;
+
+ case bitmv_hid:
+ sz = get_bitmv_post_byte_size(info, address + size);
+ if (sz >= 0)
+ size += sz;
+ else
+ retval = false;
+ break;
+
+ case loop_hid:
+ sz = get_loop_post_byte_size(info, address + size);
+ if (sz >= 0)
+ size += sz;
+ else
+ retval = false;
+ break;
+
+ default:
+ CS_ASSERT(0 && "Unexpected instruction handler id");
+ retval = false;
+ break;
+ }
+
+ if (!retval)
+ return false;
+ }
+
+ insn_description->insn_size += size;
+
+ return retval;
+}
+
+// Check for a valid M680X instruction AND for enough bytes in the code buffer
+// Return an instruction description in insn_desc.
+static bool decode_insn(const m680x_info *info, uint16_t address,
+ insn_desc *insn_description)
+{
+ const inst_pageX *inst_table = NULL;
+ const cpu_tables *cpu = info->cpu;
+ size_t table_size = 0;
+ uint16_t base_address = address;
+ uint8_t ir; // instruction register
+ int i;
+ int index;
+
+ if (!read_byte(info, &ir, address++))
+ return false;
+
+ insn_description->insn = M680X_INS_ILLGL;
+ insn_description->opcode = ir;
+
+ // Check if a page prefix byte is present
+ for (i = 0; i < ARR_SIZE(cpu->pageX_table_size); ++i) {
+ if (cpu->pageX_table_size[i] == 0 ||
+ (cpu->inst_pageX_table[i] == NULL))
+ break;
+
+ if ((cpu->pageX_prefix[i] == ir)) {
+ // Get pageX instruction and handler id.
+ // Abort for illegal instr.
+ inst_table = cpu->inst_pageX_table[i];
+ table_size = cpu->pageX_table_size[i];
+
+ if (!read_byte(info, &ir, address++))
+ return false;
+
+ insn_description->opcode =
+ (insn_description->opcode << 8) | ir;
+
+ if ((index = binary_search(inst_table, table_size,
+ ir)) < 0)
+ return false;
+
+ insn_description->hid[0] =
+ inst_table[index].handler_id1;
+ insn_description->hid[1] =
+ inst_table[index].handler_id2;
+ insn_description->insn = inst_table[index].insn;
+ break;
+ }
+ }
+
+ if (insn_description->insn == M680X_INS_ILLGL) {
+ // Get page1 insn description
+ insn_description->insn = cpu->inst_page1_table[ir].insn;
+ insn_description->hid[0] =
+ cpu->inst_page1_table[ir].handler_id1;
+ insn_description->hid[1] =
+ cpu->inst_page1_table[ir].handler_id2;
+ }
+
+ if (insn_description->insn == M680X_INS_ILLGL) {
+ // Check if opcode byte is present in an overlay table
+ for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
+ if (cpu->overlay_table_size[i] == 0 ||
+ (cpu->inst_overlay_table[i] == NULL))
+ break;
+
+ inst_table = cpu->inst_overlay_table[i];
+ table_size = cpu->overlay_table_size[i];
+
+ if ((index = binary_search(inst_table, table_size,
+ ir)) >= 0) {
+ insn_description->hid[0] =
+ inst_table[index].handler_id1;
+ insn_description->hid[1] =
+ inst_table[index].handler_id2;
+ insn_description->insn = inst_table[index].insn;
+ break;
+ }
+ }
+ }
+
+ insn_description->insn_size = address - base_address;
+
+ return (insn_description->insn != M680X_INS_ILLGL) &&
+ (insn_description->insn != M680X_INS_INVLD) &&
+ is_sufficient_code_size(info, address, insn_description);
+}
+
+static void illegal_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x_op *op0 = &info->m680x.operands[info->m680x.op_count++];
+ uint8_t temp8 = 0;
+
+ info->insn = M680X_INS_ILLGL;
+ read_byte(info, &temp8, (*address)++);
+ op0->imm = (int32_t)temp8 & 0xff;
+ op0->type = M680X_OP_IMMEDIATE;
+ op0->size = 1;
+}
+
+static void inherent_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ // There is nothing to do here :-)
+}
+
+static void add_reg_operand(m680x_info *info, m680x_reg reg)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_REGISTER;
+ op->reg = reg;
+ op->size = info->cpu->reg_byte_size[reg];
+}
+
+static void set_operand_size(m680x_info *info, cs_m680x_op *op,
+ uint8_t default_size)
+{
+ cs_m680x *m680x = &info->m680x;
+
+ if (info->insn == M680X_INS_JMP || info->insn == M680X_INS_JSR)
+ op->size = 0;
+ else if (info->insn == M680X_INS_DIVD ||
+ ((info->insn == M680X_INS_AIS || info->insn == M680X_INS_AIX) &&
+ op->type != M680X_OP_REGISTER))
+ op->size = 1;
+ else if (info->insn == M680X_INS_DIVQ ||
+ info->insn == M680X_INS_MOVW)
+ op->size = 2;
+ else if (info->insn == M680X_INS_EMACS)
+ op->size = 4;
+ else if ((m680x->op_count > 0) &&
+ (m680x->operands[0].type == M680X_OP_REGISTER))
+ op->size = m680x->operands[0].size;
+ else
+ op->size = default_size;
+}
+
+static const m680x_reg reg_s_reg_ids[] = {
+ M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
+ M680X_REG_X, M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
+};
+
+static const m680x_reg reg_u_reg_ids[] = {
+ M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
+ M680X_REG_X, M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
+};
+
+static void reg_bits_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x_op *op0 = &info->m680x.operands[0];
+ uint8_t reg_bits = 0;
+ uint16_t bit_index;
+ const m680x_reg *reg_to_reg_ids = NULL;
+
+ read_byte(info, &reg_bits, (*address)++);
+
+ switch (op0->reg) {
+ case M680X_REG_U:
+ reg_to_reg_ids = &reg_u_reg_ids[0];
+ break;
+
+ case M680X_REG_S:
+ reg_to_reg_ids = &reg_s_reg_ids[0];
+ break;
+
+ default:
+ CS_ASSERT(0 && "Unexpected operand0 register");
+ break;
+ }
+
+ if ((info->insn == M680X_INS_PULU ||
+ (info->insn == M680X_INS_PULS)) &&
+ ((reg_bits & 0x80) != 0))
+ // PULS xxx,PC or PULU xxx,PC which is like return from
+ // subroutine (RTS)
+ add_insn_group(MI->flat_insn->detail, M680X_GRP_RET);
+
+ for (bit_index = 0; bit_index < 8; ++bit_index) {
+ if (reg_bits & (1 << bit_index))
+ add_reg_operand(info, reg_to_reg_ids[bit_index]);
+ }
+}
+
+static const m680x_reg g_tfr_exg_reg_ids[] = {
+ /* 16-bit registers */
+ M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_U,
+ M680X_REG_S, M680X_REG_PC, M680X_REG_W, M680X_REG_V,
+ /* 8-bit registers */
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_DP,
+ M680X_REG_0, M680X_REG_0, M680X_REG_E, M680X_REG_F,
+};
+
+static void reg_reg09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint8_t regs = 0;
+
+ read_byte(info, &regs, (*address)++);
+
+ add_reg_operand(info, g_tfr_exg_reg_ids[regs >> 4]);
+ add_reg_operand(info, g_tfr_exg_reg_ids[regs & 0x0f]);
+
+ if ((regs & 0x0f) == 0x05) {
+ // EXG xxx,PC or TFR xxx,PC which is like a JMP
+ add_insn_group(MI->flat_insn->detail, M680X_GRP_JUMP);
+ }
+}
+
+
+static void reg_reg12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ static const m680x_reg g_tfr_exg12_reg0_ids[] = {
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_TMP3,
+ M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
+ };
+ static const m680x_reg g_tfr_exg12_reg1_ids[] = {
+ M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_TMP2,
+ M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
+ };
+ uint8_t regs = 0;
+
+ read_byte(info, &regs, (*address)++);
+
+ // The opcode of this instruction depends on
+ // the msb of its post byte.
+ if (regs & 0x80)
+ info->insn = M680X_INS_EXG;
+ else
+ info->insn = M680X_INS_TFR;
+
+ add_reg_operand(info, g_tfr_exg12_reg0_ids[(regs >> 4) & 0x07]);
+ add_reg_operand(info, g_tfr_exg12_reg1_ids[regs & 0x07]);
+}
+
+static void add_rel_operand(m680x_info *info, int16_t offset, uint16_t address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_RELATIVE;
+ op->size = 0;
+ op->rel.offset = offset;
+ op->rel.address = address;
+}
+
+static void relative8_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ int16_t offset = 0;
+
+ read_byte_sign_extended(info, &offset, (*address)++);
+ add_rel_operand(info, offset, *address + offset);
+ add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
+
+ if ((info->insn != M680X_INS_BRA) &&
+ (info->insn != M680X_INS_BSR) &&
+ (info->insn != M680X_INS_BRN))
+ add_reg_to_rw_list(MI, M680X_REG_CC, READ);
+}
+
+static void relative16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint16_t offset = 0;
+
+ read_word(info, &offset, *address);
+ *address += 2;
+ add_rel_operand(info, (int16_t)offset, *address + offset);
+ add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
+
+ if ((info->insn != M680X_INS_LBRA) &&
+ (info->insn != M680X_INS_LBSR) &&
+ (info->insn != M680X_INS_LBRN))
+ add_reg_to_rw_list(MI, M680X_REG_CC, READ);
+}
+
+static const m680x_reg g_rr5_to_reg_ids[] = {
+ M680X_REG_X, M680X_REG_Y, M680X_REG_U, M680X_REG_S,
+};
+
+static void add_indexed_operand(m680x_info *info, m680x_reg base_reg,
+ bool post_inc_dec, uint8_t inc_dec, uint8_t offset_bits,
+ uint16_t offset, bool no_comma)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_INDEXED;
+ set_operand_size(info, op, 1);
+ op->idx.base_reg = base_reg;
+ op->idx.offset_reg = M680X_REG_INVALID;
+ op->idx.inc_dec = inc_dec;
+
+ if (inc_dec && post_inc_dec)
+ op->idx.flags |= M680X_IDX_POST_INC_DEC;
+
+ if (offset_bits != M680X_OFFSET_NONE) {
+ op->idx.offset = offset;
+ op->idx.offset_addr = 0;
+ }
+
+ op->idx.offset_bits = offset_bits;
+ op->idx.flags |= (no_comma ? M680X_IDX_NO_COMMA : 0);
+}
+
+// M6800/1/2/3 indexed mode handler
+static void indexedX_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint8_t offset = 0;
+
+ read_byte(info, &offset, (*address)++);
+
+ add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_8,
+ (uint16_t)offset, false);
+}
+
+static void indexedY_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint8_t offset = 0;
+
+ read_byte(info, &offset, (*address)++);
+
+ add_indexed_operand(info, M680X_REG_Y, false, 0, M680X_OFFSET_BITS_8,
+ (uint16_t)offset, false);
+}
+
+// M6809/M6309 indexed mode handler
+static void indexed09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+ uint8_t post_byte = 0;
+ uint16_t offset = 0;
+ int16_t soffset = 0;
+
+ read_byte(info, &post_byte, (*address)++);
+
+ op->type = M680X_OP_INDEXED;
+ set_operand_size(info, op, 1);
+ op->idx.base_reg = g_rr5_to_reg_ids[(post_byte >> 5) & 0x03];
+ op->idx.offset_reg = M680X_REG_INVALID;
+
+ if (!(post_byte & 0x80)) {
+ // n5,R
+ if ((post_byte & 0x10) == 0x10)
+ op->idx.offset = post_byte | 0xfff0;
+ else
+ op->idx.offset = post_byte & 0x0f;
+
+ op->idx.offset_addr = op->idx.offset + *address;
+ op->idx.offset_bits = M680X_OFFSET_BITS_5;
+ }
+ else {
+ if ((post_byte & 0x10) == 0x10)
+ op->idx.flags |= M680X_IDX_INDIRECT;
+
+ // indexed addressing
+ switch (post_byte & 0x1f) {
+ case 0x00: // ,R+
+ op->idx.inc_dec = 1;
+ op->idx.flags |= M680X_IDX_POST_INC_DEC;
+ break;
+
+ case 0x11: // [,R++]
+ case 0x01: // ,R++
+ op->idx.inc_dec = 2;
+ op->idx.flags |= M680X_IDX_POST_INC_DEC;
+ break;
+
+ case 0x02: // ,-R
+ op->idx.inc_dec = -1;
+ break;
+
+ case 0x13: // [,--R]
+ case 0x03: // ,--R
+ op->idx.inc_dec = -2;
+ break;
+
+ case 0x14: // [,R]
+ case 0x04: // ,R
+ break;
+
+ case 0x15: // [B,R]
+ case 0x05: // B,R
+ op->idx.offset_reg = M680X_REG_B;
+ break;
+
+ case 0x16: // [A,R]
+ case 0x06: // A,R
+ op->idx.offset_reg = M680X_REG_A;
+ break;
+
+ case 0x1c: // [n8,PCR]
+ case 0x0c: // n8,PCR
+ op->idx.base_reg = M680X_REG_PC;
+ read_byte_sign_extended(info, &soffset, (*address)++);
+ op->idx.offset_addr = offset + *address;
+ op->idx.offset = soffset;
+ op->idx.offset_bits = M680X_OFFSET_BITS_8;
+ break;
+
+ case 0x18: // [n8,R]
+ case 0x08: // n8,R
+ read_byte_sign_extended(info, &soffset, (*address)++);
+ op->idx.offset = soffset;
+ op->idx.offset_bits = M680X_OFFSET_BITS_8;
+ break;
+
+ case 0x1d: // [n16,PCR]
+ case 0x0d: // n16,PCR
+ op->idx.base_reg = M680X_REG_PC;
+ read_word(info, &offset, *address);
+ *address += 2;
+ op->idx.offset_addr = offset + *address;
+ op->idx.offset = (int16_t)offset;
+ op->idx.offset_bits = M680X_OFFSET_BITS_16;
+ break;
+
+ case 0x19: // [n16,R]
+ case 0x09: // n16,R
+ read_word(info, &offset, *address);
+ *address += 2;
+ op->idx.offset = (int16_t)offset;
+ op->idx.offset_bits = M680X_OFFSET_BITS_16;
+ break;
+
+ case 0x1b: // [D,R]
+ case 0x0b: // D,R
+ op->idx.offset_reg = M680X_REG_D;
+ break;
+
+ case 0x1f: // [n16]
+ op->type = M680X_OP_EXTENDED;
+ op->ext.indirect = true;
+ read_word(info, &op->ext.address, *address);
+ *address += 2;
+ break;
+
+ default:
+ op->idx.base_reg = M680X_REG_INVALID;
+ break;
+ }
+ }
+
+ if (((info->insn == M680X_INS_LEAU) ||
+ (info->insn == M680X_INS_LEAS) ||
+ (info->insn == M680X_INS_LEAX) ||
+ (info->insn == M680X_INS_LEAY)) &&
+ (m680x->operands[0].reg == M680X_REG_X ||
+ (m680x->operands[0].reg == M680X_REG_Y)))
+ // Only LEAX and LEAY modify CC register
+ add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
+}
+
+
+static const m680x_reg g_idx12_to_reg_ids[4] = {
+ M680X_REG_X, M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
+};
+
+static const m680x_reg g_or12_to_reg_ids[3] = {
+ M680X_REG_A, M680X_REG_B, M680X_REG_D
+};
+
+// CPU12 indexed mode handler
+static void indexed12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+ uint8_t post_byte = 0;
+ uint8_t offset8 = 0;
+
+ read_byte(info, &post_byte, (*address)++);
+
+ op->type = M680X_OP_INDEXED;
+ set_operand_size(info, op, 1);
+ op->idx.offset_reg = M680X_REG_INVALID;
+
+ if (!(post_byte & 0x20)) {
+ // n5,R n5 is a 5-bit signed offset
+ op->idx.base_reg = g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
+
+ if ((post_byte & 0x10) == 0x10)
+ op->idx.offset = post_byte | 0xfff0;
+ else
+ op->idx.offset = post_byte & 0x0f;
+
+ op->idx.offset_addr = op->idx.offset + *address;
+ op->idx.offset_bits = M680X_OFFSET_BITS_5;
+ }
+ else {
+ if ((post_byte & 0xe0) == 0xe0)
+ op->idx.base_reg =
+ g_idx12_to_reg_ids[(post_byte >> 3) & 0x03];
+
+ switch (post_byte & 0xe7) {
+ case 0xe0:
+ case 0xe1: // n9,R
+ read_byte(info, &offset8, (*address)++);
+ op->idx.offset = offset8;
+
+ if (post_byte & 0x01) // sign extension
+ op->idx.offset |= 0xff00;
+
+ op->idx.offset_bits = M680X_OFFSET_BITS_9;
+
+ if (op->idx.base_reg == M680X_REG_PC)
+ op->idx.offset_addr = op->idx.offset + *address;
+
+ break;
+
+ case 0xe3: // [n16,R]
+ op->idx.flags |= M680X_IDX_INDIRECT;
+
+ // intentionally fall through
+ case 0xe2: // n16,R
+ read_word(info, (uint16_t *)&op->idx.offset, *address);
+ (*address) += 2;
+ op->idx.offset_bits = M680X_OFFSET_BITS_16;
+
+ if (op->idx.base_reg == M680X_REG_PC)
+ op->idx.offset_addr = op->idx.offset + *address;
+
+ break;
+
+ case 0xe4: // A,R
+ case 0xe5: // B,R
+ case 0xe6: // D,R
+ op->idx.offset_reg =
+ g_or12_to_reg_ids[post_byte & 0x03];
+ break;
+
+ case 0xe7: // [D,R]
+ op->idx.offset_reg = M680X_REG_D;
+ op->idx.flags |= M680X_IDX_INDIRECT;
+ break;
+
+ default: // n,-r n,+r n,r- n,r+
+ // PC is not allowed in this mode
+ op->idx.base_reg =
+ g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
+ op->idx.inc_dec = post_byte & 0x0f;
+
+ if (op->idx.inc_dec & 0x08) // evtl. sign extend value
+ op->idx.inc_dec |= 0xf0;
+
+ if (op->idx.inc_dec >= 0)
+ op->idx.inc_dec++;
+
+ if (post_byte & 0x10)
+ op->idx.flags |= M680X_IDX_POST_INC_DEC;
+
+ break;
+
+ }
+ }
+}
+
+static void index_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_CONSTANT;
+ read_byte(info, &op->const_val, (*address)++);
+};
+
+static void direct_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_DIRECT;
+ set_operand_size(info, op, 1);
+ read_byte(info, &op->direct_addr, (*address)++);
+};
+
+static void extended_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_EXTENDED;
+ set_operand_size(info, op, 1);
+ read_word(info, &op->ext.address, *address);
+ *address += 2;
+}
+
+static void immediate_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+ uint16_t word = 0;
+ int16_t sword = 0;
+
+ op->type = M680X_OP_IMMEDIATE;
+ set_operand_size(info, op, 1);
+
+ switch (op->size) {
+ case 1:
+ read_byte_sign_extended(info, &sword, *address);
+ op->imm = sword;
+ break;
+
+ case 2:
+ read_word(info, &word, *address);
+ op->imm = (int16_t)word;
+ break;
+
+ case 4:
+ read_sdword(info, &op->imm, *address);
+ break;
+
+ default:
+ op->imm = 0;
+ CS_ASSERT(0 && "Unexpected immediate byte size");
+ }
+
+ *address += op->size;
+}
+
+// handler for bit move instructions, e.g: BAND A,5,1,$40 Used by HD6309
+static void bit_move_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ static const m680x_reg m680x_reg[] = {
+ M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_INVALID,
+ };
+
+ uint8_t post_byte = 0;
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op;
+
+ read_byte(info, &post_byte, *address);
+ (*address)++;
+
+ // operand[0] = register
+ add_reg_operand(info, m680x_reg[post_byte >> 6]);
+
+ // operand[1] = bit index in source operand
+ op = &m680x->operands[m680x->op_count++];
+ op->type = M680X_OP_CONSTANT;
+ op->const_val = (post_byte >> 3) & 0x07;
+
+ // operand[2] = bit index in destination operand
+ op = &m680x->operands[m680x->op_count++];
+ op->type = M680X_OP_CONSTANT;
+ op->const_val = post_byte & 0x07;
+
+ direct_hdlr(MI, info, address);
+}
+
+// handler for TFM instruction, e.g: TFM X+,Y+ Used by HD6309
+static void tfm_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ static const uint8_t inc_dec_r0[] = {
+ 1, -1, 1, 0,
+ };
+ static const uint8_t inc_dec_r1[] = {
+ 1, -1, 0, 1,
+ };
+ uint8_t regs = 0;
+ uint8_t index = (MI->Opcode & 0xff) - 0x38;
+
+ read_byte(info, &regs, *address);
+
+ add_indexed_operand(info, g_tfr_exg_reg_ids[regs >> 4], true,
+ inc_dec_r0[index], M680X_OFFSET_NONE, 0, true);
+ add_indexed_operand(info, g_tfr_exg_reg_ids[regs & 0x0f], true,
+ inc_dec_r1[index], M680X_OFFSET_NONE, 0, true);
+
+ add_reg_to_rw_list(MI, M680X_REG_W, READ | WRITE);
+}
+
+static void opidx_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ // bit index is coded in Opcode
+ op->type = M680X_OP_CONSTANT;
+ op->const_val = (MI->Opcode & 0x0e) >> 1;
+}
+
+// handler for bit test and branch instruction. Used by M6805.
+// The bit index is part of the opcode.
+// Example: BRSET 3,<$40,LOOP
+static void opidx_dir_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ // bit index is coded in Opcode
+ op->type = M680X_OP_CONSTANT;
+ op->const_val = (MI->Opcode & 0x0e) >> 1;
+ direct_hdlr(MI, info, address);
+ relative8_hdlr(MI, info, address);
+
+ add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
+}
+
+static void indexedX0_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_NONE,
+ 0, false);
+}
+
+static void indexedX16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint16_t offset = 0;
+
+ read_word(info, &offset, *address);
+ *address += 2;
+ add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_16,
+ offset, false);
+}
+
+static void imm_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ immediate_hdlr(MI, info, address);
+ relative8_hdlr(MI, info, address);
+}
+
+static void indexedS_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint8_t offset = 0;
+
+ read_byte(info, &offset, (*address)++);
+
+ add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_8,
+ (uint16_t)offset, false);
+}
+
+static void indexedS16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint16_t offset = 0;
+
+ read_word(info, &offset, *address);
+ address += 2;
+
+ add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_16,
+ offset, false);
+}
+
+static void indexedX0p_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_NONE,
+ 0, true);
+}
+
+static void indexedXp_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ uint8_t offset = 0;
+
+ read_byte(info, &offset, (*address)++);
+
+ add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_BITS_8,
+ (uint16_t)offset, false);
+}
+
+static void imm_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op = &m680x->operands[m680x->op_count++];
+
+ indexed12_hdlr(MI, info, address);
+ op->type = M680X_OP_IMMEDIATE;
+
+ if (info->insn == M680X_INS_MOVW) {
+ uint16_t imm16 = 0;
+
+ read_word(info, &imm16, *address);
+ op->imm = (int16_t)imm16;
+ op->size = 2;
+ }
+ else {
+ uint8_t imm8 = 0;
+
+ read_byte(info, &imm8, *address);
+ op->imm = (int8_t)imm8;
+ op->size = 1;
+ }
+
+ set_operand_size(info, op, 1);
+}
+
+static void ext_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_m680x_op *op0 = &m680x->operands[m680x->op_count++];
+ uint16_t imm16 = 0;
+
+ indexed12_hdlr(MI, info, address);
+ read_word(info, &imm16, *address);
+ op0->type = M680X_OP_EXTENDED;
+ op0->ext.address = (int16_t)imm16;
+ set_operand_size(info, op0, 1);
+}
+
+// handler for CPU12 DBEQ/DNBE/IBEQ/IBNE/TBEQ/TBNE instructions.
+// Example: DBNE X,$1000
+static void loop_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
+{
+ static const m680x_reg index_to_reg_id[] = {
+ M680X_REG_A, M680X_REG_B, M680X_REG_INVALID, M680X_REG_INVALID,
+ M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
+ };
+ static const m680x_insn index_to_insn_id[] = {
+ M680X_INS_DBEQ, M680X_INS_DBNE, M680X_INS_TBEQ, M680X_INS_TBNE,
+ M680X_INS_IBEQ, M680X_INS_IBNE, M680X_INS_ILLGL, M680X_INS_ILLGL
+ };
+ cs_m680x *m680x = &info->m680x;
+ uint8_t post_byte = 0;
+ uint8_t rel = 0;
+ cs_m680x_op *op;
+
+ read_byte(info, &post_byte, (*address)++);
+
+ info->insn = index_to_insn_id[(post_byte >> 5) & 0x07];
+
+ if (info->insn == M680X_INS_ILLGL) {
+ illegal_hdlr(MI, info, address);
+ };
+
+ read_byte(info, &rel, (*address)++);
+
+ add_reg_operand(info, index_to_reg_id[post_byte & 0x07]);
+
+ op = &m680x->operands[m680x->op_count++];
+
+ op->type = M680X_OP_RELATIVE;
+
+ op->rel.offset = (post_byte & 0x10) ? 0xff00 | rel : rel;
+
+ op->rel.address = *address + op->rel.offset;
+
+ add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
+}
+
+static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
+ illegal_hdlr,
+ relative8_hdlr,
+ relative16_hdlr,
+ immediate_hdlr, // 8-bit
+ immediate_hdlr, // 16-bit
+ immediate_hdlr, // 32-bit
+ direct_hdlr,
+ extended_hdlr,
+ indexedX_hdlr,
+ indexedY_hdlr,
+ indexed09_hdlr,
+ inherent_hdlr,
+ reg_reg09_hdlr,
+ reg_bits_hdlr,
+ bit_move_hdlr,
+ tfm_hdlr,
+ opidx_hdlr,
+ opidx_dir_rel_hdlr,
+ indexedX0_hdlr,
+ indexedX16_hdlr,
+ imm_rel_hdlr,
+ indexedS_hdlr,
+ indexedS16_hdlr,
+ indexedXp_hdlr,
+ indexedX0p_hdlr,
+ indexed12_hdlr,
+ indexed12_hdlr, // subset of indexed12
+ reg_reg12_hdlr,
+ loop_hdlr,
+ index_hdlr,
+ imm_idx12_x_hdlr,
+ imm_idx12_x_hdlr,
+ ext_idx12_x_hdlr,
+}; /* handler function pointers */
+
+/* Disasemble one instruction at address and store in str_buff */
+static unsigned int m680x_disassemble(MCInst *MI, m680x_info *info,
+ uint16_t address)
+{
+ cs_m680x *m680x = &info->m680x;
+ cs_detail *detail = MI->flat_insn->detail;
+ uint16_t base_address = address;
+ insn_desc insn_description;
+ e_access_mode access_mode;
+
+ if (detail != NULL) {
+ memset(detail, 0, offsetof(cs_detail, m680x)+sizeof(cs_m680x));
+ }
+
+ memset(&insn_description, 0, sizeof(insn_description));
+ memset(m680x, 0, sizeof(*m680x));
+ info->insn_size = 1;
+
+ if (decode_insn(info, address, &insn_description)) {
+ m680x_reg reg;
+
+ if (insn_description.opcode > 0xff)
+ address += 2; // 8-bit opcode + page prefix
+ else
+ address++; // 8-bit opcode only
+
+ info->insn = insn_description.insn;
+
+ MCInst_setOpcode(MI, insn_description.opcode);
+
+ reg = g_insn_props[info->insn].reg0;
+
+ if (reg != M680X_REG_INVALID) {
+ if (reg == M680X_REG_HX &&
+ (!info->cpu->reg_byte_size[reg]))
+ reg = M680X_REG_X;
+
+ add_reg_operand(info, reg);
+ // First (or second) operand is a register which is
+ // part of the mnemonic
+ m680x->flags |= M680X_FIRST_OP_IN_MNEM;
+ reg = g_insn_props[info->insn].reg1;
+
+ if (reg != M680X_REG_INVALID) {
+ if (reg == M680X_REG_HX &&
+ (!info->cpu->reg_byte_size[reg]))
+ reg = M680X_REG_X;
+
+ add_reg_operand(info, reg);
+ m680x->flags |= M680X_SECOND_OP_IN_MNEM;
+ }
+ }
+
+ // Call addressing mode specific instruction handler
+ (g_insn_handler[insn_description.hid[0]])(MI, info,
+ &address);
+ (g_insn_handler[insn_description.hid[1]])(MI, info,
+ &address);
+
+ add_insn_group(detail, g_insn_props[info->insn].group);
+
+ if (g_insn_props[info->insn].cc_modified &&
+ (info->cpu->insn_cc_not_modified[0] != info->insn) &&
+ (info->cpu->insn_cc_not_modified[1] != info->insn))
+ add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
+
+ access_mode = g_insn_props[info->insn].access_mode;
+
+ // Fix for M6805 BSET/BCLR. It has a differnt operand order
+ // in comparison to the M6811
+ if ((info->cpu->insn_cc_not_modified[0] == info->insn) ||
+ (info->cpu->insn_cc_not_modified[1] == info->insn))
+ access_mode = rmmm;
+
+ build_regs_read_write_counts(MI, info, access_mode);
+ add_operators_access(MI, info, access_mode);
+
+ if (g_insn_props[info->insn].update_reg_access)
+ set_changed_regs_read_write_counts(MI, info);
+
+ info->insn_size = (uint8_t)insn_description.insn_size;
+
+ return info->insn_size;
+ }
+ else
+ MCInst_setOpcode(MI, insn_description.opcode);
+
+ // Illegal instruction
+ address = base_address;
+ illegal_hdlr(MI, info, &address);
+ return 1;
+}
+
+// Tables to get the byte size of a register on the CPU
+// based on an enum m680x_reg value.
+// Invalid registers return 0.
+static const uint8_t g_m6800_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_m6805_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_m6808_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_m6801_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_m6811_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_cpu12_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2
+};
+
+static const uint8_t g_m6809_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0
+};
+
+static const uint8_t g_hd6309_reg_byte_size[22] = {
+ // A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
+ 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0
+};
+
+// Table to check for a valid register nibble on the M6809 CPU
+// used for TFR and EXG instruction.
+static const bool m6809_tfr_reg_valid[16] = {
+ true, true, true, true, true, true, false, false,
+ true, true, true, true, false, false, false, false,
+};
+
+static const cpu_tables g_cpu_tables[] = {
+ {
+ // M680X_CPU_TYPE_INVALID
+ NULL,
+ { NULL, NULL },
+ { 0, 0 },
+ { 0x00, 0x00, 0x00 },
+ { NULL, NULL, NULL },
+ { 0, 0, 0 },
+ NULL,
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6301
+ &g_m6800_inst_page1_table[0],
+ { &g_m6801_inst_overlay_table[0], &g_hd6301_inst_overlay_table[0] },
+ {
+ ARR_SIZE(g_m6801_inst_overlay_table),
+ ARR_SIZE(g_hd6301_inst_overlay_table)
+ },
+ { 0x00, 0x00, 0x00 },
+ { NULL, NULL, NULL },
+ { 0, 0, 0 },
+ &g_m6801_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6309
+ &g_m6809_inst_page1_table[0],
+ { &g_hd6309_inst_overlay_table[0], NULL },
+ { ARR_SIZE(g_hd6309_inst_overlay_table), 0 },
+ { 0x10, 0x11, 0x00 },
+ { &g_hd6309_inst_page2_table[0], &g_hd6309_inst_page3_table[0], NULL },
+ {
+ ARR_SIZE(g_hd6309_inst_page2_table),
+ ARR_SIZE(g_hd6309_inst_page3_table),
+ 0
+ },
+ &g_hd6309_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6800
+ &g_m6800_inst_page1_table[0],
+ { NULL, NULL },
+ { 0, 0 },
+ { 0x00, 0x00, 0x00 },
+ { NULL, NULL, NULL },
+ { 0, 0, 0 },
+ &g_m6800_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6801
+ &g_m6800_inst_page1_table[0],
+ { &g_m6801_inst_overlay_table[0], NULL },
+ { ARR_SIZE(g_m6801_inst_overlay_table), 0 },
+ { 0x00, 0x00, 0x00 },
+ { NULL, NULL, NULL },
+ { 0, 0, 0 },
+ &g_m6801_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6805
+ &g_m6805_inst_page1_table[0],
+ { NULL, NULL },
+ { 0, 0 },
+ { 0x00, 0x00, 0x00 },
+ { NULL, NULL, NULL },
+ { 0, 0, 0 },
+ &g_m6805_reg_byte_size[0],
+ NULL,
+ { M680X_INS_BCLR, M680X_INS_BSET }
+ },
+ {
+ // M680X_CPU_TYPE_6808
+ &g_m6805_inst_page1_table[0],
+ { &g_m6808_inst_overlay_table[0], NULL },
+ { ARR_SIZE(g_m6808_inst_overlay_table), 0 },
+ { 0x9E, 0x00, 0x00 },
+ { &g_m6808_inst_page2_table[0], NULL, NULL },
+ { ARR_SIZE(g_m6808_inst_page2_table), 0, 0 },
+ &g_m6808_reg_byte_size[0],
+ NULL,
+ { M680X_INS_BCLR, M680X_INS_BSET }
+ },
+ {
+ // M680X_CPU_TYPE_6809
+ &g_m6809_inst_page1_table[0],
+ { NULL, NULL },
+ { 0, 0 },
+ { 0x10, 0x11, 0x00 },
+ {
+ &g_m6809_inst_page2_table[0],
+ &g_m6809_inst_page3_table[0],
+ NULL
+ },
+ {
+ ARR_SIZE(g_m6809_inst_page2_table),
+ ARR_SIZE(g_m6809_inst_page3_table),
+ 0
+ },
+ &g_m6809_reg_byte_size[0],
+ &m6809_tfr_reg_valid[0],
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_6811
+ &g_m6800_inst_page1_table[0],
+ {
+ &g_m6801_inst_overlay_table[0],
+ &g_m6811_inst_overlay_table[0]
+ },
+ {
+ ARR_SIZE(g_m6801_inst_overlay_table),
+ ARR_SIZE(g_m6811_inst_overlay_table)
+ },
+ { 0x18, 0x1A, 0xCD },
+ {
+ &g_m6811_inst_page2_table[0],
+ &g_m6811_inst_page3_table[0],
+ &g_m6811_inst_page4_table[0]
+ },
+ {
+ ARR_SIZE(g_m6811_inst_page2_table),
+ ARR_SIZE(g_m6811_inst_page3_table),
+ ARR_SIZE(g_m6811_inst_page4_table)
+ },
+ &g_m6811_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_CPU12
+ &g_cpu12_inst_page1_table[0],
+ { NULL, NULL },
+ { 0, 0 },
+ { 0x18, 0x00, 0x00 },
+ { &g_cpu12_inst_page2_table[0], NULL, NULL },
+ { ARR_SIZE(g_cpu12_inst_page2_table), 0, 0 },
+ &g_cpu12_reg_byte_size[0],
+ NULL,
+ { M680X_INS_INVLD, M680X_INS_INVLD }
+ },
+ {
+ // M680X_CPU_TYPE_HCS08
+ &g_m6805_inst_page1_table[0],
+ {
+ &g_m6808_inst_overlay_table[0],
+ &g_hcs08_inst_overlay_table[0]
+ },
+ {
+ ARR_SIZE(g_m6808_inst_overlay_table),
+ ARR_SIZE(g_hcs08_inst_overlay_table)
+ },
+ { 0x9E, 0x00, 0x00 },
+ { &g_hcs08_inst_page2_table[0], NULL, NULL },
+ { ARR_SIZE(g_hcs08_inst_page2_table), 0, 0 },
+ &g_m6808_reg_byte_size[0],
+ NULL,
+ { M680X_INS_BCLR, M680X_INS_BSET }
+ },
+};
+
+static const char * const s_cpu_type[] = {
+ "INVALID", "6301", "6309", "6800", "6801", "6805", "6808",
+ "6809", "6811", "CPU12", "HCS08",
+};
+
+static bool m680x_setup_internals(m680x_info *info, e_cpu_type cpu_type,
+ uint16_t address,
+ const uint8_t *code, uint16_t code_len)
+{
+ if (cpu_type == M680X_CPU_TYPE_INVALID) {
+ return false;
+ }
+
+ info->code = code;
+ info->size = code_len;
+ info->offset = address;
+ info->cpu_type = cpu_type;
+
+ info->cpu = &g_cpu_tables[info->cpu_type];
+
+ return true;
+}
+
+bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
+ MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
+{
+ unsigned int insn_size = 0;
+ e_cpu_type cpu_type = M680X_CPU_TYPE_INVALID; // No default CPU type
+ cs_struct *handle = (cs_struct *)ud;
+ m680x_info *info = (m680x_info *)handle->printer_info;
+
+ MCInst_clear(MI);
+
+ if (handle->mode & CS_MODE_M680X_6800)
+ cpu_type = M680X_CPU_TYPE_6800;
+
+ else if (handle->mode & CS_MODE_M680X_6801)
+ cpu_type = M680X_CPU_TYPE_6801;
+
+ else if (handle->mode & CS_MODE_M680X_6805)
+ cpu_type = M680X_CPU_TYPE_6805;
+
+ else if (handle->mode & CS_MODE_M680X_6808)
+ cpu_type = M680X_CPU_TYPE_6808;
+
+ else if (handle->mode & CS_MODE_M680X_HCS08)
+ cpu_type = M680X_CPU_TYPE_HCS08;
+
+ else if (handle->mode & CS_MODE_M680X_6809)
+ cpu_type = M680X_CPU_TYPE_6809;
+
+ else if (handle->mode & CS_MODE_M680X_6301)
+ cpu_type = M680X_CPU_TYPE_6301;
+
+ else if (handle->mode & CS_MODE_M680X_6309)
+ cpu_type = M680X_CPU_TYPE_6309;
+
+ else if (handle->mode & CS_MODE_M680X_6811)
+ cpu_type = M680X_CPU_TYPE_6811;
+
+ else if (handle->mode & CS_MODE_M680X_CPU12)
+ cpu_type = M680X_CPU_TYPE_CPU12;
+
+ if (cpu_type != M680X_CPU_TYPE_INVALID &&
+ m680x_setup_internals(info, cpu_type, (uint16_t)address, code,
+ (uint16_t)code_len))
+ insn_size = m680x_disassemble(MI, info, (uint16_t)address);
+
+ if (insn_size == 0) {
+ *size = 1;
+ return false;
+ }
+
+ // Make sure we always stay within range
+ if (insn_size > code_len) {
+ *size = (uint16_t)code_len;
+ return false;
+ }
+ else
+ *size = (uint16_t)insn_size;
+
+ return true;
+}
+
+cs_err M680X_disassembler_init(cs_struct *ud)
+{
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6800_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6800_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6801_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6801_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6805_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6805_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6808_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6808_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6811_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6811_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_cpu12_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_cpu12_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_REG_ENDING != ARR_SIZE(g_m6809_reg_byte_size)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6809_reg_byte_size));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_INS_ENDING != ARR_SIZE(g_insn_props)) {
+ CS_ASSERT(M680X_INS_ENDING == ARR_SIZE(g_insn_props));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_CPU_TYPE_ENDING != ARR_SIZE(s_cpu_type)) {
+ CS_ASSERT(M680X_CPU_TYPE_ENDING == ARR_SIZE(s_cpu_type));
+
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_CPU_TYPE_ENDING != ARR_SIZE(g_cpu_tables)) {
+ CS_ASSERT(M680X_CPU_TYPE_ENDING == ARR_SIZE(g_cpu_tables));
+
+ return CS_ERR_MODE;
+ }
+
+ if (HANDLER_ID_ENDING != ARR_SIZE(g_insn_handler)) {
+ CS_ASSERT(HANDLER_ID_ENDING == ARR_SIZE(g_insn_handler));
+
+ return CS_ERR_MODE;
+ }
+
+ if (ACCESS_MODE_ENDING != MATRIX_SIZE(g_access_mode_to_access)) {
+ CS_ASSERT(ACCESS_MODE_ENDING ==
+ MATRIX_SIZE(g_access_mode_to_access));
+
+ return CS_ERR_MODE;
+ }
+
+ return CS_ERR_OK;
+}
+
+#ifndef CAPSTONE_DIET
+void M680X_reg_access(const cs_insn *insn,
+ cs_regs regs_read, uint8_t *regs_read_count,
+ cs_regs regs_write, uint8_t *regs_write_count)
+{
+ if (insn->detail == NULL) {
+ *regs_read_count = 0;
+ *regs_write_count = 0;
+ }
+ else {
+ *regs_read_count = insn->detail->regs_read_count;
+ *regs_write_count = insn->detail->regs_write_count;
+
+ memcpy(regs_read, insn->detail->regs_read,
+ *regs_read_count * sizeof(insn->detail->regs_read[0]));
+ memcpy(regs_write, insn->detail->regs_write,
+ *regs_write_count *
+ sizeof(insn->detail->regs_write[0]));
+ }
+}
+#endif
+
+#endif
+
diff --git a/capstone/arch/M680X/M680XDisassembler.h b/capstone/arch/M680X/M680XDisassembler.h
new file mode 100644
index 000000000..d85a3cca6
--- /dev/null
+++ b/capstone/arch/M680X/M680XDisassembler.h
@@ -0,0 +1,17 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+#ifndef CS_M680XDISASSEMBLER_H
+#define CS_M680XDISASSEMBLER_H
+
+#include "../../MCInst.h"
+
+bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
+ MCInst *instr, uint16_t *size, uint64_t address, void *info);
+void M680X_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
+void M680X_reg_access(const cs_insn *insn,
+ cs_regs regs_read, uint8_t *regs_read_count,
+ cs_regs regs_write, uint8_t *regs_write_count);
+
+#endif
+
diff --git a/capstone/arch/M680X/M680XDisassemblerInternals.h b/capstone/arch/M680X/M680XDisassemblerInternals.h
new file mode 100644
index 000000000..2f59c3f59
--- /dev/null
+++ b/capstone/arch/M680X/M680XDisassemblerInternals.h
@@ -0,0 +1,57 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+#ifndef CS_M680XDISASSEMBLERINTERNALS_H
+#define CS_M680XDISASSEMBLERINTERNALS_H
+
+#include "../../MCInst.h"
+#include "../../include/capstone/m680x.h"
+
+typedef enum e_cpu_type {
+ M680X_CPU_TYPE_INVALID,
+ M680X_CPU_TYPE_6301, // M680X Hitachi HD6301,HD6303 mode
+ M680X_CPU_TYPE_6309, // M680X Hitachi HD6309 mode
+ M680X_CPU_TYPE_6800, // M680X Motorola 6800,6802 mode
+ M680X_CPU_TYPE_6801, // M680X Motorola 6801,6803 mode
+ M680X_CPU_TYPE_6805, // M680X Motorola/Freescale M68HC05 mode
+ M680X_CPU_TYPE_6808, // M680X Motorola/Freescale M68HC08 mode
+ M680X_CPU_TYPE_6809, // M680X Motorola 6809 mode
+ M680X_CPU_TYPE_6811, // M680X Motorola/Freescale M68HC11 mode
+ M680X_CPU_TYPE_CPU12, // M680X Motorola/Freescale CPU12 mode
+ // used on M68HC12/HCS12
+ M680X_CPU_TYPE_HCS08, // M680X Freescale HCS08 mode
+ M680X_CPU_TYPE_ENDING,
+} e_cpu_type;
+
+struct inst_page1;
+struct inst_pageX;
+
+typedef struct {
+ const struct inst_page1 *inst_page1_table;
+ const struct inst_pageX *inst_overlay_table[2];
+ size_t overlay_table_size[2];
+ uint8_t pageX_prefix[3];
+ const struct inst_pageX *inst_pageX_table[3];
+ size_t pageX_table_size[3];
+ const uint8_t *reg_byte_size;
+ const bool *tfr_reg_valid;
+ m680x_insn insn_cc_not_modified[2];
+} cpu_tables;
+
+/* Private, For internal use only */
+typedef struct m680x_info {
+ const uint8_t *code; // code buffer
+ uint32_t size; // byte size of code
+ uint16_t offset; // address offset of first byte in code buffer
+ e_cpu_type cpu_type; // The CPU type to be used for disassembling
+ cs_m680x m680x; // M680X specific properties
+ const cpu_tables *cpu;
+ m680x_insn insn; // Instruction ID
+ uint8_t insn_size; // byte size of instruction
+} m680x_info;
+
+extern cs_err M680X_disassembler_init(cs_struct *ud);
+extern cs_err M680X_instprinter_init(cs_struct *ud);
+
+#endif
+
diff --git a/capstone/arch/M680X/M680XInstPrinter.c b/capstone/arch/M680X/M680XInstPrinter.c
new file mode 100644
index 000000000..83a949098
--- /dev/null
+++ b/capstone/arch/M680X/M680XInstPrinter.c
@@ -0,0 +1,360 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+#ifdef CAPSTONE_HAS_M680X
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <capstone/platform.h>
+
+#include "../../cs_priv.h"
+#include "../../MCInst.h"
+#include "../../SStream.h"
+#include "../../MCRegisterInfo.h"
+#include "../../utils.h"
+#include "M680XInstPrinter.h"
+#include "M680XDisassembler.h"
+#include "M680XDisassemblerInternals.h"
+
+#ifndef CAPSTONE_DIET
+static const char s_reg_names[][10] = {
+ "<invalid>", "a", "b", "e", "f", "0", "d", "w", "cc", "dp", "md",
+ "hx", "h", "x", "y", "s", "u", "v", "q", "pc", "tmp2", "tmp3",
+};
+
+static const char s_instruction_names[][6] = {
+ "invld", "aba", "abx", "aby", "adc", "adca", "adcb", "adcd", "adcr",
+ "add", "adda", "addb", "addd", "adde", "addf", "addr", "addw",
+ "aim", "ais", "aix", "and", "anda", "andb", "andcc", "andd", "andr",
+ "asl", "asla", "aslb", "asld",
+ "asr", "asra", "asrb", "asrd", "asrx",
+ "band",
+ "bcc", "bclr", "bcs", "beor", "beq", "bge", "bgnd", "bgt", "bhcc",
+ "bhcs", "bhi",
+ "biand", "bieor", "bih", "bil",
+ "bior", "bit", "bita", "bitb", "bitd", "bitmd", "ble", "bls", "blt",
+ "bmc",
+ "bmi", "bms",
+ "bne", "bor", "bpl", "brclr", "brset", "bra", "brn", "bset", "bsr",
+ "bvc", "bvs",
+ "call", "cba", "cbeq", "cbeqa", "cbeqx", "clc", "cli",
+ "clr", "clra", "clrb", "clrd", "clre", "clrf", "clrh", "clrw", "clrx",
+ "clv", "cmp",
+ "cmpa", "cmpb", "cmpd", "cmpe", "cmpf", "cmpr", "cmps", "cmpu", "cmpw",
+ "cmpx", "cmpy",
+ "com", "coma", "comb", "comd", "come", "comf", "comw", "comx", "cpd",
+ "cphx", "cps", "cpx", "cpy",
+ "cwai", "daa", "dbeq", "dbne", "dbnz", "dbnza", "dbnzx",
+ "dec", "deca", "decb", "decd", "dece", "decf", "decw",
+ "decx", "des", "dex", "dey",
+ "div", "divd", "divq", "ediv", "edivs", "eim", "emacs", "emaxd",
+ "emaxm", "emind", "eminm", "emul", "emuls",
+ "eor", "eora", "eorb", "eord", "eorr", "etbl",
+ "exg", "fdiv", "ibeq", "ibne", "idiv", "idivs", "illgl",
+ "inc", "inca", "incb", "incd", "ince", "incf", "incw", "incx",
+ "ins", "inx", "iny",
+ "jmp", "jsr",
+ "lbcc", "lbcs", "lbeq", "lbge", "lbgt", "lbhi", "lble", "lbls", "lblt",
+ "lbmi", "lbne", "lbpl", "lbra", "lbrn", "lbsr", "lbvc", "lbvs",
+ "lda", "ldaa", "ldab", "ldb", "ldbt", "ldd", "lde", "ldf", "ldhx",
+ "ldmd",
+ "ldq", "lds", "ldu", "ldw", "ldx", "ldy",
+ "leas", "leau", "leax", "leay",
+ "lsl", "lsla", "lslb", "lsld", "lslx",
+ "lsr", "lsra", "lsrb", "lsrd", "lsrw", "lsrx",
+ "maxa", "maxm", "mem", "mina", "minm", "mov", "movb", "movw", "mul",
+ "muld",
+ "neg", "nega", "negb", "negd", "negx",
+ "nop", "nsa", "oim", "ora", "oraa", "orab", "orb", "orcc", "ord", "orr",
+ "psha", "pshb", "pshc", "pshd", "pshh", "pshs", "pshsw", "pshu",
+ "pshuw", "pshx", "pshy",
+ "pula", "pulb", "pulc", "puld", "pulh", "puls", "pulsw", "pulu",
+ "puluw", "pulx", "puly", "rev", "revw",
+ "rol", "rola", "rolb", "rold", "rolw", "rolx",
+ "ror", "rora", "rorb", "rord", "rorw", "rorx",
+ "rsp", "rtc", "rti", "rts", "sba", "sbc", "sbca", "sbcb", "sbcd",
+ "sbcr",
+ "sec", "sei", "sev", "sex", "sexw", "slp", "sta", "staa", "stab", "stb",
+ "stbt", "std", "ste", "stf", "stop", "sthx",
+ "stq", "sts", "stu", "stw", "stx", "sty",
+ "sub", "suba", "subb", "subd", "sube", "subf", "subr", "subw",
+ "swi", "swi2", "swi3",
+ "sync", "tab", "tap", "tax", "tba", "tbeq", "tbl", "tbne", "test",
+ "tfm", "tfr",
+ "tim", "tpa",
+ "tst", "tsta", "tstb", "tstd", "tste", "tstf", "tstw", "tstx",
+ "tsx", "tsy", "txa", "txs", "tys", "wai", "wait", "wav", "wavr",
+ "xgdx", "xgdy",
+};
+
+static const name_map s_group_names[] = {
+ { M680X_GRP_INVALID, "<invalid>" },
+ { M680X_GRP_JUMP, "jump" },
+ { M680X_GRP_CALL, "call" },
+ { M680X_GRP_RET, "return" },
+ { M680X_GRP_INT, "interrupt" },
+ { M680X_GRP_IRET, "interrupt_return" },
+ { M680X_GRP_PRIV, "privileged" },
+ { M680X_GRP_BRAREL, "branch_relative" },
+};
+#endif
+
+static void printRegName(cs_struct *handle, SStream *OS, unsigned int reg)
+{
+#ifndef CAPSTONE_DIET
+ SStream_concat(OS, handle->reg_name((csh)handle, reg));
+#endif
+}
+
+static void printInstructionName(cs_struct *handle, SStream *OS,
+ unsigned int insn)
+{
+#ifndef CAPSTONE_DIET
+ SStream_concat(OS, handle->insn_name((csh)handle, insn));
+#endif
+}
+
+static uint32_t get_unsigned(int32_t value, int byte_size)
+{
+ switch (byte_size) {
+ case 1:
+ return (uint32_t)(value & 0xff);
+
+ case 2:
+ return (uint32_t)(value & 0xffff);
+
+ default:
+ case 4:
+ return (uint32_t)value;
+ }
+}
+
+static void printIncDec(bool isPost, SStream *O, m680x_info *info,
+ cs_m680x_op *op)
+{
+ static const char s_inc_dec[][3] = { "--", "-", "", "+", "++" };
+
+ if (!op->idx.inc_dec)
+ return;
+
+ if ((!isPost && !(op->idx.flags & M680X_IDX_POST_INC_DEC)) ||
+ (isPost && (op->idx.flags & M680X_IDX_POST_INC_DEC))) {
+ const char *prePostfix = "";
+
+ if (info->cpu_type == M680X_CPU_TYPE_CPU12)
+ prePostfix = (op->idx.inc_dec < 0) ? "-" : "+";
+ else if (op->idx.inc_dec >= -2 && (op->idx.inc_dec <= 2)) {
+ prePostfix = (char *)s_inc_dec[op->idx.inc_dec + 2];
+ }
+
+ SStream_concat(O, prePostfix);
+ }
+}
+
+static void printOperand(MCInst *MI, SStream *O, m680x_info *info,
+ cs_m680x_op *op)
+{
+ switch (op->type) {
+ case M680X_OP_REGISTER:
+ printRegName(MI->csh, O, op->reg);
+ break;
+
+ case M680X_OP_CONSTANT:
+ SStream_concat(O, "%u", op->const_val);
+ break;
+
+ case M680X_OP_IMMEDIATE:
+ if (MI->csh->imm_unsigned)
+ SStream_concat(O, "#%u",
+ get_unsigned(op->imm, op->size));
+ else
+ SStream_concat(O, "#%d", op->imm);
+
+ break;
+
+ case M680X_OP_INDEXED:
+ if (op->idx.flags & M680X_IDX_INDIRECT)
+ SStream_concat(O, "[");
+
+ if (op->idx.offset_reg != M680X_REG_INVALID)
+ printRegName(MI->csh, O, op->idx.offset_reg);
+ else if (op->idx.offset_bits > 0) {
+ if (op->idx.base_reg == M680X_REG_PC)
+ SStream_concat(O, "$%04x", op->idx.offset_addr);
+ else
+ SStream_concat(O, "%d", op->idx.offset);
+ }
+ else if (op->idx.inc_dec != 0 &&
+ info->cpu_type == M680X_CPU_TYPE_CPU12)
+ SStream_concat(O, "%d", abs(op->idx.inc_dec));
+
+ if (!(op->idx.flags & M680X_IDX_NO_COMMA))
+ SStream_concat(O, ", ");
+
+ printIncDec(false, O, info, op);
+
+ printRegName(MI->csh, O, op->idx.base_reg);
+
+ if (op->idx.base_reg == M680X_REG_PC &&
+ (op->idx.offset_bits > 0))
+ SStream_concat(O, "r");
+
+ printIncDec(true, O, info, op);
+
+ if (op->idx.flags & M680X_IDX_INDIRECT)
+ SStream_concat(O, "]");
+
+ break;
+
+ case M680X_OP_RELATIVE:
+ SStream_concat(O, "$%04x", op->rel.address);
+ break;
+
+ case M680X_OP_DIRECT:
+ SStream_concat(O, "$%02x", op->direct_addr);
+ break;
+
+ case M680X_OP_EXTENDED:
+ if (op->ext.indirect)
+ SStream_concat(O, "[$%04x]", op->ext.address);
+ else {
+ if (op->ext.address < 256) {
+ SStream_concat(O, ">$%04x", op->ext.address);
+ }
+ else {
+ SStream_concat(O, "$%04x", op->ext.address);
+ }
+ }
+
+ break;
+
+ default:
+ SStream_concat(O, "<invalid_operand>");
+ break;
+ }
+}
+
+static const char *getDelimiter(m680x_info *info, cs_m680x *m680x)
+{
+ bool indexed = false;
+ int count = 0;
+ int i;
+
+ if (info->insn == M680X_INS_TFM)
+ return ", ";
+
+ if (m680x->op_count > 1) {
+ for (i = 0; i < m680x->op_count; ++i) {
+ if (m680x->operands[i].type == M680X_OP_INDEXED)
+ indexed = true;
+
+ if (m680x->operands[i].type != M680X_OP_REGISTER)
+ count++;
+ }
+ }
+
+ return (indexed && (count >= 1)) ? "; " : ", ";
+};
+
+void M680X_printInst(MCInst *MI, SStream *O, void *PrinterInfo)
+{
+ m680x_info *info = (m680x_info *)PrinterInfo;
+ cs_m680x *m680x = &info->m680x;
+ cs_detail *detail = MI->flat_insn->detail;
+ int suppress_operands = 0;
+ const char *delimiter = getDelimiter(info, m680x);
+ int i;
+
+ if (detail != NULL)
+ memcpy(&detail->m680x, m680x, sizeof(cs_m680x));
+
+ if (info->insn == M680X_INS_INVLD || info->insn == M680X_INS_ILLGL) {
+ if (m680x->op_count)
+ SStream_concat(O, "fcb $%02x", m680x->operands[0].imm);
+ else
+ SStream_concat(O, "fcb $<unknown>");
+
+ return;
+ }
+
+ printInstructionName(MI->csh, O, info->insn);
+ SStream_concat(O, " ");
+
+ if ((m680x->flags & M680X_FIRST_OP_IN_MNEM) != 0)
+ suppress_operands++;
+
+ if ((m680x->flags & M680X_SECOND_OP_IN_MNEM) != 0)
+ suppress_operands++;
+
+ for (i = 0; i < m680x->op_count; ++i) {
+ if (i >= suppress_operands) {
+ printOperand(MI, O, info, &m680x->operands[i]);
+
+ if ((i + 1) != m680x->op_count)
+ SStream_concat(O, delimiter);
+ }
+ }
+}
+
+const char *M680X_reg_name(csh handle, unsigned int reg)
+{
+#ifndef CAPSTONE_DIET
+
+ if (reg >= ARR_SIZE(s_reg_names))
+ return NULL;
+
+ return s_reg_names[(int)reg];
+#else
+ return NULL;
+#endif
+}
+
+const char *M680X_insn_name(csh handle, unsigned int id)
+{
+#ifndef CAPSTONE_DIET
+
+ if (id >= ARR_SIZE(s_instruction_names))
+ return NULL;
+ else
+ return s_instruction_names[(int)id];
+
+#else
+ return NULL;
+#endif
+}
+
+const char *M680X_group_name(csh handle, unsigned int id)
+{
+#ifndef CAPSTONE_DIET
+ return id2name(s_group_names, ARR_SIZE(s_group_names), id);
+#else
+ return NULL;
+#endif
+}
+
+cs_err M680X_instprinter_init(cs_struct *ud)
+{
+#ifndef CAPSTONE_DIET
+
+ if (M680X_REG_ENDING != ARR_SIZE(s_reg_names)) {
+ CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(s_reg_names));
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_INS_ENDING != ARR_SIZE(s_instruction_names)) {
+ CS_ASSERT(M680X_INS_ENDING == ARR_SIZE(s_instruction_names));
+ return CS_ERR_MODE;
+ }
+
+ if (M680X_GRP_ENDING != ARR_SIZE(s_group_names)) {
+ CS_ASSERT(M680X_GRP_ENDING == ARR_SIZE(s_group_names));
+ return CS_ERR_MODE;
+ }
+
+#endif
+
+ return CS_ERR_OK;
+}
+
+#endif
+
diff --git a/capstone/arch/M680X/M680XInstPrinter.h b/capstone/arch/M680X/M680XInstPrinter.h
new file mode 100644
index 000000000..6fa9f8d59
--- /dev/null
+++ b/capstone/arch/M680X/M680XInstPrinter.h
@@ -0,0 +1,25 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+#ifndef CS_M680XINSTPRINTER_H
+#define CS_M680XINSTPRINTER_H
+
+
+#include "capstone/capstone.h"
+#include "../../MCRegisterInfo.h"
+#include "../../MCInst.h"
+
+struct SStream;
+
+void M680X_init(MCRegisterInfo *MRI);
+
+void M680X_printInst(MCInst *MI, struct SStream *O, void *Info);
+const char *M680X_reg_name(csh handle, unsigned int reg);
+const char *M680X_insn_name(csh handle, unsigned int id);
+const char *M680X_group_name(csh handle, unsigned int id);
+void M680X_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm,
+ MCInst *mci);
+
+#endif
+
+
diff --git a/capstone/arch/M680X/M680XModule.c b/capstone/arch/M680X/M680XModule.c
new file mode 100644
index 000000000..3b89463d2
--- /dev/null
+++ b/capstone/arch/M680X/M680XModule.c
@@ -0,0 +1,77 @@
+/* Capstone Disassembly Engine */
+/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
+
+#ifdef CAPSTONE_HAS_M680X
+
+#include "../../utils.h"
+#include "../../MCRegisterInfo.h"
+#include "M680XDisassembler.h"
+#include "M680XDisassemblerInternals.h"
+#include "M680XInstPrinter.h"
+#include "M680XModule.h"
+
+cs_err M680X_global_init(cs_struct *ud)
+{
+ m680x_info *info;
+ cs_err errcode;
+
+ /* Do some validation checks */
+ errcode = M680X_disassembler_init(ud);
+
+ if (errcode != CS_ERR_OK)
+ return errcode;
+
+ errcode = M680X_instprinter_init(ud);
+
+ if (errcode != CS_ERR_OK)
+ return errcode;
+
+ // verify if requested mode is valid
+ if (ud->mode & ~(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 |
+ CS_MODE_M680X_6805 | CS_MODE_M680X_6808 |
+ CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
+ CS_MODE_M680X_6301 | CS_MODE_M680X_6309 |
+ CS_MODE_M680X_CPU12 | CS_MODE_M680X_HCS08)) {
+ // At least one mode is not supported by M680X
+ return CS_ERR_MODE;
+ }
+
+ if (!(ud->mode & (CS_MODE_M680X_6800 | CS_MODE_M680X_6801 |
+ CS_MODE_M680X_6805 | CS_MODE_M680X_6808 |
+ CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
+ CS_MODE_M680X_6301 | CS_MODE_M680X_6309 |
+ CS_MODE_M680X_CPU12 | CS_MODE_M680X_HCS08))) {
+ // At least the cpu type has to be selected. No default.
+ return CS_ERR_MODE;
+ }
+
+ info = cs_mem_malloc(sizeof(m680x_info));
+
+ if (!info)
+ return CS_ERR_MEM;
+
+ ud->printer = M680X_printInst;
+ ud->printer_info = info;
+ ud->getinsn_info = NULL;
+ ud->disasm = M680X_getInstruction;
+ ud->reg_name = M680X_reg_name;
+ ud->insn_id = M680X_get_insn_id;
+ ud->insn_name = M680X_insn_name;
+ ud->group_name = M680X_group_name;
+ ud->skipdata_size = 1;
+ ud->post_printer = NULL;
+#ifndef CAPSTONE_DIET
+ ud->reg_access = M680X_reg_access;
+#endif
+
+ return CS_ERR_OK;
+}
+
+cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value)
+{
+ //TODO
+ return CS_ERR_OK;
+}
+
+#endif
+
diff --git a/capstone/arch/M680X/M680XModule.h b/capstone/arch/M680X/M680XModule.h
new file mode 100644
index 000000000..6672eb289
--- /dev/null
+++ b/capstone/arch/M680X/M680XModule.h
@@ -0,0 +1,12 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_M680X_MODULE_H
+#define CS_M680X_MODULE_H
+
+#include "../../utils.h"
+
+cs_err M680X_global_init(cs_struct *ud);
+cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value);
+
+#endif
diff --git a/capstone/arch/M680X/cpu12.inc b/capstone/arch/M680X/cpu12.inc
new file mode 100644
index 000000000..83f2e89e7
--- /dev/null
+++ b/capstone/arch/M680X/cpu12.inc
@@ -0,0 +1,335 @@
+
+// CPU12 instructions on PAGE1
+static const inst_page1 g_cpu12_inst_page1_table[256] = {
+ // 0x0x
+ { M680X_INS_BGND, inh_hid, inh_hid },
+ { M680X_INS_MEM, inh_hid, inh_hid },
+ { M680X_INS_INY, inh_hid, inh_hid },
+ { M680X_INS_DEY, inh_hid, inh_hid },
+ { M680X_INS_DBEQ, loop_hid, inh_hid }, // or DBNE/IBEQ/IBNE/TBEQ/TBNE
+ { M680X_INS_JMP, idx12_hid, inh_hid },
+ { M680X_INS_JMP, ext_hid, inh_hid },
+ { M680X_INS_BSR, rel8_hid, inh_hid },
+ { M680X_INS_INX, inh_hid, inh_hid },
+ { M680X_INS_DEX, inh_hid, inh_hid },
+ { M680X_INS_RTC, inh_hid, inh_hid },
+ { M680X_INS_RTI, inh_hid, inh_hid },
+ { M680X_INS_BSET, idx12_hid, imm8_hid },
+ { M680X_INS_BCLR, idx12_hid, imm8_hid },
+ { M680X_INS_BRSET, idx12_hid, imm8rel_hid },
+ { M680X_INS_BRCLR, idx12_hid, imm8rel_hid },
+ // 0x1x
+ { M680X_INS_ANDCC, imm8_hid, inh_hid },
+ { M680X_INS_EDIV, inh_hid, inh_hid },
+ { M680X_INS_MUL, inh_hid, inh_hid },
+ { M680X_INS_EMUL, inh_hid, inh_hid },
+ { M680X_INS_ORCC, imm8_hid, inh_hid },
+ { M680X_INS_JSR, idx12_hid, inh_hid },
+ { M680X_INS_JSR, ext_hid, inh_hid },
+ { M680X_INS_JSR, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LEAY, idx12_hid, inh_hid },
+ { M680X_INS_LEAX, idx12_hid, inh_hid },
+ { M680X_INS_LEAS, idx12_hid, inh_hid },
+ { M680X_INS_BSET, ext_hid, imm8_hid },
+ { M680X_INS_BCLR, ext_hid, imm8_hid },
+ { M680X_INS_BRSET, ext_hid, imm8rel_hid },
+ { M680X_INS_BRCLR, ext_hid, imm8rel_hid },
+ // 0x2x, relative branch instructions
+ { M680X_INS_BRA, rel8_hid, inh_hid },
+ { M680X_INS_BRN, rel8_hid, inh_hid },
+ { M680X_INS_BHI, rel8_hid, inh_hid },
+ { M680X_INS_BLS, rel8_hid, inh_hid },
+ { M680X_INS_BCC, rel8_hid, inh_hid },
+ { M680X_INS_BCS, rel8_hid, inh_hid },
+ { M680X_INS_BNE, rel8_hid, inh_hid },
+ { M680X_INS_BEQ, rel8_hid, inh_hid },
+ { M680X_INS_BVC, rel8_hid, inh_hid },
+ { M680X_INS_BVS, rel8_hid, inh_hid },
+ { M680X_INS_BPL, rel8_hid, inh_hid },
+ { M680X_INS_BMI, rel8_hid, inh_hid },
+ { M680X_INS_BGE, rel8_hid, inh_hid },
+ { M680X_INS_BLT, rel8_hid, inh_hid },
+ { M680X_INS_BGT, rel8_hid, inh_hid },
+ { M680X_INS_BLE, rel8_hid, inh_hid },
+ // 0x3x
+ { M680X_INS_PULX, inh_hid, inh_hid },
+ { M680X_INS_PULY, inh_hid, inh_hid },
+ { M680X_INS_PULA, inh_hid, inh_hid },
+ { M680X_INS_PULB, inh_hid, inh_hid },
+ { M680X_INS_PSHX, inh_hid, inh_hid },
+ { M680X_INS_PSHY, inh_hid, inh_hid },
+ { M680X_INS_PSHA, inh_hid, inh_hid },
+ { M680X_INS_PSHB, inh_hid, inh_hid },
+ { M680X_INS_PULC, inh_hid, inh_hid },
+ { M680X_INS_PSHC, inh_hid, inh_hid },
+ { M680X_INS_PULD, inh_hid, inh_hid },
+ { M680X_INS_PSHD, inh_hid, inh_hid },
+ { M680X_INS_WAVR, inh_hid, inh_hid },
+ { M680X_INS_RTS, inh_hid, inh_hid },
+ { M680X_INS_WAI, inh_hid, inh_hid },
+ { M680X_INS_SWI, inh_hid, inh_hid },
+ // 0x4x
+ { M680X_INS_NEGA, inh_hid, inh_hid },
+ { M680X_INS_COMA, inh_hid, inh_hid },
+ { M680X_INS_INCA, inh_hid, inh_hid },
+ { M680X_INS_DECA, inh_hid, inh_hid },
+ { M680X_INS_LSRA, inh_hid, inh_hid },
+ { M680X_INS_ROLA, inh_hid, inh_hid },
+ { M680X_INS_RORA, inh_hid, inh_hid },
+ { M680X_INS_ASRA, inh_hid, inh_hid },
+ { M680X_INS_ASLA, inh_hid, inh_hid },
+ { M680X_INS_LSRD, inh_hid, inh_hid },
+ { M680X_INS_CALL, ext_hid, index_hid },
+ { M680X_INS_CALL, idx12_hid, index_hid },
+ { M680X_INS_BSET, dir_hid, imm8_hid },
+ { M680X_INS_BCLR, dir_hid, imm8_hid },
+ { M680X_INS_BRSET, dir_hid, imm8rel_hid },
+ { M680X_INS_BRCLR, dir_hid, imm8rel_hid },
+ // 0x5x
+ { M680X_INS_NEGB, inh_hid, inh_hid },
+ { M680X_INS_COMB, inh_hid, inh_hid },
+ { M680X_INS_INCB, inh_hid, inh_hid },
+ { M680X_INS_DECB, inh_hid, inh_hid },
+ { M680X_INS_LSRB, inh_hid, inh_hid },
+ { M680X_INS_ROLB, inh_hid, inh_hid },
+ { M680X_INS_RORB, inh_hid, inh_hid },
+ { M680X_INS_ASRB, inh_hid, inh_hid },
+ { M680X_INS_ASLB, inh_hid, inh_hid },
+ { M680X_INS_ASLD, inh_hid, inh_hid },
+ { M680X_INS_STAA, dir_hid, inh_hid },
+ { M680X_INS_STAB, dir_hid, inh_hid },
+ { M680X_INS_STD, dir_hid, inh_hid },
+ { M680X_INS_STY, dir_hid, inh_hid },
+ { M680X_INS_STX, dir_hid, inh_hid },
+ { M680X_INS_STS, dir_hid, inh_hid },
+ // 0x6x
+ { M680X_INS_NEG, idx12_hid, inh_hid },
+ { M680X_INS_COM, idx12_hid, inh_hid },
+ { M680X_INS_INC, idx12_hid, inh_hid },
+ { M680X_INS_DEC, idx12_hid, inh_hid },
+ { M680X_INS_LSR, idx12_hid, inh_hid },
+ { M680X_INS_ROL, idx12_hid, inh_hid },
+ { M680X_INS_ROR, idx12_hid, inh_hid },
+ { M680X_INS_ASR, idx12_hid, inh_hid },
+ { M680X_INS_ASL, idx12_hid, inh_hid },
+ { M680X_INS_CLR, idx12_hid, inh_hid },
+ { M680X_INS_STAA, idx12_hid, inh_hid },
+ { M680X_INS_STAB, idx12_hid, inh_hid },
+ { M680X_INS_STD, idx12_hid, inh_hid },
+ { M680X_INS_STY, idx12_hid, inh_hid },
+ { M680X_INS_STX, idx12_hid, inh_hid },
+ { M680X_INS_STS, idx12_hid, inh_hid },
+ // 0x7x
+ { M680X_INS_NEG, ext_hid, inh_hid },
+ { M680X_INS_COM, ext_hid, inh_hid },
+ { M680X_INS_INC, ext_hid, inh_hid },
+ { M680X_INS_DEC, ext_hid, inh_hid },
+ { M680X_INS_LSR, ext_hid, inh_hid },
+ { M680X_INS_ROL, ext_hid, inh_hid },
+ { M680X_INS_ROR, ext_hid, inh_hid },
+ { M680X_INS_ASR, ext_hid, inh_hid },
+ { M680X_INS_ASL, ext_hid, inh_hid },
+ { M680X_INS_CLR, ext_hid, inh_hid },
+ { M680X_INS_STAA, ext_hid, inh_hid },
+ { M680X_INS_STAB, ext_hid, inh_hid },
+ { M680X_INS_STD, ext_hid, inh_hid },
+ { M680X_INS_STY, ext_hid, inh_hid },
+ { M680X_INS_STX, ext_hid, inh_hid },
+ { M680X_INS_STS, ext_hid, inh_hid },
+ // 0x8x
+ { M680X_INS_SUBA, imm8_hid, inh_hid },
+ { M680X_INS_CMPA, imm8_hid, inh_hid },
+ { M680X_INS_SBCA, imm8_hid, inh_hid },
+ { M680X_INS_SUBD, imm16_hid, inh_hid },
+ { M680X_INS_ANDA, imm8_hid, inh_hid },
+ { M680X_INS_BITA, imm8_hid, inh_hid },
+ { M680X_INS_LDAA, imm8_hid, inh_hid },
+ { M680X_INS_CLRA, inh_hid, inh_hid },
+ { M680X_INS_EORA, imm8_hid, inh_hid },
+ { M680X_INS_ADCA, imm8_hid, inh_hid },
+ { M680X_INS_ORAA, imm8_hid, inh_hid },
+ { M680X_INS_ADDA, imm8_hid, inh_hid },
+ { M680X_INS_CPD, imm16_hid, inh_hid },
+ { M680X_INS_CPY, imm16_hid, inh_hid },
+ { M680X_INS_CPX, imm16_hid, inh_hid },
+ { M680X_INS_CPS, imm16_hid, inh_hid },
+ // 0x9x
+ { M680X_INS_SUBA, dir_hid, inh_hid },
+ { M680X_INS_CMPA, dir_hid, inh_hid },
+ { M680X_INS_SBCA, dir_hid, inh_hid },
+ { M680X_INS_SUBD, dir_hid, inh_hid },
+ { M680X_INS_ANDA, dir_hid, inh_hid },
+ { M680X_INS_BITA, dir_hid, inh_hid },
+ { M680X_INS_LDAA, dir_hid, inh_hid },
+ { M680X_INS_TSTA, inh_hid, inh_hid },
+ { M680X_INS_EORA, dir_hid, inh_hid },
+ { M680X_INS_ADCA, dir_hid, inh_hid },
+ { M680X_INS_ORAA, dir_hid, inh_hid },
+ { M680X_INS_ADDA, dir_hid, inh_hid },
+ { M680X_INS_CPD, dir_hid, inh_hid },
+ { M680X_INS_CPY, dir_hid, inh_hid },
+ { M680X_INS_CPX, dir_hid, inh_hid },
+ { M680X_INS_CPS, dir_hid, inh_hid },
+ // 0xAx
+ { M680X_INS_SUBA, idx12_hid, inh_hid },
+ { M680X_INS_CMPA, idx12_hid, inh_hid },
+ { M680X_INS_SBCA, idx12_hid, inh_hid },
+ { M680X_INS_SUBD, idx12_hid, inh_hid },
+ { M680X_INS_ANDA, idx12_hid, inh_hid },
+ { M680X_INS_BITA, idx12_hid, inh_hid },
+ { M680X_INS_LDAA, idx12_hid, inh_hid },
+ { M680X_INS_NOP, inh_hid, inh_hid },
+ { M680X_INS_EORA, idx12_hid, inh_hid },
+ { M680X_INS_ADCA, idx12_hid, inh_hid },
+ { M680X_INS_ORAA, idx12_hid, inh_hid },
+ { M680X_INS_ADDA, idx12_hid, inh_hid },
+ { M680X_INS_CPD, idx12_hid, inh_hid },
+ { M680X_INS_CPY, idx12_hid, inh_hid },
+ { M680X_INS_CPX, idx12_hid, inh_hid },
+ { M680X_INS_CPS, idx12_hid, inh_hid },
+ // 0xBx
+ { M680X_INS_SUBA, ext_hid, inh_hid },
+ { M680X_INS_CMPA, ext_hid, inh_hid },
+ { M680X_INS_SBCA, ext_hid, inh_hid },
+ { M680X_INS_SUBD, ext_hid, inh_hid },
+ { M680X_INS_ANDA, ext_hid, inh_hid },
+ { M680X_INS_BITA, ext_hid, inh_hid },
+ { M680X_INS_LDAA, ext_hid, inh_hid },
+ { M680X_INS_TFR, rr12_hid, inh_hid }, // or EXG
+ { M680X_INS_EORA, ext_hid, inh_hid },
+ { M680X_INS_ADCA, ext_hid, inh_hid },
+ { M680X_INS_ORAA, ext_hid, inh_hid },
+ { M680X_INS_ADDA, ext_hid, inh_hid },
+ { M680X_INS_CPD, ext_hid, inh_hid },
+ { M680X_INS_CPY, ext_hid, inh_hid },
+ { M680X_INS_CPX, ext_hid, inh_hid },
+ { M680X_INS_CPS, ext_hid, inh_hid },
+ // 0xCx
+ { M680X_INS_SUBB, imm8_hid, inh_hid },
+ { M680X_INS_CMPB, imm8_hid, inh_hid },
+ { M680X_INS_SBCB, imm8_hid, inh_hid },
+ { M680X_INS_ADDD, imm16_hid, inh_hid },
+ { M680X_INS_ANDB, imm8_hid, inh_hid },
+ { M680X_INS_BITB, imm8_hid, inh_hid },
+ { M680X_INS_LDAB, imm8_hid, inh_hid },
+ { M680X_INS_CLRB, inh_hid, inh_hid },
+ { M680X_INS_EORB, imm8_hid, inh_hid },
+ { M680X_INS_ADCB, imm8_hid, inh_hid },
+ { M680X_INS_ORAB, imm8_hid, inh_hid },
+ { M680X_INS_ADDB, imm8_hid, inh_hid },
+ { M680X_INS_LDD, imm16_hid, inh_hid },
+ { M680X_INS_LDY, imm16_hid, inh_hid },
+ { M680X_INS_LDX, imm16_hid, inh_hid },
+ { M680X_INS_LDS, imm16_hid, inh_hid },
+ // 0xDx
+ { M680X_INS_SUBB, dir_hid, inh_hid },
+ { M680X_INS_CMPB, dir_hid, inh_hid },
+ { M680X_INS_SBCB, dir_hid, inh_hid },
+ { M680X_INS_ADDD, dir_hid, inh_hid },
+ { M680X_INS_ANDB, dir_hid, inh_hid },
+ { M680X_INS_BITB, dir_hid, inh_hid },
+ { M680X_INS_LDAB, dir_hid, inh_hid },
+ { M680X_INS_TSTB, inh_hid, inh_hid },
+ { M680X_INS_EORB, dir_hid, inh_hid },
+ { M680X_INS_ADCB, dir_hid, inh_hid },
+ { M680X_INS_ORAB, dir_hid, inh_hid },
+ { M680X_INS_ADDB, dir_hid, inh_hid },
+ { M680X_INS_LDD, dir_hid, inh_hid },
+ { M680X_INS_LDY, dir_hid, inh_hid },
+ { M680X_INS_LDX, dir_hid, inh_hid },
+ { M680X_INS_LDS, dir_hid, inh_hid },
+ // 0xEx
+ { M680X_INS_SUBB, idx12_hid, inh_hid },
+ { M680X_INS_CMPB, idx12_hid, inh_hid },
+ { M680X_INS_SBCB, idx12_hid, inh_hid },
+ { M680X_INS_ADDD, idx12_hid, inh_hid },
+ { M680X_INS_ANDB, idx12_hid, inh_hid },
+ { M680X_INS_BITB, idx12_hid, inh_hid },
+ { M680X_INS_LDAB, idx12_hid, inh_hid },
+ { M680X_INS_TST, idx12_hid, inh_hid },
+ { M680X_INS_EORB, idx12_hid, inh_hid },
+ { M680X_INS_ADCB, idx12_hid, inh_hid },
+ { M680X_INS_ORAB, idx12_hid, inh_hid },
+ { M680X_INS_ADDB, idx12_hid, inh_hid },
+ { M680X_INS_LDD, idx12_hid, inh_hid },
+ { M680X_INS_LDY, idx12_hid, inh_hid },
+ { M680X_INS_LDX, idx12_hid, inh_hid },
+ { M680X_INS_LDS, idx12_hid, inh_hid },
+ // 0xFx
+ { M680X_INS_SUBA, ext_hid, inh_hid },
+ { M680X_INS_CMPA, ext_hid, inh_hid },
+ { M680X_INS_SBCA, ext_hid, inh_hid },
+ { M680X_INS_ADDD, ext_hid, inh_hid },
+ { M680X_INS_ANDA, ext_hid, inh_hid },
+ { M680X_INS_BITA, ext_hid, inh_hid },
+ { M680X_INS_LDAA, ext_hid, inh_hid },
+ { M680X_INS_TST, ext_hid, inh_hid },
+ { M680X_INS_EORA, ext_hid, inh_hid },
+ { M680X_INS_ADCA, ext_hid, inh_hid },
+ { M680X_INS_ORAA, ext_hid, inh_hid },
+ { M680X_INS_ADDA, ext_hid, inh_hid },
+ { M680X_INS_LDD, ext_hid, inh_hid },
+ { M680X_INS_LDY, ext_hid, inh_hid },
+ { M680X_INS_LDX, ext_hid, inh_hid },
+ { M680X_INS_LDS, ext_hid, inh_hid },
+};
+
+// CPU12 instructions on PAGE2
+static const inst_pageX g_cpu12_inst_page2_table[] = {
+ { 0x00, M680X_INS_MOVW, imm16i12x_hid, inh_hid },
+ { 0x01, M680X_INS_MOVW, exti12x_hid, inh_hid },
+ { 0x02, M680X_INS_MOVW, idx12_hid, idx12_hid },
+ { 0x03, M680X_INS_MOVW, imm16_hid, ext_hid },
+ { 0x04, M680X_INS_MOVW, ext_hid, ext_hid },
+ { 0x05, M680X_INS_MOVW, idx12_hid, ext_hid },
+ { 0x06, M680X_INS_ABA, inh_hid, inh_hid },
+ { 0x07, M680X_INS_DAA, inh_hid, inh_hid },
+ { 0x08, M680X_INS_MOVB, imm8i12x_hid, inh_hid },
+ { 0x09, M680X_INS_MOVB, exti12x_hid, inh_hid },
+ { 0x0a, M680X_INS_MOVB, idx12_hid, idx12_hid },
+ { 0x0b, M680X_INS_MOVB, imm8_hid, ext_hid },
+ { 0x0c, M680X_INS_MOVB, ext_hid, ext_hid },
+ { 0x0d, M680X_INS_MOVB, idx12_hid, ext_hid },
+ { 0x0e, M680X_INS_TAB, inh_hid, inh_hid },
+ { 0x0f, M680X_INS_TBA, inh_hid, inh_hid },
+ { 0x10, M680X_INS_IDIV, inh_hid, inh_hid },
+ { 0x11, M680X_INS_FDIV, inh_hid, inh_hid },
+ { 0x12, M680X_INS_EMACS, ext_hid, inh_hid },
+ { 0x13, M680X_INS_EMULS, inh_hid, inh_hid },
+ { 0x14, M680X_INS_EDIVS, inh_hid, inh_hid },
+ { 0x15, M680X_INS_IDIVS, inh_hid, inh_hid },
+ { 0x16, M680X_INS_SBA, inh_hid, inh_hid },
+ { 0x17, M680X_INS_CBA, inh_hid, inh_hid },
+ { 0x18, M680X_INS_MAXA, idx12_hid, inh_hid },
+ { 0x19, M680X_INS_MINA, idx12_hid, inh_hid },
+ { 0x1a, M680X_INS_EMAXD, idx12_hid, inh_hid },
+ { 0x1b, M680X_INS_EMIND, idx12_hid, inh_hid },
+ { 0x1c, M680X_INS_MAXM, idx12_hid, inh_hid },
+ { 0x1d, M680X_INS_MINM, idx12_hid, inh_hid },
+ { 0x1e, M680X_INS_EMAXM, idx12_hid, inh_hid },
+ { 0x1f, M680X_INS_EMINM, idx12_hid, inh_hid },
+ { 0x20, M680X_INS_LBRA, rel16_hid, inh_hid },
+ { 0x21, M680X_INS_LBRN, rel16_hid, inh_hid },
+ { 0x22, M680X_INS_LBHI, rel16_hid, inh_hid },
+ { 0x23, M680X_INS_LBLS, rel16_hid, inh_hid },
+ { 0x24, M680X_INS_LBCC, rel16_hid, inh_hid },
+ { 0x25, M680X_INS_LBCS, rel16_hid, inh_hid },
+ { 0x26, M680X_INS_LBNE, rel16_hid, inh_hid },
+ { 0x27, M680X_INS_LBEQ, rel16_hid, inh_hid },
+ { 0x28, M680X_INS_LBVC, rel16_hid, inh_hid },
+ { 0x29, M680X_INS_LBVS, rel16_hid, inh_hid },
+ { 0x2a, M680X_INS_LBPL, rel16_hid, inh_hid },
+ { 0x2b, M680X_INS_LBMI, rel16_hid, inh_hid },
+ { 0x2c, M680X_INS_LBGE, rel16_hid, inh_hid },
+ { 0x2d, M680X_INS_LBLT, rel16_hid, inh_hid },
+ { 0x2e, M680X_INS_LBGT, rel16_hid, inh_hid },
+ { 0x2f, M680X_INS_LBLE, rel16_hid, inh_hid },
+ { 0x3a, M680X_INS_REV, inh_hid, inh_hid },
+ { 0x3b, M680X_INS_REVW, inh_hid, inh_hid },
+ { 0x3c, M680X_INS_WAV, inh_hid, inh_hid },
+ { 0x3d, M680X_INS_TBL, idx12s_hid, inh_hid },
+ { 0x3e, M680X_INS_STOP, inh_hid, inh_hid },
+ { 0x3f, M680X_INS_ETBL, idx12s_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/hcs08.inc b/capstone/arch/M680X/hcs08.inc
new file mode 100644
index 000000000..60f8af604
--- /dev/null
+++ b/capstone/arch/M680X/hcs08.inc
@@ -0,0 +1,60 @@
+
+// Additional instructions only supported on HCS08
+static const inst_pageX g_hcs08_inst_overlay_table[] = {
+ { 0x32, M680X_INS_LDHX, ext_hid, inh_hid },
+ { 0x3e, M680X_INS_CPHX, ext_hid, inh_hid },
+ { 0x82, M680X_INS_BGND, inh_hid, inh_hid },
+ { 0x96, M680X_INS_STHX, ext_hid, inh_hid },
+};
+
+// HCS08 PAGE2 instructions (prefix 0x9E)
+static const inst_pageX g_hcs08_inst_page2_table[] = {
+ { 0x60, M680X_INS_NEG, idxS_hid, inh_hid },
+ { 0x61, M680X_INS_CBEQ, idxS_hid,rel8_hid },
+ { 0x63, M680X_INS_COM, idxS_hid, inh_hid },
+ { 0x64, M680X_INS_LSR, idxS_hid, inh_hid },
+ { 0x66, M680X_INS_ROR, idxS_hid, inh_hid },
+ { 0x67, M680X_INS_ASR, idxS_hid, inh_hid },
+ { 0x68, M680X_INS_LSL, idxS_hid, inh_hid },
+ { 0x69, M680X_INS_ROL, idxS_hid, inh_hid },
+ { 0x6a, M680X_INS_DEC, idxS_hid, inh_hid },
+ { 0x6b, M680X_INS_DBNZ, idxS_hid,rel8_hid },
+ { 0x6c, M680X_INS_INC, idxS_hid, inh_hid },
+ { 0x6d, M680X_INS_TST, idxS_hid, inh_hid },
+ { 0x6f, M680X_INS_CLR, idxS_hid, inh_hid },
+ { 0xae, M680X_INS_LDHX, idxX0_hid, inh_hid },
+ { 0xbe, M680X_INS_LDHX, idxX16_hid, inh_hid },
+ { 0xce, M680X_INS_LDHX, idxX_hid, inh_hid },
+ { 0xd0, M680X_INS_SUB, idxS16_hid, inh_hid },
+ { 0xd1, M680X_INS_CMP, idxS16_hid, inh_hid },
+ { 0xd2, M680X_INS_SBC, idxS16_hid, inh_hid },
+ { 0xd3, M680X_INS_CPX, idxS16_hid, inh_hid },
+ { 0xd4, M680X_INS_AND, idxS16_hid, inh_hid },
+ { 0xd5, M680X_INS_BIT, idxS16_hid, inh_hid },
+ { 0xd6, M680X_INS_LDA, idxS16_hid, inh_hid },
+ { 0xd7, M680X_INS_STA, idxS16_hid, inh_hid },
+ { 0xd8, M680X_INS_EOR, idxS16_hid, inh_hid },
+ { 0xd9, M680X_INS_ADC, idxS16_hid, inh_hid },
+ { 0xda, M680X_INS_ORA, idxS16_hid, inh_hid },
+ { 0xdb, M680X_INS_ADD, idxS16_hid, inh_hid },
+ { 0xde, M680X_INS_LDX, idxS16_hid, inh_hid },
+ { 0xdf, M680X_INS_STX, idxS16_hid, inh_hid },
+ { 0xe0, M680X_INS_SUB, idxS_hid, inh_hid },
+ { 0xe1, M680X_INS_CMP, idxS_hid, inh_hid },
+ { 0xe2, M680X_INS_SBC, idxS_hid, inh_hid },
+ { 0xe3, M680X_INS_CPX, idxS_hid, inh_hid },
+ { 0xe4, M680X_INS_AND, idxS_hid, inh_hid },
+ { 0xe5, M680X_INS_BIT, idxS_hid, inh_hid },
+ { 0xe6, M680X_INS_LDA, idxS_hid, inh_hid },
+ { 0xe7, M680X_INS_STA, idxS_hid, inh_hid },
+ { 0xe8, M680X_INS_EOR, idxS_hid, inh_hid },
+ { 0xe9, M680X_INS_ADC, idxS_hid, inh_hid },
+ { 0xea, M680X_INS_ORA, idxS_hid, inh_hid },
+ { 0xeb, M680X_INS_ADD, idxS_hid, inh_hid },
+ { 0xee, M680X_INS_LDX, idxS_hid, inh_hid },
+ { 0xef, M680X_INS_STX, idxS_hid, inh_hid },
+ { 0xf3, M680X_INS_CPHX, idxS_hid, inh_hid },
+ { 0xfe, M680X_INS_LDHX, idxS_hid, inh_hid },
+ { 0xff, M680X_INS_STHX, idxS_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/hd6301.inc b/capstone/arch/M680X/hd6301.inc
new file mode 100644
index 000000000..63493ab04
--- /dev/null
+++ b/capstone/arch/M680X/hd6301.inc
@@ -0,0 +1,15 @@
+
+// Additional instructions only supported on HD6301/3
+static const inst_pageX g_hd6301_inst_overlay_table[] = {
+ { 0x18, M680X_INS_XGDX, inh_hid, inh_hid },
+ { 0x1a, M680X_INS_SLP, inh_hid, inh_hid },
+ { 0x61, M680X_INS_AIM, imm8_hid, idxX_hid },
+ { 0x62, M680X_INS_OIM, imm8_hid, idxX_hid },
+ { 0x65, M680X_INS_EIM, imm8_hid, idxX_hid },
+ { 0x6B, M680X_INS_TIM, imm8_hid, idxX_hid },
+ { 0x71, M680X_INS_AIM, imm8_hid, dir_hid },
+ { 0x72, M680X_INS_OIM, imm8_hid, dir_hid },
+ { 0x75, M680X_INS_EIM, imm8_hid, dir_hid },
+ { 0x7B, M680X_INS_TIM, imm8_hid, dir_hid },
+};
+
diff --git a/capstone/arch/M680X/hd6309.inc b/capstone/arch/M680X/hd6309.inc
new file mode 100644
index 000000000..69c0dec50
--- /dev/null
+++ b/capstone/arch/M680X/hd6309.inc
@@ -0,0 +1,259 @@
+
+// The following array has to be sorted by increasing
+// opcodes. Otherwise the binary_search will fail.
+//
+// Additional instructions only supported on HD6309 PAGE1
+static const inst_pageX g_hd6309_inst_overlay_table[] = {
+ { 0x01, M680X_INS_OIM, imm8_hid, dir_hid },
+ { 0x02, M680X_INS_AIM, imm8_hid, dir_hid },
+ { 0x05, M680X_INS_EIM, imm8_hid, dir_hid },
+ { 0x0B, M680X_INS_TIM, imm8_hid, dir_hid },
+ { 0x14, M680X_INS_SEXW, inh_hid, inh_hid },
+ { 0x61, M680X_INS_OIM, imm8_hid, idx09_hid },
+ { 0x62, M680X_INS_AIM, imm8_hid, idx09_hid },
+ { 0x65, M680X_INS_EIM, imm8_hid, idx09_hid },
+ { 0x6B, M680X_INS_TIM, imm8_hid, idx09_hid },
+ { 0x71, M680X_INS_OIM, imm8_hid, ext_hid },
+ { 0x72, M680X_INS_AIM, imm8_hid, ext_hid },
+ { 0x75, M680X_INS_EIM, imm8_hid, ext_hid },
+ { 0x7B, M680X_INS_TIM, imm8_hid, ext_hid },
+ { 0xCD, M680X_INS_LDQ, imm32_hid, inh_hid },
+};
+
+// The following array has to be sorted by increasing
+// opcodes. Otherwise the binary_search will fail.
+//
+// HD6309 PAGE2 instructions (with prefix 0x10)
+static const inst_pageX g_hd6309_inst_page2_table[] = {
+ // 0x2x, relative long branch instructions
+ { 0x21, M680X_INS_LBRN, rel16_hid, inh_hid },
+ { 0x22, M680X_INS_LBHI, rel16_hid, inh_hid },
+ { 0x23, M680X_INS_LBLS, rel16_hid, inh_hid },
+ { 0x24, M680X_INS_LBCC, rel16_hid, inh_hid },
+ { 0x25, M680X_INS_LBCS, rel16_hid, inh_hid },
+ { 0x26, M680X_INS_LBNE, rel16_hid, inh_hid },
+ { 0x27, M680X_INS_LBEQ, rel16_hid, inh_hid },
+ { 0x28, M680X_INS_LBVC, rel16_hid, inh_hid },
+ { 0x29, M680X_INS_LBVS, rel16_hid, inh_hid },
+ { 0x2a, M680X_INS_LBPL, rel16_hid, inh_hid },
+ { 0x2b, M680X_INS_LBMI, rel16_hid, inh_hid },
+ { 0x2c, M680X_INS_LBGE, rel16_hid, inh_hid },
+ { 0x2d, M680X_INS_LBLT, rel16_hid, inh_hid },
+ { 0x2e, M680X_INS_LBGT, rel16_hid, inh_hid },
+ { 0x2f, M680X_INS_LBLE, rel16_hid, inh_hid },
+ // 0x3x
+ { 0x30, M680X_INS_ADDR, rr09_hid, inh_hid },
+ { 0x31, M680X_INS_ADCR, rr09_hid, inh_hid },
+ { 0x32, M680X_INS_SUBR, rr09_hid, inh_hid },
+ { 0x33, M680X_INS_SBCR, rr09_hid, inh_hid },
+ { 0x34, M680X_INS_ANDR, rr09_hid, inh_hid },
+ { 0x35, M680X_INS_ORR, rr09_hid, inh_hid },
+ { 0x36, M680X_INS_EORR, rr09_hid, inh_hid },
+ { 0x37, M680X_INS_CMPR, rr09_hid, inh_hid },
+ { 0x38, M680X_INS_PSHSW, inh_hid, inh_hid },
+ { 0x39, M680X_INS_PULSW, inh_hid, inh_hid },
+ { 0x3a, M680X_INS_PSHUW, inh_hid, inh_hid },
+ { 0x3b, M680X_INS_PULUW, inh_hid, inh_hid },
+ { 0x3f, M680X_INS_SWI2, inh_hid, inh_hid },
+ // 0x4x, Register D instructions
+ { 0x40, M680X_INS_NEGD, inh_hid, inh_hid },
+ { 0x43, M680X_INS_COMD, inh_hid, inh_hid },
+ { 0x44, M680X_INS_LSRD, inh_hid, inh_hid },
+ { 0x46, M680X_INS_RORD, inh_hid, inh_hid },
+ { 0x47, M680X_INS_ASRD, inh_hid, inh_hid },
+ { 0x48, M680X_INS_LSLD, inh_hid, inh_hid },
+ { 0x49, M680X_INS_ROLD, inh_hid, inh_hid },
+ { 0x4a, M680X_INS_DECD, inh_hid, inh_hid },
+ { 0x4c, M680X_INS_INCD, inh_hid, inh_hid },
+ { 0x4d, M680X_INS_TSTD, inh_hid, inh_hid },
+ { 0x4f, M680X_INS_CLRD, inh_hid, inh_hid },
+ // 0x5x, Register W instructions
+ { 0x53, M680X_INS_COMW, inh_hid, inh_hid },
+ { 0x54, M680X_INS_LSRW, inh_hid, inh_hid },
+ { 0x56, M680X_INS_RORW, inh_hid, inh_hid },
+ { 0x59, M680X_INS_ROLW, inh_hid, inh_hid },
+ { 0x5a, M680X_INS_DECW, inh_hid, inh_hid },
+ { 0x5c, M680X_INS_INCW, inh_hid, inh_hid },
+ { 0x5d, M680X_INS_TSTW, inh_hid, inh_hid },
+ { 0x5f, M680X_INS_CLRW, inh_hid, inh_hid },
+ // 0x8x, immediate instructionY with register D,W,Y
+ { 0x80, M680X_INS_SUBW, imm16_hid, inh_hid },
+ { 0x81, M680X_INS_CMPW, imm16_hid, inh_hid },
+ { 0x82, M680X_INS_SBCD, imm16_hid, inh_hid },
+ { 0x83, M680X_INS_CMPD, imm16_hid, inh_hid },
+ { 0x84, M680X_INS_ANDD, imm16_hid, inh_hid },
+ { 0x85, M680X_INS_BITD, imm16_hid, inh_hid },
+ { 0x86, M680X_INS_LDW, imm16_hid, inh_hid },
+ { 0x88, M680X_INS_EORD, imm16_hid, inh_hid },
+ { 0x89, M680X_INS_ADCD, imm16_hid, inh_hid },
+ { 0x8a, M680X_INS_ORD, imm16_hid, inh_hid },
+ { 0x8b, M680X_INS_ADDW, imm16_hid, inh_hid },
+ { 0x8c, M680X_INS_CMPY, imm16_hid, inh_hid },
+ { 0x8e, M680X_INS_LDY, imm16_hid, inh_hid },
+ // 0x9x, direct instructions with register D,W,Y
+ { 0x90, M680X_INS_SUBW, dir_hid, inh_hid },
+ { 0x91, M680X_INS_CMPW, dir_hid, inh_hid },
+ { 0x92, M680X_INS_SBCD, dir_hid, inh_hid },
+ { 0x93, M680X_INS_CMPD, dir_hid, inh_hid },
+ { 0x94, M680X_INS_ANDD, dir_hid, inh_hid },
+ { 0x95, M680X_INS_BITD, dir_hid, inh_hid },
+ { 0x96, M680X_INS_LDW, dir_hid, inh_hid },
+ { 0x97, M680X_INS_STW, dir_hid, inh_hid },
+ { 0x98, M680X_INS_EORD, dir_hid, inh_hid },
+ { 0x99, M680X_INS_ADCD, dir_hid, inh_hid },
+ { 0x9a, M680X_INS_ORD, dir_hid, inh_hid },
+ { 0x9b, M680X_INS_ADDW, dir_hid, inh_hid },
+ { 0x9c, M680X_INS_CMPY, dir_hid, inh_hid },
+ { 0x9e, M680X_INS_LDY, dir_hid, inh_hid },
+ { 0x9f, M680X_INS_STY, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with register D,W,Y
+ { 0xa0, M680X_INS_SUBW, idx09_hid, inh_hid },
+ { 0xa1, M680X_INS_CMPW, idx09_hid, inh_hid },
+ { 0xa2, M680X_INS_SBCD, idx09_hid, inh_hid },
+ { 0xa3, M680X_INS_CMPD, idx09_hid, inh_hid },
+ { 0xa4, M680X_INS_ANDD, idx09_hid, inh_hid },
+ { 0xa5, M680X_INS_BITD, idx09_hid, inh_hid },
+ { 0xa6, M680X_INS_LDW, idx09_hid, inh_hid },
+ { 0xa7, M680X_INS_STW, idx09_hid, inh_hid },
+ { 0xa8, M680X_INS_EORD, idx09_hid, inh_hid },
+ { 0xa9, M680X_INS_ADCD, idx09_hid, inh_hid },
+ { 0xaa, M680X_INS_ORD, idx09_hid, inh_hid },
+ { 0xab, M680X_INS_ADDW, idx09_hid, inh_hid },
+ { 0xac, M680X_INS_CMPY, idx09_hid, inh_hid },
+ { 0xae, M680X_INS_LDY, idx09_hid, inh_hid },
+ { 0xaf, M680X_INS_STY, idx09_hid, inh_hid },
+ // 0xBx, extended instructions with register D,W,Y
+ { 0xb0, M680X_INS_SUBW, ext_hid, inh_hid },
+ { 0xb1, M680X_INS_CMPW, ext_hid, inh_hid },
+ { 0xb2, M680X_INS_SBCD, ext_hid, inh_hid },
+ { 0xb3, M680X_INS_CMPD, ext_hid, inh_hid },
+ { 0xb4, M680X_INS_ANDD, ext_hid, inh_hid },
+ { 0xb5, M680X_INS_BITD, ext_hid, inh_hid },
+ { 0xb6, M680X_INS_LDW, ext_hid, inh_hid },
+ { 0xb7, M680X_INS_STW, ext_hid, inh_hid },
+ { 0xb8, M680X_INS_EORD, ext_hid, inh_hid },
+ { 0xb9, M680X_INS_ADCD, ext_hid, inh_hid },
+ { 0xba, M680X_INS_ORD, ext_hid, inh_hid },
+ { 0xbb, M680X_INS_ADDW, ext_hid, inh_hid },
+ { 0xbc, M680X_INS_CMPY, ext_hid, inh_hid },
+ { 0xbe, M680X_INS_LDY, ext_hid, inh_hid },
+ { 0xbf, M680X_INS_STY, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register S
+ { 0xce, M680X_INS_LDS, imm16_hid, inh_hid },
+ // 0xDx, direct instructions with register S,Q
+ { 0xdc, M680X_INS_LDQ, dir_hid, inh_hid },
+ { 0xdd, M680X_INS_STQ, dir_hid, inh_hid },
+ { 0xde, M680X_INS_LDS, dir_hid, inh_hid },
+ { 0xdf, M680X_INS_STS, dir_hid, inh_hid },
+ // 0xEx, indexed instructions with register S,Q
+ { 0xec, M680X_INS_LDQ, idx09_hid, inh_hid },
+ { 0xed, M680X_INS_STQ, idx09_hid, inh_hid },
+ { 0xee, M680X_INS_LDS, idx09_hid, inh_hid },
+ { 0xef, M680X_INS_STS, idx09_hid, inh_hid },
+ // 0xFx, extended instructions with register S,Q
+ { 0xfc, M680X_INS_LDQ, ext_hid, inh_hid },
+ { 0xfd, M680X_INS_STQ, ext_hid, inh_hid },
+ { 0xfe, M680X_INS_LDS, ext_hid, inh_hid },
+ { 0xff, M680X_INS_STS, ext_hid, inh_hid },
+};
+
+// The following array has to be sorted by increasing
+// opcodes. Otherwise the binary_search will fail.
+//
+// HD6309 PAGE3 instructions (with prefix 0x11)
+static const inst_pageX g_hd6309_inst_page3_table[] = {
+ { 0x30, M680X_INS_BAND, bitmv_hid, inh_hid },
+ { 0x31, M680X_INS_BIAND, bitmv_hid, inh_hid },
+ { 0x32, M680X_INS_BOR, bitmv_hid, inh_hid },
+ { 0x33, M680X_INS_BIOR, bitmv_hid, inh_hid },
+ { 0x34, M680X_INS_BEOR, bitmv_hid, inh_hid },
+ { 0x35, M680X_INS_BIEOR, bitmv_hid, inh_hid },
+ { 0x36, M680X_INS_LDBT, bitmv_hid, inh_hid },
+ { 0x37, M680X_INS_STBT, bitmv_hid, inh_hid },
+ { 0x38, M680X_INS_TFM, tfm_hid, inh_hid },
+ { 0x39, M680X_INS_TFM, tfm_hid, inh_hid },
+ { 0x3a, M680X_INS_TFM, tfm_hid, inh_hid },
+ { 0x3b, M680X_INS_TFM, tfm_hid, inh_hid },
+ { 0x3c, M680X_INS_BITMD, imm8_hid, inh_hid },
+ { 0x3d, M680X_INS_LDMD, imm8_hid, inh_hid },
+ { 0x3f, M680X_INS_SWI3, inh_hid, inh_hid },
+ // 0x4x, Register E instructions
+ { 0x43, M680X_INS_COME, inh_hid, inh_hid },
+ { 0x4a, M680X_INS_DECE, inh_hid, inh_hid },
+ { 0x4c, M680X_INS_INCE, inh_hid, inh_hid },
+ { 0x4d, M680X_INS_TSTE, inh_hid, inh_hid },
+ { 0x4f, M680X_INS_CLRE, inh_hid, inh_hid },
+ // 0x5x, Register F instructions
+ { 0x53, M680X_INS_COMF, inh_hid, inh_hid },
+ { 0x5a, M680X_INS_DECF, inh_hid, inh_hid },
+ { 0x5c, M680X_INS_INCF, inh_hid, inh_hid },
+ { 0x5d, M680X_INS_TSTF, inh_hid, inh_hid },
+ { 0x5f, M680X_INS_CLRF, inh_hid, inh_hid },
+ // 0x8x, immediate instructions with register U,S,E
+ { 0x80, M680X_INS_SUBE, imm8_hid, inh_hid },
+ { 0x81, M680X_INS_CMPE, imm8_hid, inh_hid },
+ { 0x83, M680X_INS_CMPU, imm16_hid, inh_hid },
+ { 0x86, M680X_INS_LDE, imm8_hid, inh_hid },
+ { 0x8b, M680X_INS_ADDE, imm8_hid, inh_hid },
+ { 0x8c, M680X_INS_CMPS, imm16_hid, inh_hid },
+ { 0x8d, M680X_INS_DIVD, imm8_hid, inh_hid },
+ { 0x8e, M680X_INS_DIVQ, imm16_hid, inh_hid },
+ { 0x8f, M680X_INS_MULD, imm16_hid, inh_hid },
+ // 0x9x, direct instructions with register U,S,E,Q
+ { 0x90, M680X_INS_SUBE, dir_hid, inh_hid },
+ { 0x91, M680X_INS_CMPE, dir_hid, inh_hid },
+ { 0x93, M680X_INS_CMPU, dir_hid, inh_hid },
+ { 0x96, M680X_INS_LDE, dir_hid, inh_hid },
+ { 0x97, M680X_INS_STE, dir_hid, inh_hid },
+ { 0x9b, M680X_INS_ADDE, dir_hid, inh_hid },
+ { 0x9c, M680X_INS_CMPS, dir_hid, inh_hid },
+ { 0x9d, M680X_INS_DIVD, dir_hid, inh_hid },
+ { 0x9e, M680X_INS_DIVQ, dir_hid, inh_hid },
+ { 0x9f, M680X_INS_MULD, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with register U,S,D,Q
+ { 0xa0, M680X_INS_SUBE, idx09_hid, inh_hid },
+ { 0xa1, M680X_INS_CMPE, idx09_hid, inh_hid },
+ { 0xa3, M680X_INS_CMPU, idx09_hid, inh_hid },
+ { 0xa6, M680X_INS_LDE, idx09_hid, inh_hid },
+ { 0xa7, M680X_INS_STE, idx09_hid, inh_hid },
+ { 0xab, M680X_INS_ADDE, idx09_hid, inh_hid },
+ { 0xac, M680X_INS_CMPS, idx09_hid, inh_hid },
+ { 0xad, M680X_INS_DIVD, idx09_hid, inh_hid },
+ { 0xae, M680X_INS_DIVQ, idx09_hid, inh_hid },
+ { 0xaf, M680X_INS_MULD, idx09_hid, inh_hid },
+ // 0xBx, extended instructions with register U,S,D,Q
+ { 0xb0, M680X_INS_SUBE, ext_hid, inh_hid },
+ { 0xb1, M680X_INS_CMPE, ext_hid, inh_hid },
+ { 0xb3, M680X_INS_CMPU, ext_hid, inh_hid },
+ { 0xb6, M680X_INS_LDE, ext_hid, inh_hid },
+ { 0xb7, M680X_INS_STE, ext_hid, inh_hid },
+ { 0xbb, M680X_INS_ADDE, ext_hid, inh_hid },
+ { 0xbc, M680X_INS_CMPS, ext_hid, inh_hid },
+ { 0xbd, M680X_INS_DIVD, ext_hid, inh_hid },
+ { 0xbe, M680X_INS_DIVQ, ext_hid, inh_hid },
+ { 0xbf, M680X_INS_MULD, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register F
+ { 0xc0, M680X_INS_SUBF, imm8_hid, inh_hid },
+ { 0xc1, M680X_INS_CMPF, imm8_hid, inh_hid },
+ { 0xc6, M680X_INS_LDF, imm8_hid, inh_hid },
+ { 0xcb, M680X_INS_ADDF, imm8_hid, inh_hid },
+ // 0xDx, direct instructions with register F
+ { 0xd0, M680X_INS_SUBF, dir_hid, inh_hid },
+ { 0xd1, M680X_INS_CMPF, dir_hid, inh_hid },
+ { 0xd6, M680X_INS_LDF, dir_hid, inh_hid },
+ { 0xd7, M680X_INS_STF, dir_hid, inh_hid },
+ { 0xdb, M680X_INS_ADDF, dir_hid, inh_hid },
+ // 0xEx, indexed instructions with register F
+ { 0xe0, M680X_INS_SUBF, idx09_hid, inh_hid },
+ { 0xe1, M680X_INS_CMPF, idx09_hid, inh_hid },
+ { 0xe6, M680X_INS_LDF, idx09_hid, inh_hid },
+ { 0xe7, M680X_INS_STF, idx09_hid, inh_hid },
+ { 0xeb, M680X_INS_ADDF, idx09_hid, inh_hid },
+ // 0xFx, extended instructions with register F
+ { 0xf0, M680X_INS_SUBF, ext_hid, inh_hid },
+ { 0xf1, M680X_INS_CMPF, ext_hid, inh_hid },
+ { 0xf6, M680X_INS_LDF, ext_hid, inh_hid },
+ { 0xf7, M680X_INS_STF, ext_hid, inh_hid },
+ { 0xfb, M680X_INS_ADDF, ext_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/insn_props.inc b/capstone/arch/M680X/insn_props.inc
new file mode 100644
index 000000000..813bffbca
--- /dev/null
+++ b/capstone/arch/M680X/insn_props.inc
@@ -0,0 +1,367 @@
+
+// These temporary defines keep the following table short and handy.
+#define NOG M680X_GRP_INVALID
+#define NOR M680X_REG_INVALID
+
+static const insn_props g_insn_props[] = {
+ { NOG, uuuu, NOR, NOR, false, false }, // INVLD
+ { NOG, rmmm, M680X_REG_B, M680X_REG_A, true, false }, // ABA
+ { NOG, rmmm, M680X_REG_B, M680X_REG_X, false, false }, // ABX
+ { NOG, rmmm, M680X_REG_B, M680X_REG_Y, false, false }, // ABY
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ADC
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ADCA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ADCB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ADCD
+ { NOG, rmmm, NOR, NOR, true, false }, // ADCR
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ADD
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ADDA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ADDB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ADDD
+ { NOG, mrrr, M680X_REG_E, NOR, true, false }, // ADDE
+ { NOG, mrrr, M680X_REG_F, NOR, true, false }, // ADDF
+ { NOG, rmmm, NOR, NOR, true, false }, // ADDR
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // ADDW
+ { NOG, rmmm, NOR, NOR, true, false }, // AIM
+ { NOG, mrrr, M680X_REG_S, NOR, false, false }, // AIS
+ { NOG, mrrr, M680X_REG_HX, NOR, false, false }, // AIX
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // AND
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ANDA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ANDB
+ { NOG, mrrr, M680X_REG_CC, NOR, true, false }, // ANDCC
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ANDD
+ { NOG, rmmm, NOR, NOR, true, false }, // ANDR
+ { NOG, mrrr, NOR, NOR, true, false }, // ASL
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ASLA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ASLB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ASLD
+ { NOG, mrrr, NOR, NOR, true, false }, // ASR
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ASRA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ASRB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ASRD
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // ASRX
+ { NOG, mrrr, NOR, NOR, false, false }, // BAND
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BCC
+ { NOG, mrrr, NOR, NOR, true, false }, // BCLR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BCS
+ { NOG, mrrr, NOR, NOR, false, false }, // BEOR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BEQ
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BGE
+ { NOG, uuuu, NOR, NOR, false, false }, // BGND
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BGT
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BHCC
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BHCS
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BHI
+ { NOG, mrrr, NOR, NOR, false, false }, // BIAND
+ { NOG, mrrr, NOR, NOR, false, false }, // BIEOR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BIH
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BIL
+ { NOG, mrrr, NOR, NOR, false, false }, // BIOR
+ { NOG, rrrr, M680X_REG_A, NOR, true, false }, // BIT
+ { NOG, rrrr, M680X_REG_A, NOR, true, false }, // BITA
+ { NOG, rrrr, M680X_REG_B, NOR, true, false }, // BITB
+ { NOG, rrrr, M680X_REG_D, NOR, true, false }, // BITD
+ { NOG, rrrr, M680X_REG_MD, NOR, true, false }, // BITMD
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BLE
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BLS
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BLT
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BMC
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BMI
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BMS
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BNE
+ { NOG, mrrr, NOR, NOR, false, false }, // BOR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BPL
+ { M680X_GRP_JUMP, rruu, NOR, NOR, false, false }, // BRCLR
+ { M680X_GRP_JUMP, rruu, NOR, NOR, false, false }, // BRSET
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BRA
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BRN never branches
+ { NOG, mrrr, NOR, NOR, true, false }, // BSET
+ { M680X_GRP_CALL, uuuu, NOR, NOR, false, true }, // BSR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BVC
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // BVS
+ { M680X_GRP_CALL, uuuu, NOR, NOR, false, true }, // CALL
+ { NOG, rrrr, M680X_REG_B, M680X_REG_A, true, false }, // CBA
+ { M680X_GRP_JUMP, rruu, M680X_REG_A, NOR, false, false }, // CBEQ
+ { M680X_GRP_JUMP, rruu, M680X_REG_A, NOR, false, false }, // CBEQA
+ { M680X_GRP_JUMP, rruu, M680X_REG_X, NOR, false, false }, // CBEQX
+ { NOG, uuuu, NOR, NOR, true, false }, // CLC
+ { NOG, uuuu, NOR, NOR, true, false }, // CLI
+ { NOG, wrrr, NOR, NOR, true, false }, // CLR
+ { NOG, wrrr, M680X_REG_A, NOR, true, false }, // CLRA
+ { NOG, wrrr, M680X_REG_B, NOR, true, false }, // CLRB
+ { NOG, wrrr, M680X_REG_D, NOR, true, false }, // CLRD
+ { NOG, wrrr, M680X_REG_E, NOR, true, false }, // CLRE
+ { NOG, wrrr, M680X_REG_F, NOR, true, false }, // CLRF
+ { NOG, wrrr, M680X_REG_H, NOR, true, false }, // CLRH
+ { NOG, wrrr, M680X_REG_W, NOR, true, false }, // CLRW
+ { NOG, wrrr, M680X_REG_X, NOR, true, false }, // CLRX
+ { NOG, uuuu, NOR, NOR, true, false }, // CLV
+ { NOG, rrrr, M680X_REG_A, NOR, true, false }, // CMP
+ { NOG, rrrr, M680X_REG_A, NOR, true, false }, // CMPA
+ { NOG, rrrr, M680X_REG_B, NOR, true, false }, // CMPB
+ { NOG, rrrr, M680X_REG_D, NOR, true, false }, // CMPD
+ { NOG, rrrr, M680X_REG_E, NOR, true, false }, // CMPE
+ { NOG, rrrr, M680X_REG_F, NOR, true, false }, // CMPF
+ { NOG, rrrr, NOR, NOR, true, false }, // CMPR
+ { NOG, rrrr, M680X_REG_S, NOR, true, false }, // CMPS
+ { NOG, rrrr, M680X_REG_U, NOR, true, false }, // CMPU
+ { NOG, rrrr, M680X_REG_W, NOR, true, false }, // CMPW
+ { NOG, rrrr, M680X_REG_X, NOR, true, false }, // CMPX
+ { NOG, rrrr, M680X_REG_Y, NOR, true, false }, // CMPY
+ { NOG, mrrr, NOR, NOR, true, false }, // COM
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // COMA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // COMB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // COMD
+ { NOG, mrrr, M680X_REG_E, NOR, true, false }, // COME
+ { NOG, mrrr, M680X_REG_F, NOR, true, false }, // COMF
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // COMW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // COMX
+ { NOG, rrrr, M680X_REG_D, NOR, true, false }, // CPD
+ { NOG, rrrr, M680X_REG_HX, NOR, true, false }, // CPHX
+ { NOG, rrrr, M680X_REG_S, NOR, true, false }, // CPS
+ { NOG, rrrr, M680X_REG_X, NOR, true, false }, // CPX
+ { NOG, rrrr, M680X_REG_Y, NOR, true, false }, // CPY
+ { NOG, mrrr, NOR, NOR, true, true }, // CWAI
+ { NOG, mrrr, NOR, NOR, true, true }, // DAA
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // DBEQ
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // DBNE
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // DBNZ
+ { M680X_GRP_JUMP, muuu, M680X_REG_A, NOR, false, false }, // DBNZA
+ { M680X_GRP_JUMP, muuu, M680X_REG_X, NOR, false, false }, // DBNZX
+ { NOG, mrrr, NOR, NOR, true, false }, // DEC
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // DECA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // DECB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // DECD
+ { NOG, mrrr, M680X_REG_E, NOR, true, false }, // DECE
+ { NOG, mrrr, M680X_REG_F, NOR, true, false }, // DECF
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // DECW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // DECX
+ { NOG, mrrr, M680X_REG_S, NOR, false, false }, // DES
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // DEX
+ { NOG, mrrr, M680X_REG_Y, NOR, true, false }, // DEY
+ { NOG, mmrr, NOR, NOR, true, true }, // DIV
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // DIVD
+ { NOG, mrrr, M680X_REG_Q, NOR, true, false }, // DIVQ
+ { NOG, mmrr, NOR, NOR, true, true }, // EDIV
+ { NOG, mmrr, NOR, NOR, true, true }, // EDIVS
+ { NOG, rmmm, NOR, NOR, true, false }, // EIM
+ { NOG, mrrr, NOR, NOR, true, true }, // EMACS
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // EMAXD
+ { NOG, mrrr, NOR, NOR, true, true }, // EMAXM
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // EMIND
+ { NOG, mrrr, NOR, NOR, true, true }, // EMINM
+ { NOG, mmrr, NOR, NOR, true, true }, // EMUL
+ { NOG, mmrr, NOR, NOR, true, true }, // EMULS
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // EOR
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // EORA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // EORB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // EORD
+ { NOG, rmmm, NOR, NOR, true, false }, // EORR
+ { NOG, rmmm, NOR, NOR, true, true }, // ETBL
+ { NOG, mmmm, NOR, NOR, false, false }, // EXG
+ { NOG, mmmm, NOR, NOR, true, true }, // FDIV
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // IBEQ
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // IBNE
+ { NOG, mmmm, NOR, NOR, true, true }, // IDIV
+ { NOG, mmmm, NOR, NOR, true, true }, // IDIVS
+ { NOG, uuuu, NOR, NOR, false, false }, // ILLGL
+ { NOG, mrrr, NOR, NOR, true, false }, // INC
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // INCA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // INCB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // INCD
+ { NOG, mrrr, M680X_REG_E, NOR, true, false }, // INCE
+ { NOG, mrrr, M680X_REG_F, NOR, true, false }, // INCF
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // INCW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // INCX
+ { NOG, mrrr, M680X_REG_S, NOR, false, false }, // INS
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // INX
+ { NOG, mrrr, M680X_REG_Y, NOR, true, false }, // INY
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // JMP
+ { M680X_GRP_CALL, uuuu, NOR, NOR, false, true }, // JSR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBCC
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBCS
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBEQ
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBGE
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBGT
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBHI
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBLE
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBLS
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBLT
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBMI
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBNE
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBPL
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBRA
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBRN never branches
+ { M680X_GRP_CALL, uuuu, NOR, NOR, false, true }, // LBSR
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBVC
+ { M680X_GRP_JUMP, uuuu, NOR, NOR, false, false }, // LBVS
+ { NOG, wrrr, M680X_REG_A, NOR, true, false }, // LDA
+ { NOG, wrrr, M680X_REG_A, NOR, true, false }, // LDAA
+ { NOG, wrrr, M680X_REG_B, NOR, true, false }, // LDAB
+ { NOG, wrrr, M680X_REG_B, NOR, true, false }, // LDB
+ { NOG, mrrr, NOR, NOR, false, false }, // LDBT
+ { NOG, wrrr, M680X_REG_D, NOR, true, false }, // LDD
+ { NOG, wrrr, M680X_REG_E, NOR, true, false }, // LDE
+ { NOG, wrrr, M680X_REG_F, NOR, true, false }, // LDF
+ { NOG, wrrr, M680X_REG_HX, NOR, true, false }, // LDHX
+ { NOG, mrrr, M680X_REG_MD, NOR, false, false }, // LDMD
+ { NOG, wrrr, M680X_REG_Q, NOR, true, false }, // LDQ
+ { NOG, wrrr, M680X_REG_S, NOR, true, false }, // LDS
+ { NOG, wrrr, M680X_REG_U, NOR, true, false }, // LDU
+ { NOG, wrrr, M680X_REG_W, NOR, true, false }, // LDW
+ { NOG, wrrr, M680X_REG_X, NOR, true, false }, // LDX
+ { NOG, wrrr, M680X_REG_Y, NOR, true, false }, // LDY
+ { NOG, wrrr, M680X_REG_S, NOR, false, false }, // LEAS
+ { NOG, wrrr, M680X_REG_U, NOR, false, false }, // LEAU
+ { NOG, wrrr, M680X_REG_X, NOR, false, false }, // LEAX
+ { NOG, wrrr, M680X_REG_Y, NOR, false, false }, // LEAY
+ { NOG, mrrr, NOR, NOR, true, false }, // LSL
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // LSLA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // LSLB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // LSLD
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // LSLX
+ { NOG, mrrr, NOR, NOR, true, false }, // LSR
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // LSRA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // LSRB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // LSRD
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // LSRW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // LSRX
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // MAXA
+ { NOG, mrrr, NOR, NOR, true, true }, // MAXM
+ { NOG, mmrr, NOR, NOR, true, true }, // MEM
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // MINA
+ { NOG, mrrr, NOR, NOR, true, true }, // MINM
+ { NOG, rwww, NOR, NOR, true, false }, // MOV
+ { NOG, rwww, NOR, NOR, false, false }, // MOVB
+ { NOG, rwww, NOR, NOR, false, false }, // MOVW
+ { NOG, mmmm, NOR, NOR, true, true }, // MUL
+ { NOG, mwrr, M680X_REG_D, NOR, true, true }, // MULD
+ { NOG, mrrr, NOR, NOR, true, false }, // NEG
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // NEGA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // NEGB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // NEGD
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // NEGX
+ { NOG, uuuu, NOR, NOR, false, false }, // NOP
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // NSA
+ { NOG, rmmm, NOR, NOR, true, false }, // OIM
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ORA
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ORAA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ORAB
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ORB
+ { NOG, mrrr, M680X_REG_CC, NOR, true, false }, // ORCC
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ORD
+ { NOG, rmmm, NOR, NOR, true, false }, // ORR
+ { NOG, rmmm, M680X_REG_A, NOR, false, true }, // PSHA
+ { NOG, rmmm, M680X_REG_B, NOR, false, true }, // PSHB
+ { NOG, rmmm, M680X_REG_CC, NOR, false, true }, // PSHC
+ { NOG, rmmm, M680X_REG_D, NOR, false, true }, // PSHD
+ { NOG, rmmm, M680X_REG_H, NOR, false, true }, // PSHH
+ { NOG, mrrr, M680X_REG_S, NOR, false, false }, // PSHS
+ { NOG, mrrr, M680X_REG_S, M680X_REG_W, false, false }, // PSHSW
+ { NOG, mrrr, M680X_REG_U, NOR, false, false }, // PSHU
+ { NOG, mrrr, M680X_REG_U, M680X_REG_W, false, false }, // PSHUW
+ { NOG, rmmm, M680X_REG_X, NOR, false, true }, // PSHX
+ { NOG, rmmm, M680X_REG_Y, NOR, false, true }, // PSHY
+ { NOG, wmmm, M680X_REG_A, NOR, false, true }, // PULA
+ { NOG, wmmm, M680X_REG_B, NOR, false, true }, // PULB
+ { NOG, wmmm, M680X_REG_CC, NOR, false, true }, // PULC
+ { NOG, wmmm, M680X_REG_D, NOR, false, true }, // PULD
+ { NOG, wmmm, M680X_REG_H, NOR, false, true }, // PULH
+ { NOG, mwww, M680X_REG_S, NOR, false, false }, // PULS
+ { NOG, mwww, M680X_REG_S, M680X_REG_W, false, false }, // PULSW
+ { NOG, mwww, M680X_REG_U, NOR, false, false }, // PULU
+ { NOG, mwww, M680X_REG_U, M680X_REG_W, false, false }, // PULUW
+ { NOG, wmmm, M680X_REG_X, NOR, false, true }, // PULX
+ { NOG, wmmm, M680X_REG_Y, NOR, false, true }, // PULY
+ { NOG, mmrr, NOR, NOR, true, true }, // REV
+ { NOG, mmmm, NOR, NOR, true, true }, // REVW
+ { NOG, mrrr, NOR, NOR, true, false }, // ROL
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // ROLA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // ROLB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // ROLD
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // ROLW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // ROLX
+ { NOG, mrrr, NOR, NOR, true, false }, // ROR
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // RORA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // RORB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // RORD
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // RORW
+ { NOG, mrrr, M680X_REG_X, NOR, true, false }, // RORX
+ { NOG, wrrr, M680X_REG_S, NOR, false, false }, // RSP
+ { M680X_GRP_RET, mwww, NOR, NOR, false, true }, // RTC
+ { M680X_GRP_IRET, mwww, NOR, NOR, false, true }, // RTI
+ { M680X_GRP_RET, mwww, NOR, NOR, false, true }, // RTS
+ { NOG, rmmm, M680X_REG_B, M680X_REG_A, true, false }, // SBA
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // SBC
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // SBCA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // SBCB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // SBCD
+ { NOG, rmmm, NOR, NOR, true, false }, // SBCR
+ { NOG, uuuu, NOR, NOR, true, false }, // SEC
+ { NOG, uuuu, NOR, NOR, true, false }, // SEI
+ { NOG, uuuu, NOR, NOR, true, false }, // SEV
+ { NOG, wrrr, NOR, NOR, true, true }, // SEX
+ { NOG, rwww, M680X_REG_W, NOR, true, true }, // SEXW
+ { NOG, uuuu, NOR, NOR, false, false }, // SLP
+ { NOG, rwww, M680X_REG_A, NOR, true, false }, // STA
+ { NOG, rwww, M680X_REG_A, NOR, true, false }, // STAA
+ { NOG, rwww, M680X_REG_B, NOR, true, false }, // STAB
+ { NOG, rwww, M680X_REG_B, NOR, true, false }, // STB
+ { NOG, rrrm, NOR, NOR, false, false }, // STBT
+ { NOG, rwww, M680X_REG_D, NOR, true, false }, // STD
+ { NOG, rwww, M680X_REG_E, NOR, true, false }, // STE
+ { NOG, rwww, M680X_REG_F, NOR, true, false }, // STF
+ { NOG, uuuu, NOR, NOR, false, false }, // STOP
+ { NOG, rwww, M680X_REG_HX, NOR, true, false }, // STHX
+ { NOG, rwww, M680X_REG_Q, NOR, true, false }, // STQ
+ { NOG, rwww, M680X_REG_S, NOR, true, false }, // STS
+ { NOG, rwww, M680X_REG_U, NOR, true, false }, // STU
+ { NOG, rwww, M680X_REG_W, NOR, true, false }, // STW
+ { NOG, rwww, M680X_REG_X, NOR, true, false }, // STX
+ { NOG, rwww, M680X_REG_Y, NOR, true, false }, // STY
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // SUB
+ { NOG, mrrr, M680X_REG_A, NOR, true, false }, // SUBA
+ { NOG, mrrr, M680X_REG_B, NOR, true, false }, // SUBB
+ { NOG, mrrr, M680X_REG_D, NOR, true, false }, // SUBD
+ { NOG, mrrr, M680X_REG_E, NOR, true, false }, // SUBE
+ { NOG, mrrr, M680X_REG_F, NOR, true, false }, // SUBF
+ { NOG, rmmm, NOR, NOR, true, false }, // SUBR
+ { NOG, mrrr, M680X_REG_W, NOR, true, false }, // SUBW
+ { M680X_GRP_INT, mmrr, NOR, NOR, true, true }, // SWI
+ { M680X_GRP_INT, mmrr, NOR, NOR, true, true }, // SWI2
+ { M680X_GRP_INT, mmrr, NOR, NOR, true, true }, // SWI3
+ { NOG, uuuu, NOR, NOR, false, false }, // SYNC
+ { NOG, rwww, M680X_REG_A, M680X_REG_B, true, false }, // TAB
+ { NOG, rwww, M680X_REG_A, M680X_REG_CC, false, false }, // TAP
+ { NOG, rwww, M680X_REG_A, M680X_REG_X, false, false }, // TAX
+ { NOG, rwww, M680X_REG_B, M680X_REG_A, true, false }, // TBA
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // TBEQ
+ { NOG, rmmm, NOR, NOR, true, true }, // TBL
+ { M680X_GRP_JUMP, muuu, NOR, NOR, false, false }, // TBNE
+ { NOG, uuuu, NOR, NOR, false, false }, // TEST
+ { NOG, rwww, NOR, NOR, false, false }, // TFM
+ { NOG, rwww, NOR, NOR, false, false }, // TFR
+ { NOG, rrrr, NOR, NOR, true, false }, // TIM
+ { NOG, rwww, M680X_REG_CC, M680X_REG_A, false, false }, // TPA
+ { NOG, rrrr, NOR, NOR, true, false }, // TST
+ { NOG, rrrr, M680X_REG_A, NOR, true, false }, // TSTA
+ { NOG, rrrr, M680X_REG_B, NOR, true, false }, // TSTB
+ { NOG, rrrr, M680X_REG_D, NOR, true, false }, // TSTD
+ { NOG, rrrr, M680X_REG_E, NOR, true, false }, // TSTE
+ { NOG, rrrr, M680X_REG_F, NOR, true, false }, // TSTF
+ { NOG, rrrr, M680X_REG_W, NOR, true, false }, // TSTW
+ { NOG, rrrr, M680X_REG_X, NOR, true, false }, // TSTX
+ { NOG, rwww, M680X_REG_S, M680X_REG_HX, false, false }, // TSX
+ { NOG, rwww, M680X_REG_S, M680X_REG_Y, false, false }, // TSY
+ { NOG, rwww, M680X_REG_X, M680X_REG_A, false, false }, // TXA
+ { NOG, rwww, M680X_REG_HX, M680X_REG_S, false, false }, // TXS
+ { NOG, rwww, M680X_REG_Y, M680X_REG_S, false, false }, // TYS
+ { NOG, mrrr, NOR, NOR, true, true }, // WAI
+ { NOG, uuuu, NOR, NOR, true, false }, // WAIT
+ { NOG, uuuu, NOR, NOR, true, true }, // WAV
+ { NOG, uuuu, NOR, NOR, true, true }, // WAVR
+ { NOG, mmmm, M680X_REG_D, M680X_REG_X, false, false }, // XGDX
+ { NOG, mmmm, M680X_REG_D, M680X_REG_Y, false, false }, // XGDY
+};
+#undef NOR
+#undef NOG
+
diff --git a/capstone/arch/M680X/m6800.inc b/capstone/arch/M680X/m6800.inc
new file mode 100644
index 000000000..b100aa3db
--- /dev/null
+++ b/capstone/arch/M680X/m6800.inc
@@ -0,0 +1,277 @@
+
+// M6800/2 instructions
+static const inst_page1 g_m6800_inst_page1_table[256] = {
+ // 0x0x, inherent instructions
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_NOP, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_TAP, inh_hid, inh_hid },
+ { M680X_INS_TPA, inh_hid, inh_hid },
+ { M680X_INS_INX, inh_hid, inh_hid },
+ { M680X_INS_DEX, inh_hid, inh_hid },
+ { M680X_INS_CLV, inh_hid, inh_hid },
+ { M680X_INS_SEV, inh_hid, inh_hid },
+ { M680X_INS_CLC, inh_hid, inh_hid },
+ { M680X_INS_SEC, inh_hid, inh_hid },
+ { M680X_INS_CLI, inh_hid, inh_hid },
+ { M680X_INS_SEI, inh_hid, inh_hid },
+ // 0x1x, inherent instructions
+ { M680X_INS_SBA, inh_hid, inh_hid },
+ { M680X_INS_CBA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_TAB, inh_hid, inh_hid },
+ { M680X_INS_TBA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_DAA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ABA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0x2x, relative branch instructions
+ { M680X_INS_BRA, rel8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_BHI, rel8_hid, inh_hid },
+ { M680X_INS_BLS, rel8_hid, inh_hid },
+ { M680X_INS_BCC, rel8_hid, inh_hid },
+ { M680X_INS_BCS, rel8_hid, inh_hid },
+ { M680X_INS_BNE, rel8_hid, inh_hid },
+ { M680X_INS_BEQ, rel8_hid, inh_hid },
+ { M680X_INS_BVC, rel8_hid, inh_hid },
+ { M680X_INS_BVS, rel8_hid, inh_hid },
+ { M680X_INS_BPL, rel8_hid, inh_hid },
+ { M680X_INS_BMI, rel8_hid, inh_hid },
+ { M680X_INS_BGE, rel8_hid, inh_hid },
+ { M680X_INS_BLT, rel8_hid, inh_hid },
+ { M680X_INS_BGT, rel8_hid, inh_hid },
+ { M680X_INS_BLE, rel8_hid, inh_hid },
+ // 0x3x, inherent instructions
+ { M680X_INS_TSX, inh_hid, inh_hid },
+ { M680X_INS_INS, inh_hid, inh_hid },
+ { M680X_INS_PULA, inh_hid, inh_hid },
+ { M680X_INS_PULB, inh_hid, inh_hid },
+ { M680X_INS_DES, inh_hid, inh_hid },
+ { M680X_INS_TXS, inh_hid, inh_hid },
+ { M680X_INS_PSHA, inh_hid, inh_hid },
+ { M680X_INS_PSHB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RTS, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RTI, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_WAI, inh_hid, inh_hid },
+ { M680X_INS_SWI, inh_hid, inh_hid },
+ // 0x4x, Register A instructions
+ { M680X_INS_NEGA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COMA, inh_hid, inh_hid },
+ { M680X_INS_LSRA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORA, inh_hid, inh_hid },
+ { M680X_INS_ASRA, inh_hid, inh_hid },
+ { M680X_INS_ASLA, inh_hid, inh_hid },
+ { M680X_INS_ROLA, inh_hid, inh_hid },
+ { M680X_INS_DECA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCA, inh_hid, inh_hid },
+ { M680X_INS_TSTA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRA, inh_hid, inh_hid },
+ // 0x5x, Register B instructions
+ { M680X_INS_NEGB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COMB, inh_hid, inh_hid },
+ { M680X_INS_LSRB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORB, inh_hid, inh_hid },
+ { M680X_INS_ASRB, inh_hid, inh_hid },
+ { M680X_INS_ASLB, inh_hid, inh_hid },
+ { M680X_INS_ROLB, inh_hid, inh_hid },
+ { M680X_INS_DECB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCB, inh_hid, inh_hid },
+ { M680X_INS_TSTB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRB, inh_hid, inh_hid },
+ // 0x6x, indexed instructions
+ { M680X_INS_NEG, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, idxX_hid, inh_hid },
+ { M680X_INS_LSR, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, idxX_hid, inh_hid },
+ { M680X_INS_ASR, idxX_hid, inh_hid },
+ { M680X_INS_ASL, idxX_hid, inh_hid },
+ { M680X_INS_ROL, idxX_hid, inh_hid },
+ { M680X_INS_DEC, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, idxX_hid, inh_hid },
+ { M680X_INS_TST, idxX_hid, inh_hid },
+ { M680X_INS_JMP, idxX_hid, inh_hid },
+ { M680X_INS_CLR, idxX_hid, inh_hid },
+ // 0x7x, extended instructions
+ { M680X_INS_NEG, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, ext_hid, inh_hid },
+ { M680X_INS_LSR, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, ext_hid, inh_hid },
+ { M680X_INS_ASR, ext_hid, inh_hid },
+ { M680X_INS_ASL, ext_hid, inh_hid },
+ { M680X_INS_ROL, ext_hid, inh_hid },
+ { M680X_INS_DEC, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, ext_hid, inh_hid },
+ { M680X_INS_TST, ext_hid, inh_hid },
+ { M680X_INS_JMP, ext_hid, inh_hid },
+ { M680X_INS_CLR, ext_hid, inh_hid },
+ // 0x8x, immediate instructions with Register A,X,S
+ { M680X_INS_SUBA, imm8_hid, inh_hid },
+ { M680X_INS_CMPA, imm8_hid, inh_hid },
+ { M680X_INS_SBCA, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDA, imm8_hid, inh_hid },
+ { M680X_INS_BITA, imm8_hid, inh_hid },
+ { M680X_INS_LDAA, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_EORA, imm8_hid, inh_hid },
+ { M680X_INS_ADCA, imm8_hid, inh_hid },
+ { M680X_INS_ORAA, imm8_hid, inh_hid },
+ { M680X_INS_ADDA, imm8_hid, inh_hid },
+ { M680X_INS_CPX, imm16_hid, inh_hid },
+ { M680X_INS_BSR, rel8_hid, inh_hid },
+ { M680X_INS_LDS, imm16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0x9x, direct instructions with register A,X,S
+ { M680X_INS_SUBA, dir_hid, inh_hid },
+ { M680X_INS_CMPA, dir_hid, inh_hid },
+ { M680X_INS_SBCA, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDA, dir_hid, inh_hid },
+ { M680X_INS_BITA, dir_hid, inh_hid },
+ { M680X_INS_LDAA, dir_hid, inh_hid },
+ { M680X_INS_STAA, dir_hid, inh_hid },
+ { M680X_INS_EORA, dir_hid, inh_hid },
+ { M680X_INS_ADCA, dir_hid, inh_hid },
+ { M680X_INS_ORAA, dir_hid, inh_hid },
+ { M680X_INS_ADDA, dir_hid, inh_hid },
+ { M680X_INS_CPX, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDS, dir_hid, inh_hid },
+ { M680X_INS_STS, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with Register A,X
+ { M680X_INS_SUBA, idxX_hid, inh_hid },
+ { M680X_INS_CMPA, idxX_hid, inh_hid },
+ { M680X_INS_SBCA, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDA, idxX_hid, inh_hid },
+ { M680X_INS_BITA, idxX_hid, inh_hid },
+ { M680X_INS_LDAA, idxX_hid, inh_hid },
+ { M680X_INS_STAA, idxX_hid, inh_hid },
+ { M680X_INS_EORA, idxX_hid, inh_hid },
+ { M680X_INS_ADCA, idxX_hid, inh_hid },
+ { M680X_INS_ORAA, idxX_hid, inh_hid },
+ { M680X_INS_ADDA, idxX_hid, inh_hid },
+ { M680X_INS_CPX, idxX_hid, inh_hid },
+ { M680X_INS_JSR, idxX_hid, inh_hid },
+ { M680X_INS_LDS, idxX_hid, inh_hid },
+ { M680X_INS_STS, idxX_hid, inh_hid },
+ // 0xBx, extended instructions with register A,X,S
+ { M680X_INS_SUBA, ext_hid, inh_hid },
+ { M680X_INS_CMPA, ext_hid, inh_hid },
+ { M680X_INS_SBCA, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDA, ext_hid, inh_hid },
+ { M680X_INS_BITA, ext_hid, inh_hid },
+ { M680X_INS_LDAA, ext_hid, inh_hid },
+ { M680X_INS_STAA, ext_hid, inh_hid },
+ { M680X_INS_EORA, ext_hid, inh_hid },
+ { M680X_INS_ADCA, ext_hid, inh_hid },
+ { M680X_INS_ORAA, ext_hid, inh_hid },
+ { M680X_INS_ADDA, ext_hid, inh_hid },
+ { M680X_INS_CPX, ext_hid, inh_hid },
+ { M680X_INS_JSR, ext_hid, inh_hid },
+ { M680X_INS_LDS, ext_hid, inh_hid },
+ { M680X_INS_STS, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register B,X
+ { M680X_INS_SUBB, imm8_hid, inh_hid },
+ { M680X_INS_CMPB, imm8_hid, inh_hid },
+ { M680X_INS_SBCB, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDB, imm8_hid, inh_hid },
+ { M680X_INS_BITB, imm8_hid, inh_hid },
+ { M680X_INS_LDAB, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_EORB, imm8_hid, inh_hid },
+ { M680X_INS_ADCB, imm8_hid, inh_hid },
+ { M680X_INS_ORAB, imm8_hid, inh_hid },
+ { M680X_INS_ADDB, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDX, imm16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0xDx direct instructions with register B,X
+ { M680X_INS_SUBB, dir_hid, inh_hid },
+ { M680X_INS_CMPB, dir_hid, inh_hid },
+ { M680X_INS_SBCB, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDB, dir_hid, inh_hid },
+ { M680X_INS_BITB, dir_hid, inh_hid },
+ { M680X_INS_LDAB, dir_hid, inh_hid },
+ { M680X_INS_STAB, dir_hid, inh_hid },
+ { M680X_INS_EORB, dir_hid, inh_hid },
+ { M680X_INS_ADCB, dir_hid, inh_hid },
+ { M680X_INS_ORAB, dir_hid, inh_hid },
+ { M680X_INS_ADDB, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDX, dir_hid, inh_hid },
+ { M680X_INS_STX, dir_hid, inh_hid },
+ // 0xEx, indexed instruction with register B,X
+ { M680X_INS_SUBB, idxX_hid, inh_hid },
+ { M680X_INS_CMPB, idxX_hid, inh_hid },
+ { M680X_INS_SBCB, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDB, idxX_hid, inh_hid },
+ { M680X_INS_BITB, idxX_hid, inh_hid },
+ { M680X_INS_LDAB, idxX_hid, inh_hid },
+ { M680X_INS_STAB, idxX_hid, inh_hid },
+ { M680X_INS_EORB, idxX_hid, inh_hid },
+ { M680X_INS_ADCB, idxX_hid, inh_hid },
+ { M680X_INS_ORAB, idxX_hid, inh_hid },
+ { M680X_INS_ADDB, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDX, idxX_hid, inh_hid },
+ { M680X_INS_STX, idxX_hid, inh_hid },
+ // 0xFx, extended instructions with register B,U
+ { M680X_INS_SUBB, ext_hid, inh_hid },
+ { M680X_INS_CMPB, ext_hid, inh_hid },
+ { M680X_INS_SBCB, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDB, ext_hid, inh_hid },
+ { M680X_INS_BITB, ext_hid, inh_hid },
+ { M680X_INS_LDAB, ext_hid, inh_hid },
+ { M680X_INS_STAB, ext_hid, inh_hid },
+ { M680X_INS_EORB, ext_hid, inh_hid },
+ { M680X_INS_ADCB, ext_hid, inh_hid },
+ { M680X_INS_ORAB, ext_hid, inh_hid },
+ { M680X_INS_ADDB, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDX, ext_hid, inh_hid },
+ { M680X_INS_STX, ext_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/m6801.inc b/capstone/arch/M680X/m6801.inc
new file mode 100644
index 000000000..0fe4592ca
--- /dev/null
+++ b/capstone/arch/M680X/m6801.inc
@@ -0,0 +1,39 @@
+
+// Additional instructions only supported on M6801/3
+static const inst_pageX g_m6801_inst_overlay_table[] = {
+ // 0x0x, inherent instructions
+ { 0x04, M680X_INS_LSRD, inh_hid, inh_hid },
+ { 0x05, M680X_INS_ASLD, inh_hid, inh_hid },
+ // 0x2x, relative branch instructions
+ { 0x21, M680X_INS_BRN, rel8_hid, inh_hid },
+ // 0x3x, inherent instructions
+ { 0x38, M680X_INS_PULX, inh_hid, inh_hid },
+ { 0x3A, M680X_INS_ABX, inh_hid, inh_hid },
+ { 0x3C, M680X_INS_PSHX, inh_hid, inh_hid },
+ { 0x3D, M680X_INS_MUL, inh_hid, inh_hid },
+ // 0x8x, immediate instructions with Register D
+ { 0x83, M680X_INS_SUBD, imm16_hid, inh_hid },
+ // 0x9x, direct instructions with register D
+ { 0x93, M680X_INS_SUBD, dir_hid, inh_hid },
+ { 0x9D, M680X_INS_JSR, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with Register D
+ { 0xA3, M680X_INS_SUBD, idxX_hid, inh_hid },
+ // 0xBx, extended instructions with register D
+ { 0xB3, M680X_INS_SUBD, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register D
+ { 0xC3, M680X_INS_ADDD, imm16_hid, inh_hid },
+ { 0xCC, M680X_INS_LDD, imm16_hid, inh_hid },
+ // 0xDx direct instructions with register D
+ { 0xD3, M680X_INS_ADDD, dir_hid, inh_hid },
+ { 0xDC, M680X_INS_LDD, dir_hid, inh_hid },
+ { 0xDD, M680X_INS_STD, dir_hid, inh_hid },
+ // 0xEx, indexed instruction with register D
+ { 0xE3, M680X_INS_ADDD, idxX_hid, inh_hid },
+ { 0xEC, M680X_INS_LDD, idxX_hid, inh_hid },
+ { 0xED, M680X_INS_STD, idxX_hid, inh_hid },
+ // 0xFx, extended instructions with register D
+ { 0xF3, M680X_INS_ADDD, ext_hid, inh_hid },
+ { 0xFC, M680X_INS_LDD, ext_hid, inh_hid },
+ { 0xFD, M680X_INS_STD, ext_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/m6805.inc b/capstone/arch/M680X/m6805.inc
new file mode 100644
index 000000000..080c1406c
--- /dev/null
+++ b/capstone/arch/M680X/m6805.inc
@@ -0,0 +1,277 @@
+
+// M68HC05 instructions
+static const inst_page1 g_m6805_inst_page1_table[256] = {
+ // 0x0x, bit manipulation instructions
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ { M680X_INS_BRSET, opidxdr_hid, inh_hid },
+ { M680X_INS_BRCLR, opidxdr_hid, inh_hid },
+ // 0x1x, bit set/clear instructions
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ { M680X_INS_BCLR, opidx_hid, dir_hid },
+ { M680X_INS_BSET, opidx_hid, dir_hid },
+ // 0x2x, relative branch instructions
+ { M680X_INS_BRA, rel8_hid, inh_hid },
+ { M680X_INS_BRN, rel8_hid, inh_hid },
+ { M680X_INS_BHI, rel8_hid, inh_hid },
+ { M680X_INS_BLS, rel8_hid, inh_hid },
+ { M680X_INS_BCC, rel8_hid, inh_hid },
+ { M680X_INS_BCS, rel8_hid, inh_hid },
+ { M680X_INS_BNE, rel8_hid, inh_hid },
+ { M680X_INS_BEQ, rel8_hid, inh_hid },
+ { M680X_INS_BHCC, rel8_hid, inh_hid },
+ { M680X_INS_BHCS, rel8_hid, inh_hid },
+ { M680X_INS_BPL, rel8_hid, inh_hid },
+ { M680X_INS_BMI, rel8_hid, inh_hid },
+ { M680X_INS_BMC, rel8_hid, inh_hid },
+ { M680X_INS_BMS, rel8_hid, inh_hid },
+ { M680X_INS_BIL, rel8_hid, inh_hid },
+ { M680X_INS_BIH, rel8_hid, inh_hid },
+ // 0x3x, direct instructions
+ { M680X_INS_NEG, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, dir_hid, inh_hid },
+ { M680X_INS_LSR, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, dir_hid, inh_hid },
+ { M680X_INS_ASR, dir_hid, inh_hid },
+ { M680X_INS_LSL, dir_hid, inh_hid },
+ { M680X_INS_ROL, dir_hid, inh_hid },
+ { M680X_INS_DEC, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, dir_hid, inh_hid },
+ { M680X_INS_TST, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLR, dir_hid, inh_hid },
+ // 0x4x, inherent instructions
+ { M680X_INS_NEGA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_MUL, inh_hid, inh_hid },
+ { M680X_INS_COMA, inh_hid, inh_hid },
+ { M680X_INS_LSRA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORA, inh_hid, inh_hid },
+ { M680X_INS_ASRA, inh_hid, inh_hid },
+ { M680X_INS_LSLA, inh_hid, inh_hid },
+ { M680X_INS_ROLA, inh_hid, inh_hid },
+ { M680X_INS_DECA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCA, inh_hid, inh_hid },
+ { M680X_INS_TSTA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRA, inh_hid, inh_hid },
+ // 0x5x, inherent instructions
+ { M680X_INS_NEGX, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COMX, inh_hid, inh_hid },
+ { M680X_INS_LSRX, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORX, inh_hid, inh_hid },
+ { M680X_INS_ASRX, inh_hid, inh_hid },
+ { M680X_INS_LSLX, inh_hid, inh_hid },
+ { M680X_INS_ROLX, inh_hid, inh_hid },
+ { M680X_INS_DECX, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCX, inh_hid, inh_hid },
+ { M680X_INS_TSTX, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRX, inh_hid, inh_hid },
+ // 0x6x, indexed, 1 byte offset instructions
+ { M680X_INS_NEG, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, idxX_hid, inh_hid },
+ { M680X_INS_LSR, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, idxX_hid, inh_hid },
+ { M680X_INS_ASR, idxX_hid, inh_hid },
+ { M680X_INS_LSL, idxX_hid, inh_hid },
+ { M680X_INS_ROL, idxX_hid, inh_hid },
+ { M680X_INS_DEC, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, idxX_hid, inh_hid },
+ { M680X_INS_TST, idxX_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLR, idxX_hid, inh_hid },
+ // 0x7x, indexed, no offset instructions
+ { M680X_INS_NEG, idxX0_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, idxX0_hid, inh_hid },
+ { M680X_INS_LSR, idxX0_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, idxX0_hid, inh_hid },
+ { M680X_INS_ASR, idxX0_hid, inh_hid },
+ { M680X_INS_LSL, idxX0_hid, inh_hid },
+ { M680X_INS_ROL, idxX0_hid, inh_hid },
+ { M680X_INS_DEC, idxX0_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, idxX0_hid, inh_hid },
+ { M680X_INS_TST, idxX0_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLR, idxX0_hid, inh_hid },
+ // 0x8x, inherent instructions
+ { M680X_INS_RTI, inh_hid, inh_hid },
+ { M680X_INS_RTS, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_SWI, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_STOP, inh_hid, inh_hid },
+ { M680X_INS_WAIT, inh_hid, inh_hid },
+ // 0x9x, inherent instructions
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_TAX, inh_hid, inh_hid },
+ { M680X_INS_CLC, inh_hid, inh_hid },
+ { M680X_INS_SEC, inh_hid, inh_hid },
+ { M680X_INS_CLI, inh_hid, inh_hid },
+ { M680X_INS_SEI, inh_hid, inh_hid },
+ { M680X_INS_RSP, inh_hid, inh_hid },
+ { M680X_INS_NOP, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_TXA, inh_hid, inh_hid },
+ // 0xAx, immediate instructions with reg. A
+ { M680X_INS_SUB, imm8_hid, inh_hid },
+ { M680X_INS_CMP, imm8_hid, inh_hid },
+ { M680X_INS_SBC, imm8_hid, inh_hid },
+ { M680X_INS_CPX, imm8_hid, inh_hid },
+ { M680X_INS_AND, imm8_hid, inh_hid },
+ { M680X_INS_BIT, imm8_hid, inh_hid },
+ { M680X_INS_LDA, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_EOR, imm8_hid, inh_hid },
+ { M680X_INS_ADC, imm8_hid, inh_hid },
+ { M680X_INS_ORA, imm8_hid, inh_hid },
+ { M680X_INS_ADD, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_BSR, rel8_hid, inh_hid },
+ { M680X_INS_LDX, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0xBx, direct instructions with reg. A
+ { M680X_INS_SUB, dir_hid, inh_hid },
+ { M680X_INS_CMP, dir_hid, inh_hid },
+ { M680X_INS_SBC, dir_hid, inh_hid },
+ { M680X_INS_CPX, dir_hid, inh_hid },
+ { M680X_INS_AND, dir_hid, inh_hid },
+ { M680X_INS_BIT, dir_hid, inh_hid },
+ { M680X_INS_LDA, dir_hid, inh_hid },
+ { M680X_INS_STA, dir_hid, inh_hid },
+ { M680X_INS_EOR, dir_hid, inh_hid },
+ { M680X_INS_ADC, dir_hid, inh_hid },
+ { M680X_INS_ORA, dir_hid, inh_hid },
+ { M680X_INS_ADD, dir_hid, inh_hid },
+ { M680X_INS_JMP, dir_hid, inh_hid },
+ { M680X_INS_JSR, dir_hid, inh_hid },
+ { M680X_INS_LDX, dir_hid, inh_hid },
+ { M680X_INS_STX, dir_hid, inh_hid },
+ // 0xCx, extended instructions with reg. A
+ { M680X_INS_SUB, ext_hid, inh_hid },
+ { M680X_INS_CMP, ext_hid, inh_hid },
+ { M680X_INS_SBC, ext_hid, inh_hid },
+ { M680X_INS_CPX, ext_hid, inh_hid },
+ { M680X_INS_AND, ext_hid, inh_hid },
+ { M680X_INS_BIT, ext_hid, inh_hid },
+ { M680X_INS_LDA, ext_hid, inh_hid },
+ { M680X_INS_STA, ext_hid, inh_hid },
+ { M680X_INS_EOR, ext_hid, inh_hid },
+ { M680X_INS_ADC, ext_hid, inh_hid },
+ { M680X_INS_ORA, ext_hid, inh_hid },
+ { M680X_INS_ADD, ext_hid, inh_hid },
+ { M680X_INS_JMP, ext_hid, inh_hid },
+ { M680X_INS_JSR, ext_hid, inh_hid },
+ { M680X_INS_LDX, ext_hid, inh_hid },
+ { M680X_INS_STX, ext_hid, inh_hid },
+ // 0xDx, indexed with 2 byte offset instructions with reg. A
+ { M680X_INS_SUB, idxX16_hid, inh_hid },
+ { M680X_INS_CMP, idxX16_hid, inh_hid },
+ { M680X_INS_SBC, idxX16_hid, inh_hid },
+ { M680X_INS_CPX, idxX16_hid, inh_hid },
+ { M680X_INS_AND, idxX16_hid, inh_hid },
+ { M680X_INS_BIT, idxX16_hid, inh_hid },
+ { M680X_INS_LDA, idxX16_hid, inh_hid },
+ { M680X_INS_STA, idxX16_hid, inh_hid },
+ { M680X_INS_EOR, idxX16_hid, inh_hid },
+ { M680X_INS_ADC, idxX16_hid, inh_hid },
+ { M680X_INS_ORA, idxX16_hid, inh_hid },
+ { M680X_INS_ADD, idxX16_hid, inh_hid },
+ { M680X_INS_JMP, idxX16_hid, inh_hid },
+ { M680X_INS_JSR, idxX16_hid, inh_hid },
+ { M680X_INS_LDX, idxX16_hid, inh_hid },
+ { M680X_INS_STX, idxX16_hid, inh_hid },
+ // 0xEx, indexed with 1 byte offset instructions with reg. A
+ { M680X_INS_SUB, idxX_hid, inh_hid },
+ { M680X_INS_CMP, idxX_hid, inh_hid },
+ { M680X_INS_SBC, idxX_hid, inh_hid },
+ { M680X_INS_CPX, idxX_hid, inh_hid },
+ { M680X_INS_AND, idxX_hid, inh_hid },
+ { M680X_INS_BIT, idxX_hid, inh_hid },
+ { M680X_INS_LDA, idxX_hid, inh_hid },
+ { M680X_INS_STA, idxX_hid, inh_hid },
+ { M680X_INS_EOR, idxX_hid, inh_hid },
+ { M680X_INS_ADC, idxX_hid, inh_hid },
+ { M680X_INS_ORA, idxX_hid, inh_hid },
+ { M680X_INS_ADD, idxX_hid, inh_hid },
+ { M680X_INS_JMP, idxX_hid, inh_hid },
+ { M680X_INS_JSR, idxX_hid, inh_hid },
+ { M680X_INS_LDX, idxX_hid, inh_hid },
+ { M680X_INS_STX, idxX_hid, inh_hid },
+ // 0xFx, indexed without offset instructions with reg. A
+ { M680X_INS_SUB, idxX0_hid, inh_hid },
+ { M680X_INS_CMP, idxX0_hid, inh_hid },
+ { M680X_INS_SBC, idxX0_hid, inh_hid },
+ { M680X_INS_CPX, idxX0_hid, inh_hid },
+ { M680X_INS_AND, idxX0_hid, inh_hid },
+ { M680X_INS_BIT, idxX0_hid, inh_hid },
+ { M680X_INS_LDA, idxX0_hid, inh_hid },
+ { M680X_INS_STA, idxX0_hid, inh_hid },
+ { M680X_INS_EOR, idxX0_hid, inh_hid },
+ { M680X_INS_ADC, idxX0_hid, inh_hid },
+ { M680X_INS_ORA, idxX0_hid, inh_hid },
+ { M680X_INS_ADD, idxX0_hid, inh_hid },
+ { M680X_INS_JMP, idxX0_hid, inh_hid },
+ { M680X_INS_JSR, idxX0_hid, inh_hid },
+ { M680X_INS_LDX, idxX0_hid, inh_hid },
+ { M680X_INS_STX, idxX0_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/m6808.inc b/capstone/arch/M680X/m6808.inc
new file mode 100644
index 000000000..6114f3c3f
--- /dev/null
+++ b/capstone/arch/M680X/m6808.inc
@@ -0,0 +1,91 @@
+
+// Additional instructions only supported on M68HC08
+static const inst_pageX g_m6808_inst_overlay_table[] = {
+ { 0x31, M680X_INS_CBEQ, dir_hid, rel8_hid },
+ { 0x35, M680X_INS_STHX, dir_hid, inh_hid },
+ { 0x3b, M680X_INS_DBNZ, dir_hid, rel8_hid },
+ { 0x41, M680X_INS_CBEQA, imm8rel_hid, inh_hid },
+ { 0x45, M680X_INS_LDHX, imm16_hid, inh_hid },
+ { 0x4b, M680X_INS_DBNZA, rel8_hid, inh_hid },
+ { 0x4e, M680X_INS_MOV, dir_hid, dir_hid },
+ { 0x51, M680X_INS_CBEQX, imm8rel_hid, inh_hid },
+ { 0x52, M680X_INS_DIV, inh_hid, inh_hid },
+ { 0x55, M680X_INS_LDHX, dir_hid, inh_hid },
+ { 0x5b, M680X_INS_DBNZX, rel8_hid, inh_hid },
+ { 0x5e, M680X_INS_MOV, dir_hid, idxX0p_hid },
+ { 0x61, M680X_INS_CBEQ, idxXp_hid, rel8_hid },
+ { 0x62, M680X_INS_NSA, inh_hid, inh_hid },
+ { 0x65, M680X_INS_CPHX, imm16_hid, inh_hid },
+ { 0x6b, M680X_INS_DBNZ, idxX_hid, rel8_hid },
+ { 0x6e, M680X_INS_MOV, imm8_hid, dir_hid },
+ { 0x71, M680X_INS_CBEQ, idxX0p_hid, rel8_hid },
+ { 0x72, M680X_INS_DAA, inh_hid, inh_hid },
+ { 0x75, M680X_INS_CPHX, dir_hid, inh_hid },
+ { 0x7b, M680X_INS_DBNZ, idxX0_hid, rel8_hid },
+ { 0x7e, M680X_INS_MOV, idxX0p_hid, dir_hid },
+ { 0x84, M680X_INS_TAP, inh_hid, inh_hid },
+ { 0x85, M680X_INS_TPA, inh_hid, inh_hid },
+ { 0x86, M680X_INS_PULA, inh_hid, inh_hid },
+ { 0x87, M680X_INS_PSHA, inh_hid, inh_hid },
+ { 0x88, M680X_INS_PULX, inh_hid, inh_hid },
+ { 0x89, M680X_INS_PSHX, inh_hid, inh_hid },
+ { 0x8a, M680X_INS_PULH, inh_hid, inh_hid },
+ { 0x8b, M680X_INS_PSHH, inh_hid, inh_hid },
+ { 0x8c, M680X_INS_CLRH, inh_hid, inh_hid },
+ { 0x90, M680X_INS_BGE, rel8_hid, inh_hid },
+ { 0x91, M680X_INS_BLT, rel8_hid, inh_hid },
+ { 0x92, M680X_INS_BGT, rel8_hid, inh_hid },
+ { 0x93, M680X_INS_BLE, rel8_hid, inh_hid },
+ { 0x94, M680X_INS_TXS, inh_hid, inh_hid },
+ { 0x95, M680X_INS_TSX, inh_hid, inh_hid },
+ { 0x97, M680X_INS_TAX, inh_hid, inh_hid },
+ { 0x9f, M680X_INS_TXA, inh_hid, inh_hid },
+ { 0xa7, M680X_INS_AIS, imm8_hid, inh_hid },
+ { 0xaf, M680X_INS_AIX, imm8_hid, inh_hid },
+};
+
+// M68HC08 PAGE2 instructions (prefix 0x9E)
+static const inst_pageX g_m6808_inst_page2_table[] = {
+ { 0x60, M680X_INS_NEG, idxS_hid, inh_hid },
+ { 0x61, M680X_INS_CBEQ, idxS_hid, rel8_hid },
+ { 0x63, M680X_INS_COM, idxS_hid, inh_hid },
+ { 0x64, M680X_INS_LSR, idxS_hid, inh_hid },
+ { 0x66, M680X_INS_ROR, idxS_hid, inh_hid },
+ { 0x67, M680X_INS_ASR, idxS_hid, inh_hid },
+ { 0x68, M680X_INS_LSL, idxS_hid, inh_hid },
+ { 0x69, M680X_INS_ROL, idxS_hid, inh_hid },
+ { 0x6a, M680X_INS_DEC, idxS_hid, inh_hid },
+ { 0x6b, M680X_INS_DBNZ, idxS_hid, rel8_hid },
+ { 0x6c, M680X_INS_INC, idxS_hid, inh_hid },
+ { 0x6d, M680X_INS_TST, idxS_hid, inh_hid },
+ { 0x6f, M680X_INS_CLR, idxS_hid, inh_hid },
+ { 0xd0, M680X_INS_SUB, idxS16_hid, inh_hid },
+ { 0xd1, M680X_INS_CMP, idxS16_hid, inh_hid },
+ { 0xd2, M680X_INS_SBC, idxS16_hid, inh_hid },
+ { 0xd3, M680X_INS_CPX, idxS16_hid, inh_hid },
+ { 0xd4, M680X_INS_AND, idxS16_hid, inh_hid },
+ { 0xd5, M680X_INS_BIT, idxS16_hid, inh_hid },
+ { 0xd6, M680X_INS_LDA, idxS16_hid, inh_hid },
+ { 0xd7, M680X_INS_STA, idxS16_hid, inh_hid },
+ { 0xd8, M680X_INS_EOR, idxS16_hid, inh_hid },
+ { 0xd9, M680X_INS_ADC, idxS16_hid, inh_hid },
+ { 0xda, M680X_INS_ORA, idxS16_hid, inh_hid },
+ { 0xdb, M680X_INS_ADD, idxS16_hid, inh_hid },
+ { 0xde, M680X_INS_LDX, idxS16_hid, inh_hid },
+ { 0xdf, M680X_INS_STX, idxS16_hid, inh_hid },
+ { 0xe0, M680X_INS_SUB, idxS_hid, inh_hid },
+ { 0xe1, M680X_INS_CMP, idxS_hid, inh_hid },
+ { 0xe2, M680X_INS_SBC, idxS_hid, inh_hid },
+ { 0xe3, M680X_INS_CPX, idxS_hid, inh_hid },
+ { 0xe4, M680X_INS_AND, idxS_hid, inh_hid },
+ { 0xe5, M680X_INS_BIT, idxS_hid, inh_hid },
+ { 0xe6, M680X_INS_LDA, idxS_hid, inh_hid },
+ { 0xe7, M680X_INS_STA, idxS_hid, inh_hid },
+ { 0xe8, M680X_INS_EOR, idxS_hid, inh_hid },
+ { 0xe9, M680X_INS_ADC, idxS_hid, inh_hid },
+ { 0xea, M680X_INS_ORA, idxS_hid, inh_hid },
+ { 0xeb, M680X_INS_ADD, idxS_hid, inh_hid },
+ { 0xee, M680X_INS_LDX, idxS_hid, inh_hid },
+ { 0xef, M680X_INS_STX, idxS_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/m6809.inc b/capstone/arch/M680X/m6809.inc
new file mode 100644
index 000000000..24f02603f
--- /dev/null
+++ b/capstone/arch/M680X/m6809.inc
@@ -0,0 +1,352 @@
+
+// M6809/HD6309 PAGE1 instructions
+static const inst_page1 g_m6809_inst_page1_table[256] = {
+ // 0x0x, direct instructions
+ { M680X_INS_NEG, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, dir_hid, inh_hid },
+ { M680X_INS_LSR, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, dir_hid, inh_hid },
+ { M680X_INS_ASR, dir_hid, inh_hid },
+ { M680X_INS_LSL, dir_hid, inh_hid },
+ { M680X_INS_ROL, dir_hid, inh_hid },
+ { M680X_INS_DEC, dir_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, dir_hid, inh_hid },
+ { M680X_INS_TST, dir_hid, inh_hid },
+ { M680X_INS_JMP, dir_hid, inh_hid },
+ { M680X_INS_CLR, dir_hid, inh_hid },
+ // 0x1x, misc instructions
+ { M680X_INS_ILLGL, illgl_hid, inh_hid }, // PAGE2
+ { M680X_INS_ILLGL, illgl_hid, inh_hid }, // PAGE3
+ { M680X_INS_NOP, inh_hid, inh_hid },
+ { M680X_INS_SYNC, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LBRA, rel16_hid, inh_hid },
+ { M680X_INS_LBSR, rel16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_DAA, inh_hid, inh_hid },
+ { M680X_INS_ORCC, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ANDCC, imm8_hid, inh_hid },
+ { M680X_INS_SEX, inh_hid, inh_hid },
+ { M680X_INS_EXG, rr09_hid, inh_hid },
+ { M680X_INS_TFR, rr09_hid, inh_hid },
+ // 0x2x, relative branch instructions
+ { M680X_INS_BRA, rel8_hid, inh_hid },
+ { M680X_INS_BRN, rel8_hid, inh_hid },
+ { M680X_INS_BHI, rel8_hid, inh_hid },
+ { M680X_INS_BLS, rel8_hid, inh_hid },
+ { M680X_INS_BCC, rel8_hid, inh_hid },
+ { M680X_INS_BCS, rel8_hid, inh_hid },
+ { M680X_INS_BNE, rel8_hid, inh_hid },
+ { M680X_INS_BEQ, rel8_hid, inh_hid },
+ { M680X_INS_BVC, rel8_hid, inh_hid },
+ { M680X_INS_BVS, rel8_hid, inh_hid },
+ { M680X_INS_BPL, rel8_hid, inh_hid },
+ { M680X_INS_BMI, rel8_hid, inh_hid },
+ { M680X_INS_BGE, rel8_hid, inh_hid },
+ { M680X_INS_BLT, rel8_hid, inh_hid },
+ { M680X_INS_BGT, rel8_hid, inh_hid },
+ { M680X_INS_BLE, rel8_hid, inh_hid },
+ // 0x3x, misc instructions
+ { M680X_INS_LEAX, idx09_hid, inh_hid },
+ { M680X_INS_LEAY, idx09_hid, inh_hid },
+ { M680X_INS_LEAS, idx09_hid, inh_hid },
+ { M680X_INS_LEAU, idx09_hid, inh_hid },
+ { M680X_INS_PSHS, rbits_hid, inh_hid },
+ { M680X_INS_PULS, rbits_hid, inh_hid },
+ { M680X_INS_PSHU, rbits_hid, inh_hid },
+ { M680X_INS_PULU, rbits_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RTS, inh_hid, inh_hid },
+ { M680X_INS_ABX, inh_hid, inh_hid },
+ { M680X_INS_RTI, inh_hid, inh_hid },
+ { M680X_INS_CWAI, imm8_hid, inh_hid },
+ { M680X_INS_MUL, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_SWI, inh_hid, inh_hid },
+ // 0x4x, Register A instructions
+ { M680X_INS_NEGA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COMA, inh_hid, inh_hid },
+ { M680X_INS_LSRA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORA, inh_hid, inh_hid },
+ { M680X_INS_ASRA, inh_hid, inh_hid },
+ { M680X_INS_LSLA, inh_hid, inh_hid },
+ { M680X_INS_ROLA, inh_hid, inh_hid },
+ { M680X_INS_DECA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCA, inh_hid, inh_hid },
+ { M680X_INS_TSTA, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRA, inh_hid, inh_hid },
+ // 0x5x, Register B instructions
+ { M680X_INS_NEGB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COMB, inh_hid, inh_hid },
+ { M680X_INS_LSRB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_RORB, inh_hid, inh_hid },
+ { M680X_INS_ASRB, inh_hid, inh_hid },
+ { M680X_INS_LSLB, inh_hid, inh_hid },
+ { M680X_INS_ROLB, inh_hid, inh_hid },
+ { M680X_INS_DECB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INCB, inh_hid, inh_hid },
+ { M680X_INS_TSTB, inh_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_CLRB, inh_hid, inh_hid },
+ // 0x6x, indexed instructions
+ { M680X_INS_NEG, idx09_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, idx09_hid, inh_hid },
+ { M680X_INS_LSR, idx09_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, idx09_hid, inh_hid },
+ { M680X_INS_ASR, idx09_hid, inh_hid },
+ { M680X_INS_LSL, idx09_hid, inh_hid },
+ { M680X_INS_ROL, idx09_hid, inh_hid },
+ { M680X_INS_DEC, idx09_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, idx09_hid, inh_hid },
+ { M680X_INS_TST, idx09_hid, inh_hid },
+ { M680X_INS_JMP, idx09_hid, inh_hid },
+ { M680X_INS_CLR, idx09_hid, inh_hid },
+ // 0x7x, extended instructions
+ { M680X_INS_NEG, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_COM, ext_hid, inh_hid },
+ { M680X_INS_LSR, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_ROR, ext_hid, inh_hid },
+ { M680X_INS_ASR, ext_hid, inh_hid },
+ { M680X_INS_LSL, ext_hid, inh_hid },
+ { M680X_INS_ROL, ext_hid, inh_hid },
+ { M680X_INS_DEC, ext_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_INC, ext_hid, inh_hid },
+ { M680X_INS_TST, ext_hid, inh_hid },
+ { M680X_INS_JMP, ext_hid, inh_hid },
+ { M680X_INS_CLR, ext_hid, inh_hid },
+ // 0x8x, immediate instructions with Register A,D,X
+ { M680X_INS_SUBA, imm8_hid, inh_hid },
+ { M680X_INS_CMPA, imm8_hid, inh_hid },
+ { M680X_INS_SBCA, imm8_hid, inh_hid },
+ { M680X_INS_SUBD, imm16_hid, inh_hid },
+ { M680X_INS_ANDA, imm8_hid, inh_hid },
+ { M680X_INS_BITA, imm8_hid, inh_hid },
+ { M680X_INS_LDA, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_EORA, imm8_hid, inh_hid },
+ { M680X_INS_ADCA, imm8_hid, inh_hid },
+ { M680X_INS_ORA, imm8_hid, inh_hid },
+ { M680X_INS_ADDA, imm8_hid, inh_hid },
+ { M680X_INS_CMPX, imm16_hid, inh_hid },
+ { M680X_INS_BSR, rel8_hid, inh_hid },
+ { M680X_INS_LDX, imm16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0x9x, direct instructions with register A,D,X
+ { M680X_INS_SUBA, dir_hid, inh_hid },
+ { M680X_INS_CMPA, dir_hid, inh_hid },
+ { M680X_INS_SBCA, dir_hid, inh_hid },
+ { M680X_INS_SUBD, dir_hid, inh_hid },
+ { M680X_INS_ANDA, dir_hid, inh_hid },
+ { M680X_INS_BITA, dir_hid, inh_hid },
+ { M680X_INS_LDA, dir_hid, inh_hid },
+ { M680X_INS_STA, dir_hid, inh_hid },
+ { M680X_INS_EORA, dir_hid, inh_hid },
+ { M680X_INS_ADCA, dir_hid, inh_hid },
+ { M680X_INS_ORA, dir_hid, inh_hid },
+ { M680X_INS_ADDA, dir_hid, inh_hid },
+ { M680X_INS_CMPX, dir_hid, inh_hid },
+ { M680X_INS_JSR, dir_hid, inh_hid },
+ { M680X_INS_LDX, dir_hid, inh_hid },
+ { M680X_INS_STX, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with Register A,D,X
+ { M680X_INS_SUBA, idx09_hid, inh_hid },
+ { M680X_INS_CMPA, idx09_hid, inh_hid },
+ { M680X_INS_SBCA, idx09_hid, inh_hid },
+ { M680X_INS_SUBD, idx09_hid, inh_hid },
+ { M680X_INS_ANDA, idx09_hid, inh_hid },
+ { M680X_INS_BITA, idx09_hid, inh_hid },
+ { M680X_INS_LDA, idx09_hid, inh_hid },
+ { M680X_INS_STA, idx09_hid, inh_hid },
+ { M680X_INS_EORA, idx09_hid, inh_hid },
+ { M680X_INS_ADCA, idx09_hid, inh_hid },
+ { M680X_INS_ORA, idx09_hid, inh_hid },
+ { M680X_INS_ADDA, idx09_hid, inh_hid },
+ { M680X_INS_CMPX, idx09_hid, inh_hid },
+ { M680X_INS_JSR, idx09_hid, inh_hid },
+ { M680X_INS_LDX, idx09_hid, inh_hid },
+ { M680X_INS_STX, idx09_hid, inh_hid },
+ // 0xBx, extended instructions with register A,D,X
+ { M680X_INS_SUBA, ext_hid, inh_hid },
+ { M680X_INS_CMPA, ext_hid, inh_hid },
+ { M680X_INS_SBCA, ext_hid, inh_hid },
+ { M680X_INS_SUBD, ext_hid, inh_hid },
+ { M680X_INS_ANDA, ext_hid, inh_hid },
+ { M680X_INS_BITA, ext_hid, inh_hid },
+ { M680X_INS_LDA, ext_hid, inh_hid },
+ { M680X_INS_STA, ext_hid, inh_hid },
+ { M680X_INS_EORA, ext_hid, inh_hid },
+ { M680X_INS_ADCA, ext_hid, inh_hid },
+ { M680X_INS_ORA, ext_hid, inh_hid },
+ { M680X_INS_ADDA, ext_hid, inh_hid },
+ { M680X_INS_CMPX, ext_hid, inh_hid },
+ { M680X_INS_JSR, ext_hid, inh_hid },
+ { M680X_INS_LDX, ext_hid, inh_hid },
+ { M680X_INS_STX, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register B,D,U
+ { M680X_INS_SUBB, imm8_hid, inh_hid },
+ { M680X_INS_CMPB, imm8_hid, inh_hid },
+ { M680X_INS_SBCB, imm8_hid, inh_hid },
+ { M680X_INS_ADDD, imm16_hid, inh_hid },
+ { M680X_INS_ANDB, imm8_hid, inh_hid },
+ { M680X_INS_BITB, imm8_hid, inh_hid },
+ { M680X_INS_LDB, imm8_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_EORB, imm8_hid, inh_hid },
+ { M680X_INS_ADCB, imm8_hid, inh_hid },
+ { M680X_INS_ORB, imm8_hid, inh_hid },
+ { M680X_INS_ADDB, imm8_hid, inh_hid },
+ { M680X_INS_LDD, imm16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ { M680X_INS_LDU, imm16_hid, inh_hid },
+ { M680X_INS_ILLGL, illgl_hid, inh_hid },
+ // 0xDx direct instructions with register B,D,U
+ { M680X_INS_SUBB, dir_hid, inh_hid },
+ { M680X_INS_CMPB, dir_hid, inh_hid },
+ { M680X_INS_SBCB, dir_hid, inh_hid },
+ { M680X_INS_ADDD, dir_hid, inh_hid },
+ { M680X_INS_ANDB, dir_hid, inh_hid },
+ { M680X_INS_BITB, dir_hid, inh_hid },
+ { M680X_INS_LDB, dir_hid, inh_hid },
+ { M680X_INS_STB, dir_hid, inh_hid },
+ { M680X_INS_EORB, dir_hid, inh_hid },
+ { M680X_INS_ADCB, dir_hid, inh_hid },
+ { M680X_INS_ORB, dir_hid, inh_hid },
+ { M680X_INS_ADDB, dir_hid, inh_hid },
+ { M680X_INS_LDD, dir_hid, inh_hid },
+ { M680X_INS_STD, dir_hid, inh_hid },
+ { M680X_INS_LDU, dir_hid, inh_hid },
+ { M680X_INS_STU, dir_hid, inh_hid },
+ // 0xEx, indexed instruction with register B,D,U
+ { M680X_INS_SUBB, idx09_hid, inh_hid },
+ { M680X_INS_CMPB, idx09_hid, inh_hid },
+ { M680X_INS_SBCB, idx09_hid, inh_hid },
+ { M680X_INS_ADDD, idx09_hid, inh_hid },
+ { M680X_INS_ANDB, idx09_hid, inh_hid },
+ { M680X_INS_BITB, idx09_hid, inh_hid },
+ { M680X_INS_LDB, idx09_hid, inh_hid },
+ { M680X_INS_STB, idx09_hid, inh_hid },
+ { M680X_INS_EORB, idx09_hid, inh_hid },
+ { M680X_INS_ADCB, idx09_hid, inh_hid },
+ { M680X_INS_ORB, idx09_hid, inh_hid },
+ { M680X_INS_ADDB, idx09_hid, inh_hid },
+ { M680X_INS_LDD, idx09_hid, inh_hid },
+ { M680X_INS_STD, idx09_hid, inh_hid },
+ { M680X_INS_LDU, idx09_hid, inh_hid },
+ { M680X_INS_STU, idx09_hid, inh_hid },
+ // 0xFx, extended instructions with register B,D,U
+ { M680X_INS_SUBB, ext_hid, inh_hid },
+ { M680X_INS_CMPB, ext_hid, inh_hid },
+ { M680X_INS_SBCB, ext_hid, inh_hid },
+ { M680X_INS_ADDD, ext_hid, inh_hid },
+ { M680X_INS_ANDB, ext_hid, inh_hid },
+ { M680X_INS_BITB, ext_hid, inh_hid },
+ { M680X_INS_LDB, ext_hid, inh_hid },
+ { M680X_INS_STB, ext_hid, inh_hid },
+ { M680X_INS_EORB, ext_hid, inh_hid },
+ { M680X_INS_ADCB, ext_hid, inh_hid },
+ { M680X_INS_ORB, ext_hid, inh_hid },
+ { M680X_INS_ADDB, ext_hid, inh_hid },
+ { M680X_INS_LDD, ext_hid, inh_hid },
+ { M680X_INS_STD, ext_hid, inh_hid },
+ { M680X_INS_LDU, ext_hid, inh_hid },
+ { M680X_INS_STU, ext_hid, inh_hid },
+};
+
+// The following array has to be sorted by increasing
+// opcodes. Otherwise the binary_search will fail.
+//
+// M6809 PAGE2 instructions (with prefix 0x10)
+static const inst_pageX g_m6809_inst_page2_table[] = {
+ // 0x2x, relative long branch instructions
+ { 0x21, M680X_INS_LBRN, rel16_hid, inh_hid },
+ { 0x22, M680X_INS_LBHI, rel16_hid, inh_hid },
+ { 0x23, M680X_INS_LBLS, rel16_hid, inh_hid },
+ { 0x24, M680X_INS_LBCC, rel16_hid, inh_hid },
+ { 0x25, M680X_INS_LBCS, rel16_hid, inh_hid },
+ { 0x26, M680X_INS_LBNE, rel16_hid, inh_hid },
+ { 0x27, M680X_INS_LBEQ, rel16_hid, inh_hid },
+ { 0x28, M680X_INS_LBVC, rel16_hid, inh_hid },
+ { 0x29, M680X_INS_LBVS, rel16_hid, inh_hid },
+ { 0x2a, M680X_INS_LBPL, rel16_hid, inh_hid },
+ { 0x2b, M680X_INS_LBMI, rel16_hid, inh_hid },
+ { 0x2c, M680X_INS_LBGE, rel16_hid, inh_hid },
+ { 0x2d, M680X_INS_LBLT, rel16_hid, inh_hid },
+ { 0x2e, M680X_INS_LBGT, rel16_hid, inh_hid },
+ { 0x2f, M680X_INS_LBLE, rel16_hid, inh_hid },
+ // 0x3x
+ { 0x3f, M680X_INS_SWI2, inh_hid, inh_hid },
+ // 0x8x, immediate instructions with register D,Y
+ { 0x83, M680X_INS_CMPD, imm16_hid, inh_hid },
+ { 0x8c, M680X_INS_CMPY, imm16_hid, inh_hid },
+ { 0x8e, M680X_INS_LDY, imm16_hid, inh_hid },
+ // 0x9x, direct instructions with register D,Y
+ { 0x93, M680X_INS_CMPD, dir_hid, inh_hid },
+ { 0x9c, M680X_INS_CMPY, dir_hid, inh_hid },
+ { 0x9e, M680X_INS_LDY, dir_hid, inh_hid },
+ { 0x9f, M680X_INS_STY, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with register D,Y
+ { 0xa3, M680X_INS_CMPD, idx09_hid, inh_hid },
+ { 0xac, M680X_INS_CMPY, idx09_hid, inh_hid },
+ { 0xae, M680X_INS_LDY, idx09_hid, inh_hid },
+ { 0xaf, M680X_INS_STY, idx09_hid, inh_hid },
+ // 0xBx, extended instructions with register D,Y
+ { 0xb3, M680X_INS_CMPD, ext_hid, inh_hid },
+ { 0xbc, M680X_INS_CMPY, ext_hid, inh_hid },
+ { 0xbe, M680X_INS_LDY, ext_hid, inh_hid },
+ { 0xbf, M680X_INS_STY, ext_hid, inh_hid },
+ // 0xCx, immediate instructions with register S
+ { 0xce, M680X_INS_LDS, imm16_hid, inh_hid },
+ // 0xDx, direct instructions with register S
+ { 0xde, M680X_INS_LDS, dir_hid, inh_hid },
+ { 0xdf, M680X_INS_STS, dir_hid, inh_hid },
+ // 0xEx, indexed instructions with register S
+ { 0xee, M680X_INS_LDS, idx09_hid, inh_hid },
+ { 0xef, M680X_INS_STS, idx09_hid, inh_hid },
+ // 0xFx, extended instructions with register S
+ { 0xfe, M680X_INS_LDS, ext_hid, inh_hid },
+ { 0xff, M680X_INS_STS, ext_hid, inh_hid },
+};
+
+// The following array has to be sorted by increasing
+// opcodes. Otherwise the binary_search will fail.
+//
+// M6809 PAGE3 instructions (with prefix 0x11)
+static const inst_pageX g_m6809_inst_page3_table[] = {
+ { 0x3f, M680X_INS_SWI3, inh_hid, inh_hid },
+ // 0x8x, immediate instructions with register U,S
+ { 0x83, M680X_INS_CMPU, imm16_hid, inh_hid },
+ { 0x8c, M680X_INS_CMPS, imm16_hid, inh_hid },
+ // 0x9x, direct instructions with register U,S
+ { 0x93, M680X_INS_CMPU, dir_hid, inh_hid },
+ { 0x9c, M680X_INS_CMPS, dir_hid, inh_hid },
+ // 0xAx, indexed instructions with register U,S
+ { 0xa3, M680X_INS_CMPU, idx09_hid, inh_hid },
+ { 0xac, M680X_INS_CMPS, idx09_hid, inh_hid },
+ // 0xBx, extended instructions with register U,S
+ { 0xb3, M680X_INS_CMPU, ext_hid, inh_hid },
+ { 0xbc, M680X_INS_CMPS, ext_hid, inh_hid },
+};
+
diff --git a/capstone/arch/M680X/m6811.inc b/capstone/arch/M680X/m6811.inc
new file mode 100644
index 000000000..f26fb2c4b
--- /dev/null
+++ b/capstone/arch/M680X/m6811.inc
@@ -0,0 +1,105 @@
+
+// Additional instructions only supported on M68HC11
+static const inst_pageX g_m6811_inst_overlay_table[] = {
+ { 0x00, M680X_INS_TEST, inh_hid, inh_hid },
+ { 0x02, M680X_INS_IDIV, inh_hid, inh_hid },
+ { 0x03, M680X_INS_FDIV, inh_hid, inh_hid },
+ { 0x12, M680X_INS_BRSET, dir_hid, imm8rel_hid },
+ { 0x13, M680X_INS_BRCLR, dir_hid, imm8rel_hid },
+ { 0x14, M680X_INS_BSET, dir_hid, imm8_hid },
+ { 0x15, M680X_INS_BCLR, dir_hid, imm8_hid },
+ { 0x1c, M680X_INS_BSET, idxX_hid, imm8_hid },
+ { 0x1d, M680X_INS_BCLR, idxX_hid, imm8_hid },
+ { 0x1e, M680X_INS_BRSET, idxX_hid, imm8rel_hid },
+ { 0x1f, M680X_INS_BRCLR, idxX_hid, imm8rel_hid },
+ { 0x8f, M680X_INS_XGDX, inh_hid, inh_hid },
+ { 0xcf, M680X_INS_STOP, inh_hid, inh_hid },
+};
+
+// M68HC11 PAGE2 instructions
+static const inst_pageX g_m6811_inst_page2_table[] = {
+ { 0x08, M680X_INS_INY, inh_hid, inh_hid },
+ { 0x09, M680X_INS_DEY, inh_hid, inh_hid },
+ { 0x1c, M680X_INS_BSET, idxY_hid, imm8_hid },
+ { 0x1d, M680X_INS_BCLR, idxY_hid, imm8_hid },
+ { 0x1e, M680X_INS_BRSET, idxY_hid, imm8rel_hid },
+ { 0x1f, M680X_INS_BRCLR, idxY_hid, imm8rel_hid },
+ { 0x30, M680X_INS_TSY, inh_hid, inh_hid },
+ { 0x35, M680X_INS_TYS, inh_hid, inh_hid },
+ { 0x38, M680X_INS_PULY, inh_hid, inh_hid },
+ { 0x3a, M680X_INS_ABY, inh_hid, inh_hid },
+ { 0x3c, M680X_INS_PSHY, inh_hid, inh_hid },
+ { 0x60, M680X_INS_NEG, idxY_hid, inh_hid },
+ { 0x63, M680X_INS_COM, idxY_hid, inh_hid },
+ { 0x64, M680X_INS_LSR, idxY_hid, inh_hid },
+ { 0x66, M680X_INS_ROR, idxY_hid, inh_hid },
+ { 0x67, M680X_INS_ASR, idxY_hid, inh_hid },
+ { 0x68, M680X_INS_ASL, idxY_hid, inh_hid },
+ { 0x69, M680X_INS_ROL, idxY_hid, inh_hid },
+ { 0x6a, M680X_INS_DEC, idxY_hid, inh_hid },
+ { 0x6c, M680X_INS_INC, idxY_hid, inh_hid },
+ { 0x6d, M680X_INS_TST, idxY_hid, inh_hid },
+ { 0x6e, M680X_INS_JMP, idxY_hid, inh_hid },
+ { 0x6f, M680X_INS_CLR, idxY_hid, inh_hid },
+ { 0x8c, M680X_INS_CPY, imm16_hid, inh_hid },
+ { 0x8f, M680X_INS_XGDY, inh_hid, inh_hid },
+ { 0x9c, M680X_INS_CPY, dir_hid, inh_hid },
+ { 0xa0, M680X_INS_SUBA, idxY_hid, inh_hid },
+ { 0xa1, M680X_INS_CMPA, idxY_hid, inh_hid },
+ { 0xa2, M680X_INS_SBCA, idxY_hid, inh_hid },
+ { 0xa3, M680X_INS_SUBD, idxY_hid, inh_hid },
+ { 0xa4, M680X_INS_ANDA, idxY_hid, inh_hid },
+ { 0xa5, M680X_INS_BITA, idxY_hid, inh_hid },
+ { 0xa6, M680X_INS_LDAA, idxY_hid, inh_hid },
+ { 0xa7, M680X_INS_STAA, idxY_hid, inh_hid },
+ { 0xa8, M680X_INS_EORA, idxY_hid, inh_hid },
+ { 0xa9, M680X_INS_ADCA, idxY_hid, inh_hid },
+ { 0xaa, M680X_INS_ORAA, idxY_hid, inh_hid },
+ { 0xab, M680X_INS_ADDA, idxY_hid, inh_hid },
+ { 0xac, M680X_INS_CPY, idxY_hid, inh_hid },
+ { 0xad, M680X_INS_JSR, idxY_hid, inh_hid },
+ { 0xae, M680X_INS_LDS, idxY_hid, inh_hid },
+ { 0xaf, M680X_INS_STS, idxY_hid, inh_hid },
+ { 0xbc, M680X_INS_CPY, ext_hid, inh_hid },
+ { 0xce, M680X_INS_LDY, imm16_hid, inh_hid },
+ { 0xde, M680X_INS_LDY, dir_hid, inh_hid },
+ { 0xdf, M680X_INS_STY, dir_hid, inh_hid },
+ { 0xe0, M680X_INS_SUBB, idxY_hid, inh_hid },
+ { 0xe1, M680X_INS_CMPB, idxY_hid, inh_hid },
+ { 0xe2, M680X_INS_SBCB, idxY_hid, inh_hid },
+ { 0xe3, M680X_INS_ADDD, idxY_hid, inh_hid },
+ { 0xe4, M680X_INS_ANDB, idxY_hid, inh_hid },
+ { 0xe5, M680X_INS_BITB, idxY_hid, inh_hid },
+ { 0xe6, M680X_INS_LDAB, idxY_hid, inh_hid },
+ { 0xe7, M680X_INS_STAB, idxY_hid, inh_hid },
+ { 0xe8, M680X_INS_EORB, idxY_hid, inh_hid },
+ { 0xe9, M680X_INS_ADCB, idxY_hid, inh_hid },
+ { 0xea, M680X_INS_ORAB, idxY_hid, inh_hid },
+ { 0xeb, M680X_INS_ADDB, idxY_hid, inh_hid },
+ { 0xec, M680X_INS_LDD, idxY_hid, inh_hid },
+ { 0xed, M680X_INS_STD, idxY_hid, inh_hid },
+ { 0xee, M680X_INS_LDY, idxY_hid, inh_hid },
+ { 0xef, M680X_INS_STY, idxY_hid, inh_hid },
+ { 0xfe, M680X_INS_LDY, ext_hid, inh_hid },
+ { 0xff, M680X_INS_STY, ext_hid, inh_hid },
+};
+
+// M68HC11 PAGE3 instructions
+static const inst_pageX g_m6811_inst_page3_table[] = {
+ { 0x83, M680X_INS_CPD, imm16_hid, inh_hid },
+ { 0x93, M680X_INS_CPD, dir_hid, inh_hid },
+ { 0xa3, M680X_INS_CPD, idxX_hid, inh_hid },
+ { 0xac, M680X_INS_CPY, idxX_hid, inh_hid },
+ { 0xb3, M680X_INS_CPD, ext_hid, inh_hid },
+ { 0xee, M680X_INS_LDY, idxX_hid, inh_hid },
+ { 0xef, M680X_INS_STY, idxX_hid, inh_hid },
+};
+
+// M68HC11 PAGE4 instructions
+static const inst_pageX g_m6811_inst_page4_table[] = {
+ { 0xa3, M680X_INS_CPD, idxY_hid, inh_hid },
+ { 0xac, M680X_INS_CPX, idxY_hid, inh_hid },
+ { 0xee, M680X_INS_LDX, idxY_hid, inh_hid },
+ { 0xef, M680X_INS_STX, idxY_hid, inh_hid },
+};
+