#include "opcode.h" #include #include #define MAX_TOK 0x1000 typedef struct tok token; typedef struct ln line; typedef struct sym symbol; typedef struct fix fixup; typedef struct inst instruction; typedef struct expr expr; typedef struct strln strln; struct tok { token *next; /* Pointer to the next token. */ uint8_t id; /* Token ID. */ uint8_t type; /* Token type ID. */ uint8_t subtype; /* Token subtype ID. */ uint8_t tab; /* Number of tabs. */ uint8_t space; /* Number of spaces. */ uint8_t subtab; /* Number of sub-token tabs. */ uint8_t subspace; /* Number of sub-token spaces. */ uint8_t digits; /* Number of digits. */ /* Token value(s). */ union { expr *expr; symbol *sym; char *str; uint8_t byte ; uint16_t word ; uint32_t dword; uint64_t qword; }; }; struct ln { line *next; /* Pointer to the next line. */ token *tok; /* The token(s) for this line. */ uint16_t count; /* Total tokens for this line. */ uint16_t bline; /* Number of blank lines. */ uint32_t linenum; /* Line number. */ uint64_t addr; /* The address of this line. */ }; struct fix { fixup *next; symbol *s; token *t; uint64_t adr; }; struct sym { symbol *next; symbol *prev; symbol *down; symbol *up; int depth; uint16_t count; uint64_t val; uint8_t isstruct : 1; uint8_t isanon : 1; uint8_t def : 1; char *name; uint16_t id; }; struct inst { uint32_t am; /* Addressing modes. */ uint8_t op; /* Base value used to get the actual opcode. */ }; struct expr { int type; /* Expression type. */ expr *left; /* Left side of expression. */ expr *right; /* Right side of expression. */ /* Expression value. */ union { uint64_t val; symbol *sym; } value; }; struct strln { strln *next; strln *prev; char *str; int blanks; }; extern char lexeme[]; extern char *string[]; extern char *comment[]; extern uint16_t incl[]; extern line *lines; extern line *last_line; extern token *tokens; extern token *last_tok; extern symbol *symbols; extern symbol *last_sym; extern symbol *locals; extern symbol *last_loc; extern fixup *fixups; extern fixup *last_fix; extern strln *first_strln; extern strln *last_strln; extern uint8_t lex_type; enum dir { DIR_ORG, DIR_BYTE, DIR_WORD, DIR_DWORD, DIR_QWORD, DIR_INCLUDE, DIR_RES, DIR_STRUCT, DIR_UNION, DIR_ENDSTRUCT, DIR_ENDUNION }; enum token { TOK_DIR, TOK_LOCAL, TOK_LABEL, TOK_SYM, TOK_EXPR, TOK_CSV, TOK_STRING, TOK_CHAR, TOK_IND, TOK_IMM, TOK_BREG, TOK_OPCODE, TOK_EXTOP, TOK_ORTHO, TOK_REG, TOK_MEM, TOK_CC, TOK_OS, TOK_RS, TOK_OF, TOK_COMMENT, TOK_HEX, TOK_DEC, TOK_BIN, TOK_INCLUDE, TOK_STRUCT, TOK_UNION, TOK_MEMBER }; enum pre_token { PTOK_DOT, PTOK_AT, PTOK_COLON, PTOK_EQU, PTOK_PLUS, PTOK_MINUS, PTOK_ASTRSK, PTOK_GT, PTOK_LT, PTOK_PIPE, PTOK_LBRACK, PTOK_RBRACK, PTOK_COMMA, PTOK_B, PTOK_E, PTOK_X, PTOK_Y, PTOK_S, PTOK_P, PTOK_A, PTOK_C, PTOK_D, PTOK_F, PTOK_R, PTOK_DQUOTE, PTOK_SQUOTE, PTOK_HASH, PTOK_SCOLON, PTOK_DOLLAR, PTOK_PERCENT, PTOK_NUMBER, PTOK_ALPHA, PTOK_OTHER }; enum expression { EXPR_PLUS, EXPR_MINUS, EXPR_LOW, EXPR_HIGH, EXPR_OR, EXPR_LSHFT, EXPR_RSHFT, EXPR_MUL, EXPR_HEX, EXPR_DEC, EXPR_BIN, EXPR_CHAR, EXPR_SYM, EXPR_REG, EXPR_NONE }; 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) }; 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 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} }; static const char *dir_t[11] = { [ 0] = "org", [ 1] = "byte", [ 2] = "word", [ 3] = "dword", [ 4] = "qword", [ 5] = "include", [ 6] = "res", [ 7] = "struct", [ 8] = "union", [ 9] = "endstruct", [10] = "endunion" }; static const char *rs_t[4] = { [0] = "", [1] = ".w", [2] = ".d", [3] = ".q" }; static const char *lex_tok[] = { [TOK_DIR ] = "TOK_DIR", [TOK_LOCAL ] = "TOK_LOCAL", [TOK_LABEL ] = "TOK_LABEL", [TOK_SYM ] = "TOK_SYM", [TOK_EXPR ] = "TOK_EXPR", [TOK_CSV ] = "TOK_CSV", [TOK_STRING ] = "TOK_STRING", [TOK_CHAR ] = "TOK_CHAR", [TOK_IND ] = "TOK_IND", [TOK_IMM ] = "TOK_IMM", [TOK_BREG ] = "TOK_BREG", [TOK_OPCODE ] = "TOK_OPCODE", [TOK_EXTOP ] = "TOK_EXTOP", [TOK_ORTHO ] = "TOK_ORTHO", [TOK_REG ] = "TOK_REG", [TOK_MEM ] = "TOK_MEM", [TOK_CC ] = "TOK_CC", [TOK_OS ] = "TOK_OS", [TOK_RS ] = "TOK_RS", [TOK_OF ] = "TOK_OF", [TOK_COMMENT] = "TOK_COMMENT", [TOK_HEX ] = "TOK_HEX", [TOK_DEC ] = "TOK_DEC", [TOK_BIN ] = "TOK_BIN", [TOK_INCLUDE] = "TOK_INCLUDE", [TOK_STRUCT ] = "TOK_STRUCT", [TOK_UNION ] = "TOK_UNION", [TOK_MEMBER ] = "TOK_MEMBER" }; static const char *adrmode[] = { [IMM ] = "IMM", [ZM ] = "ZM", [ZMX ] = "ZMX", [ZMY ] = "ZMY", [IND ] = "IND", [INDX ] = "INDX", [INDY ] = "INDY", [ABS ] = "ABS", [REL ] = "REL", [BREG ] = "BREG", [IMPL ] = "IMPL", [ABSX ] = "ABSX", [ABSY ] = "ABSY", [AIND ] = "AIND", [AINDX] = "AINDX", [AINDY] = "AINDY", [EIND ] = "EIND" /* [ZMR ] = "ZMR", [ZINDR] = "ZINDR", [ZRIND] = "ZRIND", [AINDR] = "AINDR", [AINDY] = "ARIND",*/ }; static const char *mne[OPNUM] = { [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" }; static const char *ext_mne[EXT_OPNUM] = { [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" }; static const char *ortho_mne[ORTHO_OPNUM] = { [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" }; static const char *set_cc[8] = { "NG", "PO", "CS", "CC", "EQ", "NE", "VS", "VC" }; static const char *reg_name[16] = { [REG_A ] = "A", [REG_B ] = "B", [REG_X ] = "X", [REG_Y ] = "Y", [REG_E ] = "E", [REG_C ] = "C", [REG_D ] = "D", [REG_S ] = "S", [REG_F ] = "F", [REG_SP ] = "SP", [REG_BP ] = "BP", [REG_R11] = "R11", [REG_R12] = "R12", [REG_R13] = "R13", [REG_R14] = "R14", [REG_R15] = "R15" }; static const char *instdesc[OPNUM] = { [ADC] = "ADd accumulator, with operand, Carry if needed.", [AND] = "Bitwise AND accumulator, with operand.", [ASR] = "Arithmetic Shift Right accumulator, with operand.", [BCC] = "Branch if the Carry flag has been Cleared.", [BCS] = "Branch if the Carry flag is Set.", [BEQ] = "Branch if EQual (the zero flag has been set).", [BNE] = "Branch if Not Equal (the zero flag has been cleared)", [BNG] = "Branch if NeGative.", [BPO] = "Branch if POsitive.", [BRA] = "BRanch Always.", [BRK] = "BReaKpoint", [BVC] = "Branch if the oVerflow flag has been Cleared.", [BVS] = "Branch if the oVerflow flag is Set.", [CLC] = "CLear the Carry flag.", [CLI] = "CLear the Interrupt flag.", [CLV] = "CLear the oVerflow flag.", [CMP] = "CoMPare acumulator, with operand.", [CPB] = "ComPare the B register, with operand.", [CPS] = "Clears the Processor Status register.", [CPX] = "ComPare the X register, with operand.", [CPY] = "ComPare the Y register, with operand.", [DEB] = "DEcrement the B register.", [DEC] = "DECrement accumulator, or memory.", [DEX] = "DEcrement the X register.", [DEY] = "DEcrement the Y register.", [DIV] = "DIVide accumulator, with operand, and put the remainder into the B register.", [INB] = "INcrement the B register.", [INC] = "INCrement accumulator, or memory.", [INX] = "INcrement the X register.", [INY] = "INcrement the Y register.", [JMP] = "JuMP to the address specified.", [JSR] = "Jump to a SubRoutine.", [LDA] = "LoaD the value from the operand, to the Accumulator.", [LDB] = "LoaD the value from the operand, to the B register.", [LDX] = "LoaD the value from the operand, to the X register.", [LDY] = "LoaD the value from the operand, to the Y register.", [LSL] = "Logical Shift Left accumulator, with operand.", [LSR] = "Logical Shift Right accumulator, with operand.", [MUL] = "MULtiply accumulator, with operand.", [NOP] = "NO oPeration", [ORA] = "Bitwise OR Accumulator, with operand.", [PHA] = "PusH the number of bytes specified, from the Accumulator to the stack.", [PHB] = "PusH the number of bytes specified, from the B register to the stack.", [PHP] = "PusH the number of bytes specified, from the Processor status register to the stack.", [PHX] = "PusH the number of bytes specified, from the X register to the stack.", [PHY] = "PusH the number of bytes specified, from the Y register to the stack.", [PLA] = "PuLl the number of bytes specified, from the stack, to the Accumulator.", [PLB] = "PuLl the number of bytes specified, from the stack, to the B register.", [PLP] = "PuLl the number of bytes specified, from the stack, to the Processor status register.", [PLX] = "PuLl the number of bytes specified, from the stack, to the X register.", [PLY] = "PuLl the number of bytes specified, from the stack, to the Y register.", [ROL] = "ROtate Left accumulator, with operand.", [ROR] = "ROtate Right accumulator, with operand.", [RTI] = "ReTurn from an Interrupt.", [RTS] = "ReTurn from a Subroutine.", [SBC] = "SuBtract accumulator, with operand, Carry if needed", [SEC] = "SEt the Carry flag.", [SEI] = "SEt the Interrupt flag.", [STA] = "STore the value from the Accumulator, in memory.", [STB] = "STore the value from the B register, in memory.", [STX] = "STore the value from the X register, in memory.", [STY] = "STore the value from the Y register, in memory.", [TAB] = "Transfer the value from the Accumulator, to the B register.", [TAX] = "Transfer the value from the Accumulator, to the X register.", [TAY] = "Transfer the value from the Accumulator, to the Y register.", [TBA] = "Transfer the value from the Y register, to the Accumulator.", [TSX] = "Transfer the value from the Stack pointer, to the X register.", [TXA] = "Transfer the value from the X register, to the Accumulator.", [TXS] = "Transfer the value from the X register, to the Stack pointer.", [TXY] = "Transfer the value from the X register, to the Y register.", [TYA] = "Transfer the value from the Y register, to the Accumulator.", [TYX] = "Transfer the value from the Y register, to the X register.", [WAI] = "WAIt for an interrupt", [XOR] = "Bitwise XOR Accumulator, with operand." }; static const uint8_t bitsize[4] = { [0] = 0x07, [1] = 0x0F, [2] = 0x1F, [3] = 0x3F }; static const uint8_t amp[8] = { [0] = 0x00, [1] = 0x00, [2] = 0x07, [4] = 0x07, [5] = 0x0B, [6] = 0x0B, [3] = 0x0F, [7] = 0x0F }; extern uint16_t linenum; extern uint16_t lineidx; extern uint16_t stridx; extern uint16_t comidx; extern uint16_t inc_file; /* Number of included files. */ extern uint16_t inc_count; struct bc { uint64_t progsize; uint64_t datasize; }; typedef struct bc bytecount; extern uint8_t defined; extern uint8_t isfixup; extern line *find_line(uint32_t ln, uint8_t dbg); extern uint64_t parse_quote(char **s, char delm, int get_value, uint8_t *buf, uint8_t dbg); extern uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg); extern uint64_t get_val(expr *tree, uint64_t addr, uint8_t size, int depth, uint8_t dbg); extern token *skip_expr(token *t, uint8_t end_expr, uint8_t stop_comma, uint8_t dbg); extern uint64_t parse_tokens(token *tm, line **l, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg); extern token *make_token(uint8_t id, uint8_t type, uint8_t space, uint8_t tab, uint64_t value, char *str, symbol *s, expr *e); extern void assemble(line *ln, bytecount *bc, uint8_t dbg); extern void fix_symtree(line *l); extern void cleanup();