#include "enums.h"
#include <stdint.h>
#include <stdlib.h>
#define OPNUM 74
#define EXT_OPNUM 49
#define ORTHO_OPNUM 16
#define ORTHO_EXT EIND+1
typedef struct inst instruction;
typedef struct inst_id instruction_id;
typedef struct opts options;
struct inst {
uint32_t am;
uint8_t op;
};
struct inst_id {
int ext;
int id;
};
struct opts {
uint32_t addr_modes;
instruction_id *instr;
int ext;
};
enum extensions {
BASE,
EXT,
ORTHO,
EXT_LEN
};
enum addrmode_type {
AMT_IMM,
AMT_ZM,
AMT_ZMX,
AMT_ZMY,
AMT_IND,
AMT_INDX,
AMT_INDY,
AMT_ABS,
AMT_REL,
AMT_BREG,
AMT_IMPL,
AMT_INDX2,
AMT_ZM2,
AMT_EIND,
AMT_EIND2,
AMT_ABY,
AMT_ABX,
AMT_AIND,
AMT_AINDY,
AMT_AINDX,
AMT_ORTHO,
AMT_ORTHO2,
AMT_LEN
};
enum addrmode {
AM_IMM = (1 << 0),
AM_ZM = (1 << 1),
AM_ZMX = (1 << 2),
AM_ZMY = (1 << 3),
AM_IND = (1 << 4),
AM_INDX = (1 << 5),
AM_INDY = (1 << 6),
AM_ABS = (1 << 7),
AM_REL = (1 << 8),
AM_BREG = (1 << 9),
AM_IMPL = (1 << 10),
AM_INDX2 = (1 << 11),
AM_ZM2 = (1 << 12),
AM_EIND = (1 << 13),
AM_EIND2 = (1 << 14),
AM_ABY = (1 << 15),
AM_ABX = (1 << 16),
AM_AIND = (1 << 17),
AM_AINDY = (1 << 18),
AM_AINDX = (1 << 19),
AM_ORTHO = (1 << 20),
AM_ORTHO2 = (1 << 21),
AM_LEN = (1 << 22)
};
enum ind {
CMP_IND = 0,
CMP_IDY = 1,
CMP_IDX = 2,
CPB_IND = 3,
CPB_IDY = 4,
CPB_IDX = 5,
JMP_IND = 6,
JSR_IND = 7,
LDA_IND = 8,
LDA_IDY = 9,
LDB_IND = 10,
LDB_IDY = 11,
LDX_IND = 12,
LDY_IND = 13,
STA_IND = 14,
STA_IDY = 15,
STB_IND = 16,
STB_IDY = 17,
STX_IND = 18,
STY_IND = 19
};
enum eind {
DEC_EIND,
INC_EIND,
STY_EIND,
STA_EIND,
STB_EIND,
LDX_EIND,
STX_EIND,
CPB_EIND,
CPX_EIND,
CPY_EIND
};
enum baseext_ortho {
OP_LEA,
OP_PEA,
OP_ADD,
OP_SUB,
OP_NOT,
OP_CLZ,
OP_CLO,
OP_SWP,
OP_PCN
};
static const char *ext_names[EXT_LEN] = {
[BASE ] = "base",
[EXT ] = "ext",
[ORTHO] = "ortho"
};
static const char *adrmode[AMT_LEN] = {
[AMT_IMM ] = "IMM",
[AMT_ZM ] = "ZM",
[AMT_ZMX ] = "ZMX",
[AMT_ZMY ] = "ZMY",
[AMT_IND ] = "IND",
[AMT_INDX ] = "INDX",
[AMT_INDY ] = "INDY",
[AMT_ABS ] = "ABS",
[AMT_REL ] = "REL",
[AMT_BREG ] = "BREG",
[AMT_IMPL ] = "IMPL",
[AMT_INDX2 ] = "INDX",
[AMT_ZM2 ] = "ZM",
[AMT_EIND ] = "EIND",
[AMT_EIND2 ] = "EIND",
[AMT_ABY ] = "ABSY",
[AMT_ABX ] = "ABSX",
[AMT_AIND ] = "AIND",
[AMT_AINDY ] = "AINDY",
[AMT_AINDX ] = "AINDX",
[AMT_ORTHO ] = "ORTHO",
[AMT_ORTHO2] = "ORTHO"
};
static const char *mne[] = {
[ADC] = "ADC",
[AND] = "AND",
[ASR] = "ASR",
[BCC] = "BCC",
[BCS] = "BCS",
[BEQ] = "BEQ",
[BNE] = "BNE",
[BNG] = "BNG",
[BPO] = "BPO",
[BRA] = "BRA",
[BRK] = "BRK",
[BVC] = "BVC",
[BVS] = "BVS",
[CLC] = "CLC",
[CLI] = "CLI",
[CLV] = "CLV",
[CMP] = "CMP",
[CPB] = "CPB",
[CPS] = "CPS",
[CPX] = "CPX",
[CPY] = "CPY",
[DEB] = "DEB",
[DEC] = "DEC",
[DEX] = "DEX",
[DEY] = "DEY",
[DIV] = "DIV",
[INB] = "INB",
[INC] = "INC",
[INX] = "INX",
[INY] = "INY",
[JMP] = "JMP",
[JSR] = "JSR",
[LDA] = "LDA",
[LDB] = "LDB",
[LDX] = "LDX",
[LDY] = "LDY",
[LSL] = "LSL",
[LSR] = "LSR",
[MUL] = "MUL",
[NOP] = "NOP",
[ORA] = "ORA",
[PHA] = "PHA",
[PHB] = "PHB",
[PHP] = "PHP",
[PHX] = "PHX",
[PHY] = "PHY",
[PLA] = "PLA",
[PLB] = "PLB",
[PLP] = "PLP",
[PLX] = "PLX",
[PLY] = "PLY",
[ROL] = "ROL",
[ROR] = "ROR",
[RTI] = "RTI",
[RTS] = "RTS",
[SBC] = "SBC",
[SEC] = "SEC",
[SEI] = "SEI",
[STA] = "STA",
[STB] = "STB",
[STX] = "STX",
[STY] = "STY",
[TAB] = "TAB",
[TAX] = "TAX",
[TAY] = "TAY",
[TBA] = "TBA",
[TSX] = "TSX",
[TXA] = "TXA",
[TXS] = "TXS",
[TXY] = "TXY",
[TYA] = "TYA",
[TYX] = "TYX",
[WAI] = "WAI",
[XOR] = "XOR",
NULL
};
static const char *ext_mne[] = {
[LEA] = "LEA",
[PEA] = "PEA",
[ADD] = "ADD",
[SUB] = "SUB",
[ADE] = "ADE",
[SBE] = "SBE",
[ADS] = "ADS",
[SBS] = "SBS",
[NOT] = "NOT",
[LLM] = "LLM",
[LRM] = "LRM",
[RLM] = "RLM",
[RRM] = "RRM",
[ARM] = "ARM",
[PHE] = "PHE",
[PLE] = "PLE",
[CPE] = "CPE",
[ICE] = "ICE",
[LDS] = "LDS",
[DEE] = "DEE",
[INE] = "INE",
[DES] = "DES",
[INS] = "INS",
[STS] = "STS",
[STE] = "STE",
[STZ] = "STZ",
[SCO] = "SCO",
[ECO] = "ECO",
[CLZ] = "CLZ",
[CLO] = "CLO",
[BIT] = "BIT",
[MMV] = "MMV",
[SWP] = "SWP",
[PCN] = "PCN",
[REP] = "REP",
[REQ] = "REQ",
[RNE] = "RNE",
[LNG] = "LNG",
[LPO] = "LPO",
[LCS] = "LCS",
[LCC] = "LCC",
[LEQ] = "LEQ",
[LNE] = "LNE",
[SNG] = "SNG",
[SPO] = "SPO",
[SCS] = "SCS",
[SCC] = "SCC",
[SEQ] = "SEQ",
[SNE] = "SNE",
NULL
};
static const char *ortho_mne[] = {
[MNG] = "MNG",
[MPO] = "MPO",
[MCS] = "MCS",
[MCC] = "MCC",
[MEQ] = "MEQ",
[MNE] = "MNE",
[MVS] = "MVS",
[MVC] = "MVC",
[OR ] = "OR",
[MOV] = "MOV",
[IML] = "IML",
[IDV] = "IDV",
[PSH] = "PSH",
[PUL] = "PUL",
[NEG] = "NEG",
[SET] = "SET",
NULL
};
static const char *set_cc[] = {
"NG",
"PO",
"CS",
"CC",
"EQ",
"NE",
"VS",
"VC",
NULL
};
static const int addr_mode_type[AMT_LEN] = {
[AMT_IMM ] = IMM,
[AMT_ZM ] = ZM,
[AMT_ZMX ] = ZMX,
[AMT_ZMY ] = ZMY,
[AMT_IND ] = IND,
[AMT_INDX ] = INDX,
[AMT_INDY ] = INDY,
[AMT_ABS ] = ABS,
[AMT_REL ] = REL,
[AMT_BREG ] = BREG,
[AMT_IMPL ] = IMPL,
[AMT_INDX2 ] = INDX,
[AMT_ZM2 ] = ZM,
[AMT_EIND ] = EIND,
[AMT_EIND2 ] = EIND,
[AMT_ABY ] = ABSY,
[AMT_ABX ] = ABSX,
[AMT_AIND ] = AIND,
[AMT_AINDY ] = AINDY,
[AMT_AINDX ] = AINDX,
[AMT_ORTHO ] = ORTHO_EXT,
[AMT_ORTHO2] = ORTHO_EXT
};
static const uint8_t ext_ortho_ops[9] = {
[OP_LEA] = 0x63,
[OP_PEA] = 0x4C,
[OP_ADD] = 0x03,
[OP_SUB] = 0x23,
[OP_NOT] = 0x44,
[OP_CLZ] = 0xC4,
[OP_CLO] = 0xE4,
[OP_SWP] = 0x6C,
[OP_PCN] = 0x43
};
static const uint8_t ind_ops[20] = {
[CMP_IND] = CMP_IN,
[CMP_IDY] = CMP_IY,
[CMP_IDX] = CMP_IX,
[CPB_IND] = CPB_IN,
[CPB_IDY] = CPB_IY,
[CPB_IDX] = CPB_IX,
[JMP_IND] = JMP_IN,
[JSR_IND] = JSR_IN,
[LDA_IND] = LDA_IN,
[LDA_IDY] = LDA_IY,
[LDB_IND] = LDB_IN,
[LDB_IDY] = LDB_IY,
[LDX_IND] = LDX_IN,
[LDY_IND] = LDY_IN,
[STA_IND] = STA_IN,
[STA_IDY] = STA_IY,
[STB_IND] = STB_IN,
[STB_IDY] = STB_IY,
[STX_IND] = STX_IN,
[STY_IND] = STY_IN
};
static const uint8_t eind_base_ops[10] = {
[DEC_EIND] = DEC_E,
[INC_EIND] = INC_E,
[STY_EIND] = STY_E,
[STA_EIND] = STA_E,
[STB_EIND] = STB_E,
[LDX_EIND] = LDX_E,
[STX_EIND] = STX_E,
[CPB_EIND] = CPB_E,
[CPX_EIND] = CPX_E,
[CPY_EIND] = CPY_E
};
static const instruction inst[OPNUM] = {
[ADC] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x01},
[AND] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x41},
[ASR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x62},
[BCC] = {(AM_REL), 0xA0},
[BCS] = {(AM_REL), 0x90},
[BEQ] = {(AM_REL), 0xB0},
[BNE] = {(AM_REL), 0xC0},
[BNG] = {(AM_REL), 0x80},
[BPO] = {(AM_REL), 0x70},
[BRA] = {(AM_REL), 0xF0},
[BRK] = {(AM_IMPL), 0x69},
[BVC] = {(AM_REL), 0xE0},
[BVS] = {(AM_REL), 0xD0},
[CLC] = {(AM_IMPL), 0x09},
[CLI] = {(AM_IMPL), 0x29},
[CLV] = {(AM_IMPL), 0x49},
[CMP] = {(AM_IMM|AM_ZM|AM_IND|AM_INDY|AM_ABS|AM_BREG|AM_INDX2|AM_EIND|AM_ORTHO), 0x82},
[CPB] = {(AM_IMM|AM_ZM|AM_IND|AM_INDY|AM_ABS|AM_INDX2|AM_EIND2), 0x04},
[CPS] = {(AM_IMPL), 0x00},
[CPX] = {(AM_IMM|AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x24},
[CPY] = {(AM_IMM|AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x44},
[DEB] = {(AM_IMPL), 0x99},
[DEC] = {(AM_IMPL|AM_ZM|AM_ABS|AM_EIND2|AM_ORTHO2), 0x84},
[DEX] = {(AM_IMPL), 0xB9},
[DEY] = {(AM_IMPL), 0x79},
[DIV] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x42},
[INB] = {(AM_IMPL), 0xA9},
[INC] = {(AM_IMPL|AM_ZM|AM_ABS|AM_EIND2|AM_ORTHO2), 0xA4},
[INX] = {(AM_IMPL), 0xC9},
[INY] = {(AM_IMPL), 0x89},
[JMP] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND|AM_ORTHO|AM_ORTHO2), 0x00},
[JSR] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND|AM_ORTHO|AM_ORTHO2), 0x20},
[LDA] = {(AM_IMM|AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND), 0xC2},
[LDB] = {(AM_IMM|AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND), 0xE2},
[LDX] = {(AM_IMM|AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x64},
[LDY] = {(AM_IMM|AM_ZM|AM_IND|AM_ABS|AM_EIND), 0xA2},
[LSL] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0xA1},
[LSR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0xC1},
[MUL] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x22},
[NOP] = {(AM_IMPL), 0xEA},
[ORA] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x61},
[PHA] = {(AM_IMPL), 0x8E},
[PHB] = {(AM_IMPL), 0xAE},
[PHP] = {(AM_IMPL), 0x6E},
[PHX] = {(AM_IMPL), 0xEE},
[PHY] = {(AM_IMPL), 0xCE},
[PLA] = {(AM_IMPL), 0x9E},
[PLB] = {(AM_IMPL), 0xBE},
[PLP] = {(AM_IMPL), 0x7E},
[PLX] = {(AM_IMPL), 0xFE},
[PLY] = {(AM_IMPL), 0xDE},
[ROL] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0xE1},
[ROR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x02},
[RTI] = {(AM_IMPL), 0x60},
[RTS] = {(AM_IMPL), 0x50},
[SBC] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x21},
[SEC] = {(AM_IMPL), 0x19},
[SEI] = {(AM_IMPL), 0x39},
[STA] = {(AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND2), 0x28},
[STB] = {(AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND2), 0x48},
[STX] = {(AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x68},
[STY] = {(AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x08},
[TAB] = {(AM_IMPL), 0x0A},
[TAX] = {(AM_IMPL), 0x4A},
[TAY] = {(AM_IMPL), 0x2A},
[TBA] = {(AM_IMPL), 0x1A},
[TSX] = {(AM_IMPL), 0x8A},
[TXA] = {(AM_IMPL), 0x5A},
[TXS] = {(AM_IMPL), 0x9A},
[TXY] = {(AM_IMPL), 0x7A},
[TYA] = {(AM_IMPL), 0x3A},
[TYX] = {(AM_IMPL), 0x6A},
[WAI] = {(AM_IMPL), 0x59},
[XOR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND|AM_ORTHO), 0x81}
};
static const instruction ext_inst[EXT_OPNUM] = {
[LEA] = {(AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_ABX|AM_ABY|AM_AIND|AM_AINDX|AM_AINDY|AM_ORTHO), 0x03},
[PEA] = {(AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_ABX|AM_ABY|AM_AIND|AM_AINDX|AM_AINDY|AM_ORTHO2), 0x23},
[ADD] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND|AM_ORTHO), 0x06},
[SUB] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND|AM_ORTHO), 0x26},
[ADE] = {(AM_IMM|AM_ZM|AM_ABS), 0x46},
[SBE] = {(AM_IMM|AM_ZM|AM_ABS), 0x66},
[ADS] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x86},
[SBS] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0xA6},
[NOT] = {(AM_IMPL|AM_ZM|AM_ABS|AM_EIND|AM_ORTHO2), 0xC6},
[LLM] = {(AM_ZM|AM_ABS|AM_EIND), 0x48},
[LRM] = {(AM_ZM|AM_ABS|AM_EIND), 0x68},
[RLM] = {(AM_ZM|AM_ABS|AM_EIND), 0x88},
[RRM] = {(AM_ZM|AM_ABS|AM_EIND), 0xA8},
[ARM] = {(AM_ZM|AM_ABS|AM_EIND), 0xC8},
[PHE] = {(AM_IMPL), 0x6B},
[PLE] = {(AM_IMPL), 0x7B},
[CPE] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x08},
[ICE] = {(AM_ZM|AM_ABS|AM_EIND), 0x28},
[LDS] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x40},
[DEE] = {(AM_IMPL), 0x8B},
[INE] = {(AM_IMPL), 0x9B},
[DES] = {(AM_IMPL), 0xAB},
[INS] = {(AM_IMPL), 0xBB},
[STS] = {(AM_ZM|AM_ABS|AM_EIND), 0xA0},
[STE] = {(AM_ZM|AM_ABS), 0xC0},
[STZ] = {(AM_ZM|AM_ABS|AM_EIND), 0xE0},
[SCO] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x60},
[ECO] = {(AM_ZM|AM_ABS|AM_EIND), 0x80},
[CLZ] = {(AM_ZM|AM_ABS|AM_EIND|AM_ORTHO2), 0x05},
[CLO] = {(AM_ZM|AM_ABS|AM_EIND|AM_ORTHO2), 0x25},
[BIT] = {(AM_ZM|AM_ABS|AM_EIND), 0x45},
[MMV] = {(AM_IMPL), 0xCB},
[SWP] = {(AM_IMPL|AM_ZM|AM_ABS|AM_EIND|AM_ORTHO2), 0xE6},
[PCN] = {(AM_ZM|AM_ABS|AM_EIND|AM_ORTHO), 0xE8},
[REP] = {(AM_REL), 0xBD},
[REQ] = {(AM_REL), 0xCD},
[RNE] = {(AM_REL), 0xDD},
[LNG] = {(AM_IMM|AM_EIND2), 0x0D},
[LPO] = {(AM_IMM|AM_EIND2), 0x2D},
[LCS] = {(AM_IMM|AM_EIND2), 0x4D},
[LCC] = {(AM_IMM|AM_EIND2), 0x6D},
[LEQ] = {(AM_IMM|AM_EIND2), 0x8D},
[LNE] = {(AM_IMM|AM_EIND2), 0xAD},
[SNG] = {(AM_EIND2), 0x1D},
[SPO] = {(AM_EIND2), 0x3D},
[SCS] = {(AM_EIND2), 0x5D},
[SCC] = {(AM_EIND2), 0x7D},
[SEQ] = {(AM_EIND2), 0x9D},
[SNE] = {(AM_EIND2), 0xBD}
};
static const instruction ortho_inst[ORTHO_OPNUM] = {
[MNG] = {(AM_ORTHO), 0x00},
[MPO] = {(AM_ORTHO), 0x20},
[MCS] = {(AM_ORTHO), 0x40},
[MCC] = {(AM_ORTHO), 0x60},
[MEQ] = {(AM_ORTHO), 0x80},
[MNE] = {(AM_ORTHO), 0xA0},
[MVS] = {(AM_ORTHO), 0xC0},
[MVC] = {(AM_ORTHO), 0xE0},
[OR ] = {(AM_ORTHO), 0x61},
[MOV] = {(AM_ORTHO), 0xA2},
[IML] = {(AM_ORTHO), 0xC2},
[IDV] = {(AM_ORTHO), 0xE2},
[PSH] = {(AM_ORTHO2), 0x04},
[PUL] = {(AM_ORTHO2), 0x24},
[NEG] = {(AM_ORTHO2), 0x64},
[SET] = {(AM_ORTHO2), 0x05}
};