diff options
Diffstat (limited to 'capstone/arch/M680X')
-rw-r--r-- | capstone/arch/M680X/M680XDisassembler.c | 2318 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XDisassembler.h | 17 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XDisassemblerInternals.h | 57 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XInstPrinter.c | 360 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XInstPrinter.h | 25 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XModule.c | 77 | ||||
-rw-r--r-- | capstone/arch/M680X/M680XModule.h | 12 | ||||
-rw-r--r-- | capstone/arch/M680X/cpu12.inc | 335 | ||||
-rw-r--r-- | capstone/arch/M680X/hcs08.inc | 60 | ||||
-rw-r--r-- | capstone/arch/M680X/hd6301.inc | 15 | ||||
-rw-r--r-- | capstone/arch/M680X/hd6309.inc | 259 | ||||
-rw-r--r-- | capstone/arch/M680X/insn_props.inc | 367 | ||||
-rw-r--r-- | capstone/arch/M680X/m6800.inc | 277 | ||||
-rw-r--r-- | capstone/arch/M680X/m6801.inc | 39 | ||||
-rw-r--r-- | capstone/arch/M680X/m6805.inc | 277 | ||||
-rw-r--r-- | capstone/arch/M680X/m6808.inc | 91 | ||||
-rw-r--r-- | capstone/arch/M680X/m6809.inc | 352 | ||||
-rw-r--r-- | capstone/arch/M680X/m6811.inc | 105 |
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, ®_bits, (*address)++); + + switch (op0->reg) { + case M680X_REG_U: + reg_to_reg_ids = ®_u_reg_ids[0]; + break; + + case M680X_REG_S: + reg_to_reg_ids = ®_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, ®s, (*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, ®s, (*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, ®s, *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 }, +}; + |