#include "enums.h" #include #include #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; /* Addressing modes. */ uint8_t op; /* Base value used to get the actual opcode. */ }; 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} };