#include "opcode.h"
#include <ctype.h>
#include <string.h>
#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;
struct tok {
token *next;
uint8_t id;
uint8_t type;
uint8_t subtype;
uint8_t tab;
uint8_t space;
uint8_t subtab;
uint8_t subspace;
uint8_t digits;
union {
expr *expr;
symbol *sym;
char *str;
uint8_t byte ;
uint16_t word ;
uint32_t dword;
uint64_t qword;
};
};
struct ln {
line *next;
token *tok;
uint16_t count;
uint16_t bline;
uint32_t linenum;
uint64_t addr;
};
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;
uint8_t op;
};
struct expr {
int type;
expr *left;
expr *right;
union {
uint64_t val;
symbol *sym;
} value;
};
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 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_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] = 0x0C,
[OP_ADD] = 0x03,
[OP_SUB] = 0x23,
[OP_NOT] = 0x44,
[OP_CLZ] = 0xC4,
[OP_CLO] = 0xE4,
[OP_SWP] = 0x2C,
[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), 0x00},
[JSR] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND), 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"
};
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;
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 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();