#include "opcode.h"
#include <ctype.h>
#include <string.h>
#define MAX_TOK 0x1000
#define TXS_MNE_ID 78
typedef struct tok token ;
typedef struct ln line ;
typedef struct sym symbol;
typedef struct fix fixup ;
struct tok {
token *next;
uint8_t id;
uint8_t type;
union {
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;
uint32_t linenum;
uint64_t addr;
uint8_t stab;
uint8_t sspace;
uint8_t etab;
uint8_t espace;
};
struct fix {
fixup *next;
symbol *s;
token *t;
uint64_t adr;
};
struct sym {
symbol *next;
symbol *local;
uint16_t count;
uint64_t val;
uint8_t def;
char *name;
uint16_t id;
};
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 *locals;
extern fixup *fixups;
extern uint8_t lex_type;
enum dir {
DIR_ORG,
DIR_BYTE,
DIR_WORD,
DIR_DWORD,
DIR_QWORD,
DIR_INCLUDE
};
enum token {
TOK_DIR,
TOK_LOCAL,
TOK_LABEL,
TOK_SYM,
TOK_EXPR,
TOK_CSV,
TOK_STRING,
TOK_CHAR,
TOK_IND,
TOK_IMM,
TOK_OPCODE,
TOK_RS,
TOK_COMMENT,
TOK_HEX,
TOK_DEC,
TOK_BIN,
TOK_INCLUDE
};
enum pre_token {
PTOK_DOT,
PTOK_AT,
PTOK_COLON,
PTOK_EQU,
PTOK_PLUS,
PTOK_MINUS,
PTOK_GT,
PTOK_LT,
PTOK_LBRACK,
PTOK_RBRACK,
PTOK_COMMA,
PTOK_X,
PTOK_Y,
PTOK_DQUOTE,
PTOK_SQUOTE,
PTOK_HASH,
PTOK_SCOLON,
PTOK_DOLLAR,
PTOK_PERCENT,
PTOK_NUMBER,
PTOK_ALPHA,
PTOK_OTHER
};
enum expr {
EXPR_PLUS,
EXPR_MINUS,
EXPR_LOW,
EXPR_HIGH,
EXPR_NONE
};
static const uint8_t opcodes[OPNUM][9] = {
[ 0] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
[ 1] = {0x01, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0xFF},
[ 2] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02},
[ 3] = {0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[ 4] = {0x09, 0x2D, 0xFF, 0xFF, 0x55, 0xAD, 0xAC, 0x2C, 0xFF},
[ 5] = {0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[ 6] = {0xFF, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xE5},
[ 7] = {0xFF, 0x0E, 0xFF, 0xFF, 0xCE, 0xFF, 0xFF, 0x10, 0xFF},
[ 8] = {0x11, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xFF},
[ 9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12},
[10] = {0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[11] = {0x19, 0x3D, 0xFF, 0xFF, 0x85, 0xFF, 0xFF, 0x4C, 0xFF},
[12] = {0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[13] = {0xFF, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xF5},
[14] = {0xFF, 0x1E, 0xFF, 0xFF, 0xBE, 0xFF, 0xFF, 0x20, 0xFF},
[15] = {0x21, 0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0xFF},
[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22},
[17] = {0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[18] = {0x29, 0x4D, 0xFF, 0xFF, 0xB5, 0xFF, 0xFF, 0x3C, 0xFF},
[19] = {0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[20] = {0xFF, 0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0xFF},
[21] = {0x31, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0xFF},
[22] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x32},
[23] = {0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[24] = {0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[25] = {0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xFF},
[26] = {0x41, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x44, 0xFF},
[27] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x42},
[28] = {0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[29] = {0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[30] = {0xFF, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF},
[31] = {0x51, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0xFF},
[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52},
[33] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x58},
[34] = {0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[35] = {0xFF, 0x5E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0xFF},
[36] = {0x61, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x64, 0xFF},
[37] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62},
[38] = {0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[39] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A},
[40] = {0xFF, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0xFF},
[41] = {0x71, 0x76, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0xFF},
[42] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x72},
[43] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78},
[44] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7A},
[45] = {0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF},
[46] = {0x81, 0x86, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xFF},
[47] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x82},
[48] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88},
[49] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A},
[50] = {0xFF, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xFF},
[51] = {0x91, 0x96, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0xFF},
[52] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92},
[53] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98},
[54] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A},
[55] = {0xFF, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF},
[56] = {0xA1, 0xA6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF},
[57] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2},
[58] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8},
[59] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA},
[60] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE},
[61] = {0xB1, 0xB6, 0xFF, 0xFF, 0x25, 0x7D, 0x7C, 0xB4, 0xFF},
[62] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2},
[63] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8},
[64] = {0xB9, 0xBD, 0xFF, 0xC9, 0x95, 0xFF, 0xFF, 0xBC, 0xFF},
[65] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA},
[66] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0},
[67] = {0xC1, 0xC6, 0x79, 0x39, 0x05, 0x5D, 0x5C, 0xC4, 0xFF},
[68] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5},
[69] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8},
[70] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA},
[71] = {0xFF, 0xCD, 0x89, 0x49, 0x15, 0x6D, 0x6C, 0xCC, 0xFF},
[72] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0},
[73] = {0xD1, 0xD6, 0x99, 0x59, 0x35, 0x8D, 0x8C, 0xD4, 0xFF},
[74] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5},
[75] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8},
[76] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA},
[77] = {0xFF, 0xDD, 0xA9, 0x69, 0x45, 0x9D, 0x9C, 0xDC, 0xFF},
[78] = {0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
[79] = {0xE1, 0xE6, 0xE9, 0xFF, 0x65, 0xFF, 0xFF, 0xE4, 0xFF},
[80] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8},
[81] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA},
[82] = {0xFF, 0xED, 0xF9, 0xFF, 0x75, 0xFF, 0xFF, 0xEC, 0xFF},
[83] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE},
[84] = {0xF1, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF},
[85] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2},
[86] = {0xFF, 0xFD, 0xFF, 0xD9, 0xA5, 0xFF, 0xFF, 0xFC, 0xFF},
[87] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}
};
static const char *dir_t[6] = {
[0] = "org",
[1] = "byte",
[2] = "word",
[3] = "dword",
[4] = "qword",
[5] = "include"
};
static const char *rs_t[4] = {
[0] = "",
[1] = ".w",
[2] = ".d",
[3] = ".q"
};
static const char *lex_tok[17] = {
[0x00] = "TOK_DIR",
[0x01] = "TOK_LOCAL",
[0x02] = "TOK_LABEL",
[0x03] = "TOK_SYM",
[0x04] = "TOK_EXPR",
[0x05] = "TOK_CSV",
[0x06] = "TOK_STRING",
[0x07] = "TOK_CHAR",
[0x08] = "TOK_IND",
[0x09] = "TOK_IMM",
[0x0A] = "TOK_OPCODE",
[0x0B] = "TOK_RS",
[0x0C] = "TOK_COMMENT",
[0x0D] = "TOK_HEX",
[0x0E] = "TOK_DEC",
[0x0F] = "TOK_BIN",
[0x10] = "TOK_INCLUDE"
};
static const char *adrmode[9] = {
[IMM ] = "IMM",
[ZM ] = "ZM",
[ZMX ] = "ZMX",
[ZMY ] = "ZMY",
[IND ] = "IND",
[INDX] = "INDX",
[INDY] = "INDY",
[ABS ] = "ABS",
[IMPL] = "IMPL"
};
static const char *mne[OPNUM] = {
[ 0] = "CPS",
[ 1] = "ADC",
[ 2] = "AAB",
[ 3] = "PHP",
[ 4] = "CPB",
[ 5] = "PHB",
[ 6] = "DEC",
[ 7] = "JMP",
[ 8] = "SBC",
[ 9] = "SAB",
[10] = "ENT",
[11] = "CPY",
[12] = "PLB",
[13] = "INC",
[14] = "JSR",
[15] = "AND",
[16] = "ABA",
[17] = "PLP",
[18] = "CPX",
[19] = "PHY",
[20] = "BPO",
[21] = "ORA",
[22] = "OAB",
[23] = "STT",
[24] = "PLY",
[25] = "BNG",
[26] = "XOR",
[27] = "XAB",
[28] = "PHA",
[29] = "PHX",
[30] = "BCS",
[31] = "LSL",
[32] = "LLB",
[33] = "CLC",
[34] = "PLX",
[35] = "BCC",
[36] = "LSR",
[37] = "LRB",
[38] = "PLA",
[39] = "TAB",
[40] = "BEQ",
[41] = "ROL",
[42] = "RLB",
[43] = "SEC",
[44] = "TBA",
[45] = "BNE",
[46] = "ROR",
[47] = "RRB",
[48] = "DEY",
[49] = "TAY",
[50] = "BVS",
[51] = "MUL",
[52] = "MAB",
[53] = "CLI",
[54] = "TYA",
[55] = "BVC",
[56] = "DIV",
[57] = "DAB",
[58] = "INY",
[59] = "TAX",
[60] = "RTS",
[61] = "CMP",
[62] = "CAB",
[63] = "SEI",
[64] = "LDX",
[65] = "TXA",
[66] = "RTI",
[67] = "LDA",
[68] = "DEX",
[69] = "CLV",
[70] = "TYX",
[71] = "STA",
[72] = "TSX",
[73] = "LDB",
[74] = "INX",
[75] = "WAI",
[76] = "TXY",
[77] = "STB",
[78] = "TXS",
[79] = "LDY",
[80] = "BRK",
[81] = "NOP",
[82] = "STY",
[83] = "DEB",
[84] = "ASR",
[85] = "ARB",
[86] = "STX",
[87] = "INB"
};
static const char *instdesc[OPNUM] = {
[ 0] = "Clears the Processor Status register.",
[ 1] = "ADd accumulator, with operand, Carry if needed.",
[ 2] = "Add Accumulator, with B, carry if needed.",
[ 3] = "PusH the number of bytes specified, from the Processor status register to the stack.",
[ 4] = "ComPare the B register, with operand.",
[ 5] = "PusH the number of bytes specified, from the B register to the stack.",
[ 6] = "DECrement accumulator, or memory.",
[ 7] = "JuMP to the address specified.",
[ 8] = "SuBtract accumulator, with operand, Carry if needed",
[ 9] = "Subtract Accumulator, with B, carry if needed.",
[10] = "ENd a Thread.",
[11] = "ComPare the Y register, with operand.",
[12] = "PuLl the number of bytes specified, from the stack, to the B register.",
[13] = "INCrement accumulator, or memory.",
[14] = "Jump to a SubRoutine.",
[15] = "Bitwise AND accumulator, with operand.",
[16] = "Bitwise AND Accumulator, with B.",
[17] = "PuLl the number of bytes specified, from the stack, to the Processor status register.",
[18] = "ComPare the X register, with operand.",
[19] = "PusH the number of bytes specified, from the Y register to the stack.",
[20] = "Branch if POsitive.",
[21] = "Bitwise OR Accumulator, with operand.",
[22] = "Bitwise OR Accumulator, with B.",
[23] = "STart a Thread.",
[24] = "PuLl the number of bytes specified, from the stack, to the Y register.",
[25] = "Branch if NeGative.",
[26] = "Bitwise XOR Accumulator, with operand.",
[27] = "Bitwise XOR Accumulator, with B.",
[28] = "PusH the number of bytes specified, from the Accumulator to the stack.",
[29] = "PusH the number of bytes specified, from the X register to the stack.",
[30] = "Branch if the Carry flag is Set.",
[31] = "Logical Shift Left accumulator, with operand.",
[32] = "Logical Shift Left accumulator, with B.",
[33] = "CLear the Carry flag.",
[34] = "PuLl the number of bytes specified, from the stack, to the X register.",
[35] = "Branch if the Carry flag has been Cleared.",
[36] = "Logical Shift Right accumulator, with operand.",
[37] = "Logical Shift Right accumulator, with B.",
[38] = "PuLl the number of bytes specified, from the stack, to the Accumulator.",
[39] = "Transfer the value from the Accumulator, to the B register.",
[40] = "Branch if EQual (the zero flag has been set).",
[41] = "ROtate Left accumulator, with operand.",
[42] = "Rotate Left accumulator, with B.",
[43] = "SEt the Carry flag.",
[44] = "Transfer the value from the Y register, to the Accumulator.",
[45] = "Branch if Not Equal (the zero flag has been cleared)",
[46] = "ROtate Right accumulator, with operand.",
[47] = "Rotate Right accumulator, with B.",
[48] = "DEcrement the Y register.",
[49] = "Transfer the value from the Accumulator, to the Y register.",
[50] = "Branch if the oVerflow flag is Set.",
[51] = "MULtiply accumulator, with operand.",
[52] = "Multiply Accumulator, with B.",
[53] = "CLear the Interrupt flag.",
[54] = "Transfer the value from the Y register, to the Accumulator.",
[55] = "Branch if the oVerflow flag has been Cleared.",
[56] = "DIVide accumulator, with operand, and put the remainder into the B register.",
[57] = "Divide Accumulator, with B, and put the remainder into the X register.",
[58] = "INcrement the Y register.",
[59] = "Transfer the value from the Accumulator, to the X register.",
[60] = "ReTurn from a Subroutine.",
[61] = "CoMPare acumulator, with operand.",
[62] = "Compare Accumulator, with B.",
[63] = "SEt the Interrupt flag.",
[64] = "LoaD the value from the operand, to the X register.",
[65] = "Transfer the value from the X register, to the Accumulator.",
[66] = "ReTurn from an Interrupt.",
[67] = "LoaD the value from the operand, to the Accumulator.",
[68] = "DEcrement the X register.",
[69] = "CLear the oVerflow flag.",
[70] = "Transfer the value from the Y register, to the X register.",
[71] = "STore the value from the Accumulator, in memory.",
[72] = "Transfer the value from the Stack pointer, to the X register.",
[73] = "LoaD the value from the operand, to the B register.",
[74] = "INcrement the X register.",
[75] = "WAIt for an interrupt",
[76] = "Transfer the value from the X register, to the Y register.",
[77] = "STore the value from the B register, in memory.",
[78] = "Transfer the value from the X register, to the Stack pointer.",
[79] = "LoaD the value from the operand, to the Y register.",
[80] = "BReaKpoint",
[81] = "NO oPeration",
[82] = "STore the value from the Y register, in memory.",
[83] = "DEcrement the B register.",
[84] = "Arithmetic Shift Right accumulator, with operand.",
[85] = "Arithmetic shift Right accumulator, with B.",
[86] = "STore the value from the X register, in memory.",
[87] = "INcrement the B register."
};
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, uint8_t dbg);
extern uint64_t parse_tokens(token *tm, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg);
extern token *make_token(uint8_t id, uint8_t type, uint64_t value, char *str, symbol *sym);
extern void assemble(line *ln, bytecount *bc, uint8_t dbg);
extern void cleanup();