diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2020-12-04 15:20:28 -0500 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2020-12-04 15:20:28 -0500 |
commit | 96393257a43ac52f2b911594d106741245dec5f0 (patch) | |
tree | 6b9d11c50ed3cd1920444c4dd0ee4027814ef4bd | |
parent | 83ce1151ee1f06ae6b1c5c1018cc2489494e5ea4 (diff) |
- Started work on writing the new version of the
assembler.
- Did alot of stuff in the emulator.
- Did alot of stuff in the SuB Suite.
-rw-r--r-- | asmmon.c | 2 | ||||
-rw-r--r-- | asmmon.h | 102 | ||||
-rw-r--r-- | assemble.c | 2 | ||||
-rw-r--r-- | disasm.c | 4 | ||||
-rw-r--r-- | enums.h | 86 | ||||
-rw-r--r-- | io.c | 1 | ||||
-rw-r--r-- | lexer.c | 186 | ||||
-rw-r--r-- | lexer.h | 149 | ||||
-rw-r--r-- | lexer/asmmon.h | 794 | ||||
-rw-r--r-- | lexer/backup/asmmon.h | 794 | ||||
-rw-r--r-- | lexer/backup/assemble.c | 975 | ||||
-rw-r--r-- | lexer/backup/enums.h | 540 | ||||
-rw-r--r-- | lexer/backup/lexer.c | 937 | ||||
-rw-r--r-- | lexer/backup/lexer.h | 228 | ||||
-rw-r--r-- | lexer/cpu/sux/cpu.c | 30 | ||||
-rw-r--r-- | lexer/enums.h | 540 | ||||
-rw-r--r-- | lexer/lexer.c | 311 | ||||
-rw-r--r-- | lexer/lexer.h | 228 | ||||
-rw-r--r-- | lexer/misc.c | 14 | ||||
-rw-r--r-- | lexer/parse.c | 171 | ||||
-rw-r--r-- | lexer/symbol.c | 42 | ||||
-rw-r--r-- | opcode.h | 1 | ||||
-rw-r--r-- | programs/sub-suite/libc.s | 77 | ||||
-rw-r--r-- | programs/sub-suite/shift_line.c | 79 | ||||
-rw-r--r-- | programs/sub-suite/subasm.s | 61 | ||||
-rw-r--r-- | programs/sub-suite/subeditor.s | 154 | ||||
-rw-r--r-- | programs/sub-suite/subsuite.s | 3 | ||||
-rw-r--r-- | programs/sub-suite/utils.s | 105 | ||||
-rw-r--r-- | sux.c | 20 | ||||
-rw-r--r-- | sux.h | 516 | ||||
-rw-r--r-- | test/base-ext.s | 2 |
31 files changed, 6620 insertions, 534 deletions
@@ -305,7 +305,7 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u if (t->next && !isopdone(t)) { op_done = isopdone(t->next); } - if (am != 0xFF && op_done && t->id != TOK_RS && !t->next) { + if (am != 0xFF && op_done && t->id != TOK_RS) { switch (am) { case EIND: putchar('('); am_done = 0; break; case BREG: putchar('b'); am_done = 1; break; @@ -118,6 +118,8 @@ enum token { TOK_BREG, TOK_OPCODE, TOK_EXTOP, + TOK_ORTHO, + TOK_REG, TOK_RS, TOK_OF, TOK_COMMENT, @@ -150,6 +152,11 @@ enum pre_token { PTOK_Y, PTOK_S, PTOK_P, + PTOK_A, + PTOK_C, + PTOK_D, + PTOK_F, + PTOK_R, PTOK_DQUOTE, PTOK_SQUOTE, PTOK_HASH, @@ -193,6 +200,8 @@ enum addrmode { AM_AIND = (1 << 17), AM_AINDY = (1 << 18), AM_AINDX = (1 << 19), + AM_ORTHO = (1 << 20), + AM_ORTHO2 = (1 << 21) }; enum ind { @@ -268,9 +277,9 @@ static const uint8_t eind_base_ops[10] = { }; static const instruction inst[OPNUM] = { - [ADC] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x01}, - [AND] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x41}, - [ASR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x62}, + [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}, @@ -284,18 +293,18 @@ static const instruction inst[OPNUM] = { [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), 0x82}, + [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), 0x84}, + [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), 0x42}, + [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), 0xA4}, + [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}, @@ -304,9 +313,9 @@ static const instruction inst[OPNUM] = { [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), 0xA1}, - [LSR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0xC1}, - [MUL] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x22}, + [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}, @@ -319,11 +328,11 @@ static const instruction inst[OPNUM] = { [PLP] = {(AM_IMPL), 0x7E}, [PLX] = {(AM_IMPL), 0xFE}, [PLY] = {(AM_IMPL), 0xDE}, - [ROL] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0xE1}, - [ROR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x02}, + [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), 0x21}, + [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}, @@ -341,19 +350,19 @@ static const instruction inst[OPNUM] = { [TYA] = {(AM_IMPL), 0x3A}, [TYX] = {(AM_IMPL), 0x6A}, [WAI] = {(AM_IMPL), 0x59}, - [XOR] = {(AM_IMM|AM_ZM|AM_ABS|AM_BREG|AM_EIND), 0x81} + [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), 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), 0x23}, - [ADD] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x06}, - [SUB] = {(AM_IMM|AM_ZM|AM_ABS|AM_EIND), 0x26}, + [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), 0xC6}, + [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}, @@ -373,12 +382,12 @@ static const instruction ext_inst[EXT_OPNUM] = { [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), 0x05}, - [CLO] = {(AM_ZM|AM_ABS|AM_EIND), 0x25}, + [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), 0xE6}, - [PCN] = {(AM_ZM|AM_ABS|AM_EIND), 0xE8}, + [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}, @@ -396,6 +405,25 @@ static const instruction ext_inst[EXT_OPNUM] = { [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", @@ -417,7 +445,7 @@ static const char *rs_t[4] = { [3] = ".q" }; -static const char *lex_tok[23] = { +static const char *lex_tok[] = { [TOK_DIR ] = "TOK_DIR", [TOK_LOCAL ] = "TOK_LOCAL", [TOK_LABEL ] = "TOK_LABEL", @@ -431,6 +459,8 @@ static const char *lex_tok[23] = { [TOK_BREG ] = "TOK_BREG", [TOK_OPCODE ] = "TOK_OPCODE", [TOK_EXTOP ] = "TOK_EXTOP", + [TOK_ORTHO ] = "TOK_ORTHO", + [TOK_REG ] = "TOK_REG", [TOK_RS ] = "TOK_RS", [TOK_OF ] = "TOK_OF", [TOK_COMMENT] = "TOK_COMMENT", @@ -461,6 +491,11 @@ static const char *adrmode[] = { [AINDX] = "AINDX", [AINDY] = "AINDY", [EIND ] = "EIND" +/* [ZMR ] = "ZMR", + [ZINDR] = "ZINDR", + [ZRIND] = "ZRIND", + [AINDR] = "AINDR", + [AINDY] = "ARIND",*/ }; static const char *mne[OPNUM] = { @@ -592,6 +627,25 @@ static const char *ext_mne[EXT_OPNUM] = { [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 *instdesc[OPNUM] = { [ADC] = "ADd accumulator, with operand, Carry if needed.", [AND] = "Bitwise AND accumulator, with operand.", @@ -426,7 +426,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, case 1: opcode = (id == TOK_EXTOP) ? opcode+0x01 : eind_base_ops[get_eind(instr, dbg)]; break; } } - opcode = (am & AM_BREG) ? opcode+0x14 : opcode; + opcode = ((am & AM_BREG) && type == BREG) ? opcode+0x14 : opcode; } break; case REL: @@ -38,7 +38,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint mask.u64 = 0; const char *inst_name; uint8_t inst_type; - if ((ext_prefix & 0xD) == 0xD) { + if ((ext_prefix & 0xF) == 0xD) { switch (ext_prefix >> 4) { case 0x0: inst_name = ext_opname[opcode]; inst_type = ext_optype[opcode]; break; } @@ -104,9 +104,9 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint value = (sign[0] == '-') ? (~value + 1) & mask.u64 : value; } switch (inst_type) { - case EIND : case BREG : case IMPL : wprintw(scr, "%s%s" , inst_name, postfix); break; + case EIND : wprintw(scr, "%s%s (E)" , op, postfix); break; case IMM : wprintw(scr, "%s%s #$%0*"PRIX64 , op, postfix, (addrsize+1) << 1, value); break; case AIND : case AINDX: @@ -1,23 +1,56 @@ enum am { /* Part of Base ISA. */ - IMM, /* Immediate Data. */ - ZM, /* Zero Matrix. */ - ZMX, /* Zero Matrix, indexed with X. */ - ZMY, /* Zero Matrix, indexed with Y. */ - IND, /* Indirect. */ - INDX, /* Indexed Indirect. */ - INDY, /* Indirect Indexed. */ - ABS, /* Absolute. */ - REL, /* Relative to Program Counter. */ - BREG, /* B Register. */ - IMPL, /* Implied. */ + IMM, /* Immediate Data. */ + ZM, /* Zero Matrix. */ + ZMX, /* Zero Matrix, indexed with X. */ + ZMY, /* Zero Matrix, indexed with Y. */ + IND, /* Indirect. */ + INDX, /* Indexed Indirect. */ + INDY, /* Indirect Indexed. */ + ABS, /* Absolute. */ + REL, /* Relative to Program Counter. */ + BREG, /* B Register. */ + IMPL, /* Implied. */ /* Part of Base Extension. */ - ABSX, /* Absolute, Indexed with X. */ - ABSY, /* Absolute, Indexed with Y. */ - AIND, /* Absolute Indirect. */ - AINDX, /* Absolute Indexed Indirect. */ - AINDY, /* Absolute Indirect Indexed. */ - EIND, /* Effective Address Register, Indirect. */ + ABSX, /* Absolute, Indexed with X. */ + ABSY, /* Absolute, Indexed with Y. */ + AIND, /* Absolute Indirect. */ + AINDX, /* Absolute Indexed Indirect. */ + AINDY, /* Absolute Indirect Indexed. */ + EIND, /* Effective Address Register, Indirect. */ +}; + +/* Part of the Orthogonal Extension. */ +enum ortho_reg { + REG_A, + REG_B, + REG_X, + REG_Y, + REG_E, + REG_C, + REG_D, + REG_S, + REG_F, + REG_SP, + REG_BP, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15, +}; + +enum ortho_mem { + MEM_ABS, /* Absolute. */ + MEM_ZM, /* Zero Matrix. */ + MEM_ABSR, /* Absolute, Indexed with register. */ + MEM_ZMR, /* Zero Matrix, Indexed with register. */ + MEM_ZINDR, /* Zero Matrix, Indirect Indexed Register. */ + MEM_ZRIND, /* Zero Matrix, Indexed Indirect Register. */ + MEM_AINDR, /* Absolute, Indirect Indexed Register. */ + MEM_ARIND, /* Absolute, Indexed Indirect Register. */ + MEM_RIND, /* Register Indirect. */ + MEM_SIB, /* Scale Index Base. */ }; enum mne { @@ -149,6 +182,25 @@ enum ext_mne { SNE }; +enum ortho_mne { + MNG, + MPO, + MCS, + MCC, + MEQ, + MNE, + MVS, + MVC, + OR , + MOV, + IML, + IDV, + PSH, + PUL, + NEG, + SET +}; + enum base_isa { CPS_IMP = 0x00, /* Clear Processor Status. */ ADC_IMM = 0x01, /* ADd with Carry. */ @@ -333,6 +333,7 @@ void io(uint64_t address, uint8_t rw) { } else { handle_ctrlcode(addr[TX_ADDR]); } + //wrefresh(scr); break; } } @@ -228,8 +228,95 @@ line *find_line(uint32_t ln, uint8_t dbg) { return l; } -uint8_t is_struct = 0; -uint8_t is_anon = 0; +int is_struct = 0; +int is_anon = 0; + +void create_struct(symbol *c_sym, line *l, token *t, token *lt, char *name, uint8_t dbg) { + uint8_t ismember = !(is_struct == 1 && lt && lt->id == TOK_DIR); + mksymbol(name, 0, 1, ismember, 0, 0, dbg); + if (isfixup) { + isfixup = reslv_fixups(dbg); + } + t->sym = get_sym(name, 0, t, ismember, dbg); + if (lt && lt->id == TOK_DIR) { + t->sym->isstruct = 1; + t->id = (lt->type == DIR_STRUCT) ? TOK_STRUCT : TOK_UNION; + tmp_line = l; + } else { + t->id = TOK_MEMBER; + t->sym->isanon = (is_anon > 0); + } + isfixup += (t->sym == NULL); + int is_top = (c_sym == NULL); + c_sym = (!ismember && !c_sym) ? last_sym : c_sym; + if (!ismember) { + if (!is_top) { + c_sym = t->sym; + locals = NULL; + last_loc = NULL; + } else { + c_sym->down = locals; + } + } else { + if (lt && lt->id == TOK_DIR) { + if (lt->type == DIR_UNION || lt->type == DIR_STRUCT) { + c_sym->down = locals; + c_sym->down->up = c_sym; + last_loc->up = c_sym; + c_sym = last_loc; + locals = NULL; + last_loc = NULL; + } + } + } + cur_sym = c_sym; +} + +void end_struct(symbol *c_sym, symbol *s_sym, uint8_t dbg) { + int skip = 0; + if (is_anon > 0) { + if ((c_sym && c_sym->isanon) || (c_sym->up && !c_sym->up->isanon) || (c_sym && s_sym->isanon)) { + is_anon--; + } else if (is_struct <= 0) { + is_anon = 0; + } + skip = (!is_anon); + } + if (((is_struct-is_anon) > 0 && !skip) || (is_anon <= 0 && is_struct <= 0)) { + symbol *s; + for (s = locals; s; s = s->next) { + if (s->up == NULL) { + s->up = c_sym; + } + if (dbg) { + printf("s: %p, s->up: %p, c_sym: %p, last_loc: %p\n", s, s->up, c_sym, last_loc); + } + } + if (c_sym->down == NULL) { + c_sym->down = locals; + } + } + if ((is_anon <= 0 || is_struct <= 0)) { + for (s_sym = c_sym; s_sym->prev && !s_sym->isanon; s_sym = s_sym->prev); + struct_sym = s_sym; + } + if ((is_struct-is_anon) > 0 && !skip) { + symbol *s = c_sym; + for (; s->prev; s = s->prev) { + if (s->up == NULL && c_sym->up) { + s->up = c_sym->up; + } + if (dbg) { + printf("s: %p, s->up: %p, c_sym->up: %p, last_loc: %p\n", s, s->up, c_sym->up, last_loc); + } + } + if (c_sym->up) { + cur_sym = c_sym->up; + } + for (locals = locals->up; locals->prev; locals = locals->prev); + for (last_loc = locals; last_loc->next; last_loc = last_loc->next); + } +} uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { char sym[0x100]; @@ -321,7 +408,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { uint8_t ptok = get_ptok(str[i], dbg); if (is_altok(ptok, dbg)) { offset++; - if ((ptok == PTOK_S && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C')) { + if (((ptok == PTOK_S && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C'))) { offset++; } switch (get_ptok(str[i+offset], dbg)) { @@ -331,6 +418,11 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { case PTOK_Y : case PTOK_S : case PTOK_P : + case PTOK_A : + case PTOK_C : + case PTOK_D : + case PTOK_F : + case PTOK_R : case PTOK_ALPHA : case PTOK_NUMBER: ptok = PTOK_ALPHA; break; } @@ -338,6 +430,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { ptok = PTOK_ALPHA; } } + /*i = ptok_handler[ptok](str, i, lex_type, l, t, dbg);*/ switch (ptok) { case PTOK_DOT: i++; @@ -353,54 +446,14 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { for (j = 0; isdelm(str[i+j], dbg) & 16; j++); uint8_t ret = get_ptok(str[i+j], dbg); j = tmp; + if ((k == DIR_STRUCT || k == DIR_UNION) && (ret != PTOK_ALPHA || (is_anon && ret == PTOK_ALPHA))) { is_anon++; } is_struct += (k == DIR_STRUCT || k == DIR_UNION); is_struct -= (k == DIR_ENDSTRUCT || k == DIR_ENDUNION); if ((k == DIR_ENDSTRUCT || k == DIR_ENDUNION)) { - int skip = 0; - if ((int)is_anon > 0) { - if ((cur_sym && cur_sym->isanon) || (cur_sym->up && !cur_sym->up->isanon) || (struct_sym && struct_sym->isanon)) { - is_anon--; - } else if ((int)is_struct <= 0) { - is_anon = 0; - } - skip = (!is_anon); - } - if (((int)(is_struct-is_anon) > 0 && !skip) || ((int)is_anon <= 0 && (int)is_struct <= 0)) { - symbol *s; - for (s = locals; s; s = s->next) { - if (s->up == NULL) { - s->up = cur_sym; - } - if (dbg) { - printf("s: %p, s->up: %p, cur_sym: %p, last_loc: %p\n", s, s->up, cur_sym, last_loc); - } - } - if (cur_sym->down == NULL) { - cur_sym->down = locals; - } - } - if (((int)is_anon <= 0 || (int)is_struct <= 0)) { - for (struct_sym = cur_sym; struct_sym->prev && !struct_sym->isanon; struct_sym = struct_sym->prev); - } - if ((int)(is_struct-is_anon) > 0 && !skip) { - symbol *s = cur_sym; - for (; s->prev; s = s->prev) { - if (s->up == NULL && cur_sym->up) { - s->up = cur_sym->up; - } - if (dbg) { - printf("s: %p, s->up: %p, cur_sym->up: %p, last_loc: %p\n", s, s->up, cur_sym->up, last_loc); - } - } - if (cur_sym->up) { - cur_sym = cur_sym->up; - } - for (locals = locals->up; locals->prev; locals = locals->prev); - for (last_loc = locals; last_loc->next; last_loc = last_loc->next); - } + end_struct(cur_sym, struct_sym, dbg); } break; } @@ -592,12 +645,9 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { lexeme[j] = str[i++]; lexeme[j+1] = '\0'; lexeme[j+2] = '\0'; - if (lex_type != TOK_IND && lex_type != TOK_CSV) { - break; - } switch (ptok) { case PTOK_E: l->tok->type = (lex_type == TOK_IND) ? EIND : l->tok->type; break; - case PTOK_X: l->tok->type = (lex_type == TOK_IND) ? INDX : ZMX; break; + case PTOK_X: l->tok->type = (l->tok->type == IND) ? INDX : ZMX; break; case PTOK_Y: l->tok->type = (lex_type == TOK_IND) ? INDY : ZMY; break; } break; @@ -732,43 +782,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { printf("lex(): spaces: %u\n", spaces); } if (is_struct) { - islocal = !(is_struct == 1 && lt && lt->id == TOK_DIR); - mksymbol(sym, 0, 1, islocal, 0, 0, dbg); - if (isfixup) { - isfixup = reslv_fixups(dbg); - } - t->sym = get_sym(sym, 0, t, islocal, dbg); - if (lt && lt->id == TOK_DIR) { - t->sym->isstruct = 1; - t->id = (lt->type == DIR_STRUCT) ? TOK_STRUCT : TOK_UNION; - tmp_line = l; - } else { - t->id = TOK_MEMBER; - t->sym->isanon = (is_anon > 0); - } - isfixup += (t->sym == NULL); - int is_top = (cur_sym == NULL); - cur_sym = (!islocal && !cur_sym) ? last_sym : cur_sym; - if (!islocal) { - if (!is_top) { - cur_sym = t->sym; - locals = NULL; - last_loc = NULL; - } else { - cur_sym->down = locals; - } - } else { - if (lt && lt->id == TOK_DIR) { - if (lt->type == DIR_UNION || lt->type == DIR_STRUCT) { - cur_sym->down = locals; - cur_sym->down->up = cur_sym; - last_loc->up = cur_sym; - cur_sym = last_loc; - locals = NULL; - last_loc = NULL; - } - } - } + create_struct(cur_sym, l, t, lt, sym, dbg); islocal = 0; } else if ((str[i+spaces] != ':' && str[i+spaces] != '=')) { uint8_t sym_struct = 0; @@ -1,4 +1,4 @@ -static inline uint8_t isdelm(char c, uint8_t dbg) { +static uint8_t isdelm(char c, uint8_t dbg) { switch (c) { default : return 0x00; case '\0': @@ -11,7 +11,7 @@ static inline uint8_t isdelm(char c, uint8_t dbg) { } } -static inline uint8_t isdelm2(char c, uint8_t dbg) { +static uint8_t isdelm2(char c, uint8_t dbg) { switch (c) { default : return 0; case ')' : @@ -32,7 +32,7 @@ static inline uint8_t isdelm2(char c, uint8_t dbg) { } } -static inline uint8_t get_ptok(char c, uint8_t dbg) { +static uint8_t get_ptok(char c, uint8_t dbg) { switch (c) { case '.' : return PTOK_DOT ; case '@' : return PTOK_AT ; @@ -69,7 +69,7 @@ static inline uint8_t get_ptok(char c, uint8_t dbg) { } } -static inline uint8_t is_altok(uint8_t ptok, uint8_t dbg) { +static uint8_t is_altok(uint8_t ptok, uint8_t dbg) { switch (ptok) { case PTOK_B: case PTOK_E: @@ -80,3 +80,144 @@ static inline uint8_t is_altok(uint8_t ptok, uint8_t dbg) { default : return 0; } } + +#if 0 +static int handle_dot(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_at(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_colon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_equ(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_plus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_minus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_gt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_pipe(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_rbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_comma(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_b(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_e(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_x(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_y(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_s(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_p(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dquote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_squote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_hash(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_scolon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dollar(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_percent(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} +static int handle_number(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_alpha(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_other(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + return idx+1; +} + +typedef int (*ptok_func)(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg); + +static ptok_func ptok_handler[PTOK_OTHER+1] = { + [PTOK_DOT ] = handle_dot, + [PTOK_AT ] = handle_at, + [PTOK_COLON ] = handle_colon, + [PTOK_EQU ] = handle_equ, + [PTOK_PLUS ] = handle_plus, + [PTOK_MINUS ] = handle_minus, + [PTOK_GT ] = handle_gt, + [PTOK_LT ] = handle_lt, + [PTOK_PIPE ] = handle_pipe, + [PTOK_LBRACK ] = handle_lbrack, + [PTOK_RBRACK ] = handle_rbrack, + [PTOK_COMMA ] = handle_comma, + [PTOK_B ] = handle_b, + [PTOK_E ] = handle_e, + [PTOK_X ] = handle_x, + [PTOK_Y ] = handle_y, + [PTOK_S ] = handle_s, + [PTOK_P ] = handle_p, + [PTOK_DQUOTE ] = handle_dquote, + [PTOK_SQUOTE ] = handle_squote, + [PTOK_HASH ] = handle_hash, + [PTOK_SCOLON ] = handle_scolon, + [PTOK_DOLLAR ] = handle_dollar, + [PTOK_PERCENT] = handle_percent, + [PTOK_NUMBER ] = handle_number, + [PTOK_ALPHA ] = handle_alpha, + [PTOK_OTHER ] = handle_other +}; +#endif diff --git a/lexer/asmmon.h b/lexer/asmmon.h new file mode 100644 index 0000000..430d37c --- /dev/null +++ b/lexer/asmmon.h @@ -0,0 +1,794 @@ +#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 op operand ; + + +struct tok { + token *next; /* Pointer to the next token. */ + uint8_t id; /* Token ID. */ + uint8_t type; /* Token type 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 { + 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; + 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 op { + uint8_t type; /* Operand Type. 0 = register, 1 = memory. */ + uint8_t id; /* Operand Type ID 1. 4 bits. */ + uint8_t id2[2]; /* Operand Type ID 2. 16 bits. */ + uint64_t value; /* Value of operand (used only by memory operands). */ +}; + + +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_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 expr { + EXPR_PLUS, + EXPR_MINUS, + EXPR_LOW, + EXPR_HIGH, + EXPR_OR, + EXPR_LSHFT, + EXPR_RSHFT, + 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 +}; + +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_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 *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 lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg); + +extern uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg); +extern token *skip_expr(token *t, 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); +extern void assemble(line *ln, bytecount *bc, uint8_t dbg); +extern void fix_symtree(line *l); +extern void cleanup(); diff --git a/lexer/backup/asmmon.h b/lexer/backup/asmmon.h new file mode 100644 index 0000000..430d37c --- /dev/null +++ b/lexer/backup/asmmon.h @@ -0,0 +1,794 @@ +#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 op operand ; + + +struct tok { + token *next; /* Pointer to the next token. */ + uint8_t id; /* Token ID. */ + uint8_t type; /* Token type 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 { + 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; + 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 op { + uint8_t type; /* Operand Type. 0 = register, 1 = memory. */ + uint8_t id; /* Operand Type ID 1. 4 bits. */ + uint8_t id2[2]; /* Operand Type ID 2. 16 bits. */ + uint64_t value; /* Value of operand (used only by memory operands). */ +}; + + +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_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 expr { + EXPR_PLUS, + EXPR_MINUS, + EXPR_LOW, + EXPR_HIGH, + EXPR_OR, + EXPR_LSHFT, + EXPR_RSHFT, + 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 +}; + +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_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 *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 lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg); + +extern uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg); +extern token *skip_expr(token *t, 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); +extern void assemble(line *ln, bytecount *bc, uint8_t dbg); +extern void fix_symtree(line *l); +extern void cleanup(); diff --git a/lexer/backup/assemble.c b/lexer/backup/assemble.c new file mode 100644 index 0000000..28825d1 --- /dev/null +++ b/lexer/backup/assemble.c @@ -0,0 +1,975 @@ +#include "asmmon.h" + +#define AM_ADDR (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_INDX2 | AM_ZM2) + +static const uint64_t mem_size = 0x04000000; /* Size of address space. */ + +token *tok_global; + +uint8_t isexpr(uint8_t type, uint8_t dbg) { + switch (type) { + case EXPR_PLUS: + case EXPR_MINUS: + case EXPR_LOW: + case EXPR_HIGH: + case EXPR_OR: + case EXPR_LSHFT: + case EXPR_RSHFT: + return 1; + default: + return 0; + } +} + +uint8_t get_rs(token *t, uint8_t dbg) { + if (t->id == TOK_RS) { + return t->type; + } else { + return 0xFF; + } +} + +uint8_t get_of(token *t, uint8_t dbg) { + if (t->id == TOK_OF) { + return t->type; + } else { + return 0xFF; + } +} + +uint8_t get_ind(uint8_t mne, uint8_t am, uint8_t dbg) { + uint8_t base_idx = 0; + uint8_t offset = 0; + switch (mne) { + case CMP: base_idx = CMP_IND; break; + case CPB: base_idx = CPB_IND; break; + case JMP: base_idx = JMP_IND; break; + case JSR: base_idx = JSR_IND; break; + case LDA: base_idx = LDA_IND; break; + case LDB: base_idx = LDB_IND; break; + case LDX: base_idx = LDX_IND; break; + case LDY: base_idx = LDY_IND; break; + case STA: base_idx = STA_IND; break; + case STB: base_idx = STB_IND; break; + case STX: base_idx = STX_IND; break; + case STY: base_idx = STY_IND; break; + } + switch (am) { + case IND : offset = 0; break; + case INDY: offset += 1; break; + case INDX: offset += 2; break; + } + return base_idx + offset; +} + +uint8_t get_eind(uint8_t mne, uint8_t dbg) { + switch (mne) { + case DEC: return DEC_EIND; + case INC: return INC_EIND; + case STY: return STY_EIND; + case STA: return STA_EIND; + case STB: return STB_EIND; + case LDX: return LDX_EIND; + case STX: return STX_EIND; + case CPB: return CPB_EIND; + case CPX: return CPX_EIND; + case CPY: return CPY_EIND; + } + return 0xFF; +} + +static void write_value(uint64_t value, uint64_t address, uint8_t size) { + if (address < mem_size) { + size = (size > 7) ? 7 : size; + #if 1 + if (size < 7) { + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask); + } else { + *(uint64_t *)(addr+address) = value; + } + #else + memcpy(addr+address, &value, size+1); + #endif + } +} + +uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t end_expr, uint8_t stop_reg, uint8_t dbg) { + uint64_t value = 0; + uint64_t tmp_val = 0; + uint8_t type = EXPR_NONE; + uint8_t isstart = 1; + do { + if (t->id == TOK_EXPR) { + type = t->type; + t = t->next; + } + if (stop_reg && t->id == TOK_REG) { + break; + } + switch (t->id) { + case TOK_HEX: + case TOK_DEC: + case TOK_BIN: + case TOK_CHAR: tmp_val = t->qword; t = t->next; break; + case TOK_SYM: + case TOK_LABEL: + for (; t->sym && t->sym->isstruct && t->next && t->next->id == TOK_SYM; t = t->next); + tmp_val = (t->sym) ? t->sym->val : addr; + t = t->next; + break; + } + if (end_expr != 0xFF && type == end_expr) { + break; + } + switch (type) { + case EXPR_PLUS : (isstart) ? (value = tmp_val) : (value += tmp_val); break; + case EXPR_MINUS: (isstart) ? (value = -tmp_val) : (value -= tmp_val); break; + case EXPR_OR : value |= tmp_val; break; + case EXPR_LSHFT: value <<= tmp_val; break; + case EXPR_RSHFT: value >>= tmp_val; break; + case EXPR_LOW : + value = tmp_val; + switch (size) { + default: + case 2 : value &= 0xFFFFFFFF; break; + case 1 : value &= 0x0000FFFF; break; + case 0 : value &= 0x000000FF; break; + } + break; + case EXPR_HIGH : + value = tmp_val; + switch (size) { + default: + case 2 : value >>= 0x20; break; + case 1 : value >>= 0x10; break; + case 0 : value >>= 0x08; break; + } + break; + case EXPR_NONE : value = tmp_val; break; + } + isstart = 0; + if (dbg) { + printf("get_val(): Value: $%"PRIX64", Expression type: $%X, Expression Value: $%"PRIX64".\n", value, type, tmp_val); + } + } while (t && t->id == TOK_EXPR && isexpr(t->type, dbg)); + return value; +} + +token *skip_expr(token *t, uint8_t end_expr, uint8_t stop_reg, uint8_t dbg) { + do { + t = (t->id == TOK_EXPR) ? t->next : t; + if (stop_reg && t->id == TOK_REG) { + break; + } + switch (t->id) { + case TOK_HEX : + case TOK_DEC : + case TOK_BIN : + case TOK_CHAR : + case TOK_SYM : + case TOK_LABEL: t = t->next; break; + } + if (end_expr != 0xFF && t->id == TOK_EXPR && t->type == end_expr) { + break; + } + } while (t && t->id == TOK_EXPR && isexpr(t->type, dbg)); + return t; +} + + + +uint8_t get_directivesize(uint8_t type, uint8_t dbg) { + switch (type) { + case DIR_QWORD: return 3; + case DIR_DWORD: return 2; + case DIR_WORD : return 1; + case DIR_BYTE : return 0; + } + return 0; +} + +uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg) { + uint8_t is_struct = 0; + uint8_t done = 0; + uint8_t ismember = 0; + uint16_t size = 0; + uint16_t member_size = 0; + line *l = *ln; + symbol *strct = NULL; + token *tok = l->tok; + + for (uint8_t found = 0; tok && !found; tok = tok->next) { + switch (tok->id) { + case TOK_DIR: + is_struct = (tok->type == DIR_STRUCT); + found = (tok->type == DIR_STRUCT || tok->type == DIR_UNION); + break; + case TOK_STRUCT: is_struct = 1; + case TOK_UNION : found = 1; break; + } + } + if (tok != NULL) { + strct = tok->sym; + } + + if (l && l->next) { + l = l->next; + } + + for (; l && !done; l = l->next) { + token *t = l->tok; + token *start = t; + symbol *member; + for (; t && !done; t = t->next) { + switch (t->id) { + case TOK_MEMBER: ismember = 1; member = t->sym; break; + case TOK_DIR : + ismember = (t->type == DIR_STRUCT || t->type == DIR_UNION) ? 1 : ismember; + done = ((is_struct && t->type == DIR_ENDSTRUCT) || (!is_struct && t->type == DIR_ENDUNION)); + if (!done && ismember) { + switch (t->type) { + case DIR_BYTE : member_size = 1; break; + case DIR_WORD : member_size = 2; break; + case DIR_DWORD : member_size = 4; break; + case DIR_QWORD : member_size = 8; break; + case DIR_UNION : + case DIR_STRUCT: member_size = handle_struct(&l, address, offset, dbg); break; + case DIR_RES : member_size = get_val(t, address, 3, 0xFF, 0, dbg); t = skip_expr(t, 0xFF, 0, dbg); break; + } + if (member && t->type != DIR_UNION && t->type != DIR_STRUCT) { + member->val = offset; + } + if (is_struct) { + size += member_size; + offset += member_size; + } else if (size < member_size) { + size = member_size; + } + } + ismember = 0; + break; + } + } + if (done) { + break; + } + } + *ln = l; + if (strct != NULL) { + strct->val = size; + } + return size; +} + +uint64_t handle_directive(token *t, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg) { + union reg val; + uint8_t c = 0; + uint8_t tmp = 0; + uint8_t type = t->type; + uint64_t tmpaddr = address; + t = t->next; + for (; t; t = t->next) { + tmp = 0; + switch (t->id) { + case TOK_HEX: + case TOK_DEC: + case TOK_BIN: + case TOK_CHAR: + case TOK_SYM: + case TOK_LABEL: + val.u64 = get_val(t, tmpaddr, get_directivesize(type, dbg), 0xFF, 0, dbg); + switch (type) { + case DIR_QWORD: tmp = 8; break; + case DIR_DWORD: tmp = 4; break; + case DIR_WORD : tmp = 2; break; + case DIR_BYTE : tmp = 1; break; + } + write_value(val.u64, tmpaddr, tmp-1); + tmpaddr += tmp; + bc->datasize += tmp; + if (t->next && t->next->id == TOK_EXPR && isexpr(t->next->type, dbg)) { + t = skip_expr(t, 0xFF, 0, dbg); + } + break; + case TOK_STRING: + if (type == DIR_BYTE) { + for (uint16_t k = 0; t->str[k] != '\0'; k++) { + switch (t->str[k]) { + case '\\': + switch (t->str[k+1]) { + case 'n' : c = '\n'; break; + case 'r' : c = '\r'; break; + case 't' : c = '\t'; break; + case '\"': c = '\"'; break; + case '\'': c = '\''; break; + case '\\': c = '\\'; break; + case '0' : c = '\0'; break; + } + k++; + break; + default: c = t->str[k]; break; + } + if (isasm) { + addr[tmpaddr] = c; + } + tmpaddr++; + bc->datasize++; + } + if (isasm) { + addr[tmpaddr] = '\0'; + } + tmpaddr++; + bc->datasize++; + } + break; + } + if (t == NULL) { + break; + } + } + return tmpaddr; +} + +static uint8_t write_inst(uint8_t prefix, uint8_t ext_prefix, uint8_t opcode, uint64_t value, uint64_t address, uint8_t size, uint8_t isasm, uint8_t dbg) { + uint8_t inst_size = 0; + union reg ins; + if (prefix & 3) { + ins.u8[inst_size++] = prefix; + } + if ((ext_prefix & 0x0D) == 0x0D) { + ins.u8[inst_size++] = ext_prefix; + } + ins.u8[inst_size++] = opcode; + if (isasm) { + write_value(ins.u64, address, inst_size-1); + if (size) { + write_value(value, address+inst_size, size-1); + } + } + inst_size += size; + return inst_size; +} + +void get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t dbg) { + uint8_t op_type; + uint8_t op_inst; + switch (t->id) { + case TOK_OPCODE: + case TOK_EXTOP : + case TOK_ORTHO : + op_type = tok->id; + op_inst = tok->byte; + t = t->next; + break; + } + int i = 0; + int old_i = -1; + uint8_t expr_type = 0xFF; + uint8_t stop_reg = 0; + uint64_t value = 0; + uint8_t reg = 0; + uint8_t got_value = 0; + uint8_t is_sib = 0; + for (; t; t = t->next) { + switch (t->id) { + case TOK_HEX : + case TOK_DEC : + case TOK_BIN : + case TOK_SYM : + case TOK_LABEL: + if (!got_value) { + expr_type = (expr_type == 0xFF && t->next && t->next->id == TOK_EXPR) ? t->next->type : expr_type; + switch (expr_type) { + default : stop_reg = 1; break; + case EXPR_MUL : stop_reg = 0; break; + } + is_sib = !stop_reg; + value = get_val(t, address, (rs != 0xFF) ? rs : 0, (!stop_reg) ? expr_type : 0xFF, stop_reg, dbg); + got_value = 1; + } else { + got_value = 0; + } + /* Falls Through. */ + case TOK_MEM: + if (old_i != i) { + op[i].type = 1; /* Set type to memory. */ + op[i].id = (t->id == TOK_MEM) ? t->type : op[i].id; + op[i].id = (is_sib) ? MEM_SIB : op[i].id; + op[i].id2[0] = (is_sib) ? value : op[i].id2[0]; + old_i = i; + } else { + } + op[i].value = (!is_sib && got_value) ? value : op[i].value; + if (stop_reg && got_value) { + t = skip_expr(t, 0xFF, stop_reg, dgb); + } + i += (t->next && t->next->id != TOK_EXPR); + break; + case TOK_REG: + if (old_i != i) { + op[i].type = 0; /* Set type to register. */ + op[i].id = t->type; + old_i = i; + } else { + op[i].id = (op[i].id == MEM_IND) ? MEM_RIND : op[i].id; + is_sib = (op[i].id == MEM_SIB); + op[i].id2[is_sib] = (t->type << (reg*4)); + reg++; + reg = (reg > 1) ? 0 : reg; + } + i += (t->next && t->next->id != TOK_EXPR); + break; + case TOK_EXPR: + expr_type = t->type; + switch (expr_type) { + default : stop_reg = 1; break; + case EXPR_MUL : stop_reg = 0; break; + } + if (!got_value) { + value = get_val(t, address, (rs != 0xFF) ? rs : 0, (!stop_reg) ? expr_type : 0xFF, stop_reg, dbg); + got_value = 1; + } else { + got_value = 0; + } + break; + } + } +} + +uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg) { + union reg val; + uint8_t opsize; + uint8_t id; + uint8_t instr; + uint8_t opcode; + uint8_t ext_prefix = 0; + uint8_t type; + uint32_t am = 0; + uint8_t tmp = 0; + uint8_t prefix = 0; + uint8_t rs = 0; + uint8_t of = 0; + uint8_t tmp_prefix = 0; + uint8_t inst_size = 0; + val.u64 = 0; + instruction ins; + operand op[2]; + memset(op, 0xFF, sizeof(op)); + + for (; t; t = t->next) { + if (t->id == TOK_OPCODE || t->id == TOK_EXTOP) { + id = t->id; + instr = t->byte; + type = t->type; + } else { + break; + } + tmp = 0; + opsize = 1; + opcode = 0; + if (t->next) { + rs = get_rs(t->next, dbg); + t = (rs != 0xFF) ? t->next : t; + if (t->next) { + of = get_of(t->next, dbg); + t = (of != 0xFF) ? t->next : t; + } + } + get_operands(t, op, address, rs, dbg); + if (rs != 0xFF || of != 0xFF) { + tmp_prefix = (rs != 0xFF) ? (rs << 0) : tmp_prefix; + tmp_prefix |= (of != 0xFF) ? (of << 2) : tmp_prefix; + } + prefix = (tmp_prefix) ? ((tmp_prefix << 4) | 3) : 0; + uint8_t isincdec = (instr == INC || instr == DEC); + uint8_t isimplied = (op[0].type == 0xFF); + switch (id) { + case TOK_OPCODE: ins = inst[instr]; break; + case TOK_EXTOP : ins = ext_inst[instr]; break; + case TOK_ORTHO : ins = ortho_inst[instr]; break; + } + am = ins.am; + uint8_t is_eind = (op[0].type && op[0].id == MEM_RIND && op[0].id2[0] == REG_E); + uint8_t is_mem = (op[0].type && op[0].id != MEM_IMM); + uint8_t is_idx = (is_mem && !op[1].type && (op[1].id == REG_X || op[1].id == REG_Y)); + if (id == TOK_EXTOP || (id == TOK_OPCODE && is_eind)) { + ext_prefix = 0x0D; + } else if (!is_idx) { + ext_prefix = 0x1D; + } + if ((am & AM_IMPL) && isimplied) { + type = IMPL; + } else { + if (ins.am & AM_REL) { + type = REL; + } + } + opcode = ins.op; + uint64_t saveaddr = address; + uint64_t max_val = 0; + uint8_t i = 0; + uint8_t j = 1; + uint8_t type2 = 0xFF; + + switch (type) { + case REG_B: + case IMPL: + case REG_E: + if (id == TOK_OPCODE && instr == CPS) { + rs = 0; + } + if ((am & (AM_IMPL|AM_BREG|AM_EIND|AM_EIND2))) { + if ((type == EIND) && (am & AM_EIND|AM_EIND2)) { + int eind_type = ((am & AM_EIND2) != 0); + switch (eind_type) { + case 0: opcode = (id == TOK_EXTOP) ? opcode+0x14 : opcode+0x10; break; + case 1: opcode = (id == TOK_EXTOP) ? opcode+0x01 : eind_base_ops[get_eind(instr, dbg)]; break; + } + } + opcode = ((am & AM_BREG) && type == BREG) ? opcode+0x14 : opcode; + } + break; + case REL: + case IMM: + if (am & (AM_IMM|AM_REL|AM_ORTHO|AM_ORTHO2)) { + rs = (rs != 0xFF) ? rs : 0; + tmp = (1 << rs); + if (type == REL) { + uint64_t max_sign = 0; + uint8_t offset = 1; + uint64_t tmp_val; + tmp_val = val.u64; + offset += (prefix != 0); + tmp_val -= offset+tmp; + tmp_val -= address; + switch (rs) { + default: max_sign = (int8_t )(1 << 7); break; + case 1 : max_sign = (int16_t)(1 << 15); break; + case 2 : max_sign = (int32_t)(1 << 31); break; + case 3 : max_sign = (int64_t)((uint64_t)1 << 63); break; + } + if ((int64_t)tmp_val > ~(int64_t)max_sign || (int64_t)tmp_val < (int64_t)max_sign) { + offset += (!rs); + rs += (rs <= 3); + tmp = (1 << rs); + tmp_val = val.u64; + tmp_val -= offset+tmp; + tmp_val -= address; + prefix = ((rs << 4) | 3); + } + val.u64 = tmp_val; + } + } + break; + default: + if (of != 0xFF) { + i = 8; + for (; i <= 64; i += 8, j++) { + max_val |= ((uint64_t)1 << (i-1)); + if ((int64_t)val.u64 >= ~(int64_t)(max_val) || (int64_t)val.u64 <= (int64_t)(max_val)) { + opsize = j; + break; + } + } + } else { + for (; i <= 64; i += 8, j++) { + max_val |= (0xFF << i); + if (val.u64 <= max_val) { + opsize = j; + break; + } + } + } + type2 = type; + if (type == 0xFF || (id == TOK_EXTOP && type2 != 0xFF)) { + switch (opsize-1) { + case 0: case 2: case 5: case 3: type = ZM ; break; + case 1: case 4: case 6: case 7: type = ABS; break; + } + } + switch (type2) { + case ZMX : type = (type == ABS) ? ABSX : type2; break; + case ZMY : type = (type == ABS) ? ABSY : type2; break; + case IND : type = (type == ABS) ? AIND : type2; break; + case INDX: type = (type == ABS) ? AINDX : type2; break; + case INDY: type = (type == ABS) ? AINDY : type2; break; + } + if (opsize) { + uint8_t is_abs = 0; + switch (type) { + case ABS : + case ABSX : + case ABSY : + case AIND : + case AINDX: + case AINDY: is_abs = 1; break; + + } + if (!is_abs || (type2 != 0xFF && type == type2)) { + switch (opsize) { + case 2: opsize = 3; break; + case 5: opsize = 6; break; + } + } + prefix |= amp[opsize-1]; + } + if (am & AM_ADDR|AM_ORTHO|AM_ORTHO2) { + switch (type) { + case ZM: + if (am & AM_ZM) { + opcode += 0x04; + } else if (am & AM_ZM2) { + opcode += 0x20; + } + break; + case ZMX: + if (am & AM_ZMX) { + opcode += (id == TOK_OPCODE) ? 0x06 : 0x54; + } + break; + case ZMY: + if (am & AM_ZMY) { + opcode += 0x14; + } + break; + case INDX: + if (am & AM_INDX) { + opcode += (id == TOK_OPCODE) ? 0x16 : 0x94; + break; + } + /* Falls Through. */ + case IND: + case INDY: + if ((id == TOK_OPCODE) && (am & (AM_IND|AM_INDY|AM_INDX2))) { + opcode = ind_ops[get_ind(instr, type, dbg)]; + } else { + opcode += (type == IND) ? 0x44 : 0x84; + } + break; + case ABS: + if (am & AM_ABS) { + opcode += 0x10; + } + break; + case ABSX: + if (am & AM_ABX) { + opcode += 0x50; + } + break; + case ABSY: + if (am & AM_ABY) { + opcode += 0x00; + } + break; + case AIND: + if (am & AM_AIND) { + opcode += 0x40; + } + break; + case AINDX: + if (am & AM_AINDX) { + opcode += 0x90; + } + break; + case AINDY: + if (am & AM_AINDY) { + opcode += 0x80; + } + break; + + } + tmp = opsize; + } + break; + } + inst_size = write_inst(prefix, ext_prefix, opcode, val.u64, address, tmp, isasm, dbg); + address += inst_size; + bc->progsize += inst_size; + } + return address; +} + +uint64_t parse_tokens(token *t, line **l, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg) { + for (; t; t = t->next) { + switch (t->id) { + case TOK_DIR: + switch (t->type) { + case DIR_STRUCT: + case DIR_UNION : handle_struct(l, address, 0, dbg); break; + case DIR_RES: t = t->next; address += get_val(t, address, 3, 0xFF, 0, dbg); break; + case DIR_ORG: t = t->next; address = get_val(t, address, 3, 0xFF, 0, dbg); break; + case DIR_BYTE: + case DIR_WORD: + case DIR_DWORD: + case DIR_QWORD: address = handle_directive(t, bc, isasm, address, dbg); break; + } + break; + case TOK_EXTOP : + case TOK_OPCODE: address = handle_opcode(t, bc, isasm, address, dbg); break; + case TOK_COMMENT: break; + } + } + return address; +} + +token *make_token(uint8_t id, uint8_t type, uint8_t space, uint8_t tab, uint64_t value, char *str, symbol *s) { + token *new_tok = malloc(sizeof(token)); + (last_tok) ? (last_tok->next = new_tok) : (tokens = new_tok); + + new_tok->id = id; + new_tok->type = type; + + new_tok->tab = tab; + new_tok->space = space; + + new_tok->subtab = 0; + new_tok->subspace = 0; + + new_tok->digits = 0; + + if (s) { + new_tok->sym = s; + } else if (str[0]) { + new_tok->str = str; + } else { + new_tok->qword = value; + } + new_tok->next = NULL; + last_tok = new_tok; + return new_tok; +} + +void assemble(line *ln, bytecount *bc, uint8_t dbg) { + uint64_t address = 0; + line *l = ln; + for (int i = 0; i < 2; i++) { + l = ln; + for (; l; l = l->next) { + l->addr = address; + token *t = l->tok; + address = parse_tokens(t, &l, bc, 0, address, dbg); + } + l = ln; + for (; l; l = l->next) { + address = l->addr; + token *t = l->tok; + for (; t; t = t->next) { + if (t->id == TOK_LABEL && t->sym->val != address) { + t->sym->val = l->addr; + } + } + } + } + l = ln; + bc->progsize = 0; + bc->datasize = 0; + for (; l; l = l->next) { + address = parse_tokens(l->tok, &l, bc, 1, address, dbg); + } +} + +static void find_dupsym() { + symbol *root = symbols; + symbol *s = symbols; + for (; s; s = s->next) { + root = symbols; + for (int i = 0; root; root = root->next) { + if (root == s) { + i++; + } + if (i > 1) { + printf("Found duplicate symbol, s->name: %s, root->name: %s\n", s->name, root->name); + i = 0; + } + } + } +} + +static symbol *find_fixup(token *t) { + fixup* f = fixups; + for (; f && t != f->t; f = f->next); + return (f && t == f->t) ? f->s : NULL; +} + + +static void print_symval(symbol *s) { + if (s) { + if (s->down) { + print_symval(s->down); + } + if (s->name) { + printf("s->name: %s, s->val: $%"PRIX64"\n", s->name, s->val); + } + print_symval(s->next); + } +} + +static void print_symtree(symbol *s, int depth) { + if (s) { + if (s->name != NULL) { + for (int i = depth; i; i--) { + printf("|%s", (i > 1) ? " " : "--"); + } + printf("%s: $%"PRIX64"\n", s->name, s->val); + } + if (s->down != NULL) { + print_symtree(s->down, depth+1); + } + print_symtree(s->next, depth); + } +} + +void fix_symtree(line *l) { + symbol *s = symbols; + symbol *cur_sym = NULL; + symbol *sym_struct = NULL; + symbols = NULL; + last_sym = NULL; + int islocal = 0; + int isanon = 0; + int is_struct = 0; + int is_structsym = 0; + for (; l; l = l->next) { + token *t = l->tok; + token *lt = NULL; + for (; t; t = t->next) { + int ismember = (t->id == TOK_MEMBER); + switch (t->id) { + case TOK_STRUCT: + case TOK_UNION : islocal = !(is_struct == 1 && lt && lt->id == TOK_DIR); + case TOK_SYM : + if (t->id == TOK_SYM && t != l->tok) { + break; + } + case TOK_MEMBER: + case TOK_LABEL : + if (symbols) { + (!islocal && s && !s->up) ? (last_sym = s) : (last_loc = s); + } + if (((t->type == 1 || ismember) && !islocal) || (islocal && ismember && is_structsym)) { + is_structsym = 0; + last_loc = NULL; + islocal = 1; + cur_sym = s; + s->down = t->sym; + s->down->up = s; + s = s->down; + if (s) { + s->next = NULL; + s->prev = NULL; + s->down = NULL; + } + locals = s; + } else if ((islocal || t->type == 0)) { + if (t->type == 0 && !is_struct && islocal && !ismember) { + islocal = 0; + if (s) { + s->up->down = locals; + s = s->up; + } + } + symbol *tmp = s; + s = t->sym; + if (s) { + s->prev = (tmp && tmp != s) ? tmp : NULL; + s->up = (s->prev) ? s->prev->up : s->up; + } + if (s && s->next) { + s->next = NULL; + } + } + if (!islocal) { + last_loc = NULL; + (last_sym) ? (last_sym->next = s) : (symbols = s); + cur_sym = s; + if (last_sym) { + last_sym->next->prev = last_sym; + last_sym->next->up = last_sym->up; + last_sym->next->down = NULL; + } + } else { + (last_loc) ? (last_loc->next = s) : (locals = s); + if (last_loc) { + last_loc->next->prev = last_loc; + last_loc->next->up = last_loc->up; + last_loc->next->down = NULL; + } else { + locals->prev = NULL; + locals->down = NULL; + } + } + break; + case TOK_DIR: + if (t->type == DIR_STRUCT || t->type == DIR_UNION) { + is_struct++; + is_structsym = (t->next && (t->next->id == TOK_STRUCT || t->next->id == TOK_UNION)); + if ((!is_structsym) || (isanon && is_structsym)) { + isanon++; + } + sym->name = NULL; + } + s = s->next; + free(sym); + sym = NULL; + free_symbols(s); + } +} + +static inline void free_fixups(fixup *f) { + fixup *fix; + if (f != NULL) { + fix = f; + f = f->next; + free(fix); + fix = NULL; + free_fixups(f); + } +} + +uint64_t get_tokmem(token *t) { + uint64_t i = 0; + for (; t; t = t->next, i++); + return i*sizeof(token); +} + +void get_linemem(line *l) { + uint64_t i = 0; + uint64_t j = 0; + for (; l; j += get_tokmem(l->tok), l = l->next, i++); + printf("Bytes per line: %"PRIu64", Bytes per token: %"PRIu64", Total size of line table in bytes: %"PRIu64"\n", sizeof(line), sizeof(token), j+(i*sizeof(line))); +} + +void cleanup() { + uint16_t i; + if (lines) { + /*get_linemem(lines);*/ + /*fix_symtree(lines);*/ + free_lines(lines); + lines = NULL; + } + if (symbols) { + /*print_symtree(symbols, 0);*/ + free_symbols(symbols); + symbols = NULL; + } + if (fixups) { + free_fixups(fixups); + fixups = NULL; + } + while (i < stridx || i < comidx) { + if (i < stridx && string[i]) { + free(string[i]); + string[i] = NULL; + } + if (i < comidx && comment[i]) { + free(comment[i]); + comment[i] = NULL; + } + i++; + } +} diff --git a/lexer/backup/enums.h b/lexer/backup/enums.h new file mode 100644 index 0000000..07338ee --- /dev/null +++ b/lexer/backup/enums.h @@ -0,0 +1,540 @@ +enum am { + /* Part of Base ISA. */ + IMM, /* Immediate Data. */ + ZM, /* Zero Matrix. */ + ZMX, /* Zero Matrix, indexed with X. */ + ZMY, /* Zero Matrix, indexed with Y. */ + IND, /* Indirect. */ + INDX, /* Indexed Indirect. */ + INDY, /* Indirect Indexed. */ + ABS, /* Absolute. */ + REL, /* Relative to Program Counter. */ + BREG, /* B Register. */ + IMPL, /* Implied. */ + /* Part of Base Extension. */ + ABSX, /* Absolute, Indexed with X. */ + ABSY, /* Absolute, Indexed with Y. */ + AIND, /* Absolute Indirect. */ + AINDX, /* Absolute Indexed Indirect. */ + AINDY, /* Absolute Indirect Indexed. */ + EIND, /* Effective Address Register, Indirect. */ +}; + +/* Part of the Orthogonal Extension. */ +enum ortho_reg { + REG_A, + REG_B, + REG_X, + REG_Y, + REG_E, + REG_C, + REG_D, + REG_S, + REG_F, + REG_SP, + REG_BP, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15, +}; + +enum ortho_mem { + MEM_ABS, /* Absolute. */ + MEM_ZM, /* Zero Matrix. */ + MEM_ABSR, /* Absolute, Indexed with register. */ + MEM_ZMR, /* Zero Matrix, Indexed with register. */ + MEM_ZINDR, /* Zero Matrix, Indirect Indexed Register. */ + MEM_ZRIND, /* Zero Matrix, Indexed Indirect Register. */ + MEM_AINDR, /* Absolute, Indirect Indexed Register. */ + MEM_ARIND, /* Absolute, Indexed Indirect Register. */ + MEM_RIND, /* Register Indirect. */ + MEM_SIB, /* Scale Index Base. */ +}; + +enum mne { + ADC, + AND, + ASR, + BCC, + BCS, + BEQ, + BNE, + BNG, + BPO, + BRA, + BRK, + BVC, + BVS, + CLC, + CLI, + CLV, + CMP, + CPB, + CPS, + CPX, + CPY, + DEB, + DEC, + DEX, + DEY, + DIV, + INB, + INC, + INX, + INY, + JMP, + JSR, + LDA, + LDB, + LDX, + LDY, + LSL, + LSR, + MUL, + NOP, + ORA, + PHA, + PHB, + PHP, + PHX, + PHY, + PLA, + PLB, + PLP, + PLX, + PLY, + ROL, + ROR, + RTI, + RTS, + SBC, + SEC, + SEI, + STA, + STB, + STX, + STY, + TAB, + TAX, + TAY, + TBA, + TSX, + TXA, + TXS, + TXY, + TYA, + TYX, + WAI, + XOR +}; + +enum ext_mne { + LEA, + PEA, + ADD, + SUB, + ADE, + SBE, + ADS, + SBS, + NOT, + LLM, + LRM, + RLM, + RRM, + ARM, + PHE, + PLE, + CPE, + ICE, + LDS, + DEE, + INE, + DES, + INS, + STS, + STE, + STZ, + SCO, + ECO, + CLZ, + CLO, + BIT, + MMV, + SWP, + PCN, + REP, + REQ, + RNE, + LNG, + LPO, + LCS, + LCC, + LEQ, + LNE, + SNG, + SPO, + SCS, + SCC, + SEQ, + SNE +}; + +enum ortho_mne { + MNG, + MPO, + MCS, + MCC, + MEQ, + MNE, + MVS, + MVC, + OR , + MOV, + IML, + IDV, + PSH, + PUL, + NEG, + SET +}; + +enum base_isa { + CPS_IMP = 0x00, /* Clear Processor Status. */ + ADC_IMM = 0x01, /* ADd with Carry. */ + ROR_IMM = 0x02, /* ROtate Right. */ + CPB_IMM = 0x04, /* ComPare B register. */ + ADC_Z = 0x05, /* ADC Zero Matrix. */ + ROR_Z = 0x06, /* ROR Zero Matrix. */ + CPB_Z = 0x08, /* CPB Zero Matrix. */ + CLC_IMP = 0x09, /* CLear Carry flag. */ + TAB_IMP = 0x0A, /* Transfer Accumulator to B. */ + STY_Z = 0x0C, /* STore Y register. */ + JMP_AB = 0x10, /* JMP Absolute. */ + ADC_AB = 0x11, /* ADC Absolute. */ + ROR_AB = 0x12, /* ROR Absolute. */ + CPB_AB = 0x14, /* CPB Absolute. */ + ADC_B = 0x15, /* ADC B Register. */ + ROR_B = 0x16, /* ROR B Register. */ + STY_AB = 0x18, /* STY Absolute. */ + SEC_IMP = 0x19, /* SEt Carry flag. */ + TBA_IMP = 0x1A, /* Transfer B to Accumulator. */ + JMP_Z = 0x20, /* JuMP to memory location. */ + SBC_IMM = 0x21, /* SuBtract with Carry. */ + MUL_IMM = 0x22, /* MULtiply accumulator. */ + CPX_IMM = 0x24, /* ComPare X register. */ + SBC_Z = 0x25, /* SBC Zero Matrix. */ + MUL_Z = 0x26, /* MUL Zero Matrix. */ + CPX_Z = 0x28, /* CPX Zero Matrix. */ + CLI_IMP = 0x29, /* CLear Interupt flag. */ + TAY_IMP = 0x2A, /* Transfer Accumulator to Y. */ + STA_Z = 0x2C, /* STore Accumulator. */ + STA_ZX = 0x2E, /* STA Zero Marrix, Indexed with X. */ + JSR_AB = 0x30, /* JSR Absolute. */ + SBC_AB = 0x31, /* SBC Absolute. */ + MUL_AB = 0x32, /* MUL Absolute. */ + CPX_AB = 0x34, /* CPX Absolute. */ + SBC_B = 0x35, /* SBC B Register. */ + MUL_B = 0x36, /* MUL B Register. */ + STA_AB = 0x38, /* STA Absolute. */ + SEI_IMP = 0x39, /* SEt Interupt flag. */ + TYA_IMP = 0x3A, /* Transfer Y to Accumulator. */ + STA_ZY = 0x3C, /* STA Zero Marrix, Indexed with Y. */ + STA_IX = 0x3E, /* STA Indexed Indirect. */ + JSR_Z = 0x40, /* Jump to SubRoutine. */ + AND_IMM = 0x41, /* bitwise AND with accumulator. */ + DIV_IMM = 0x42, /* DIVide with accumulator. */ + CPY_IMM = 0x44, /* ComPare Y register. */ + AND_Z = 0x45, /* AND Zero Matrix. */ + DIV_Z = 0x46, /* DIV Zero Matrix. */ + CPY_Z = 0x48, /* CPY Zero Matrix. */ + CLV_IMP = 0x49, /* CLear oVerflow flag. */ + TAX_IMP = 0x4A, /* Transfer Accumulator to X. */ + STB_Z = 0x4C, /* STore B register. */ + STB_ZX = 0x4E, /* STB Zero Marrix, Indexed with X. */ + RTS_IMP = 0x50, /* ReTurn from Subroutine. */ + AND_AB = 0x51, /* AND Absolute. */ + DIV_AB = 0x52, /* DIV Absolute. */ + CPY_AB = 0x54, /* CPY Absolute. */ + AND_B = 0x55, /* AND B Register. */ + DIV_B = 0x56, /* DIV B Register. */ + STB_AB = 0x58, /* STB Absolute. */ + WAI_IMP = 0x59, /* WAit for Interrupt. */ + TXA_IMP = 0x5A, /* Transfer X to Accumulator. */ + STB_ZY = 0x5C, /* STB Zero Marrix, Indexed with Y. */ + STB_IX = 0x5E, /* STB Indexed Indirect. */ + RTI_IMP = 0x60, /* ReTurn from Interrupt. */ + ORA_IMM = 0x61, /* bitwise OR with Accumulator. */ + ASR_IMM = 0x62, /* Arithmetic Shift Right. */ + LDX_IMM = 0x64, /* LoaD X register. */ + ORA_Z = 0x65, /* ORA Zero Matrix. */ + ASR_Z = 0x66, /* ASR Zero Matrix. */ + LDX_Z = 0x68, /* LDX Zero Matrix. */ + BRK_IMP = 0x69, /* BReaK. */ + TYX_IMP = 0x6A, /* Transfer Y to X. */ + STX_Z = 0x6C, /* STore X register. */ + PHP_IMP = 0x6E, /* PusH Processor status to stack. */ + BPO_REL = 0x70, /* Branch if POsitive. */ + ORA_AB = 0x71, /* ORA Absolute. */ + ASR_AB = 0x72, /* ASR Absolute. */ + LDX_AB = 0x74, /* LDX Absolute. */ + ORA_B = 0x75, /* ORA B Register. */ + ASR_B = 0x76, /* ASR B Register. */ + STX_AB = 0x78, /* STX Absolute. */ + DEY_IMP = 0x79, /* DEcrement Y register. */ + TXY_IMP = 0x7A, /* Transfer X to Y. */ + CPB_IN = 0x7C, /* CPB Indirect */ + PLP_IMP = 0x7E, /* PuLl Processor status from stack. */ + BNG_REL = 0x80, /* Branch if NeGative. */ + XOR_IMM = 0x81, /* bitwise XOR with accumulator. */ + CMP_IMM = 0x82, /* CoMPare accumulator. */ + DEC_IMP = 0x84, /* DECrement accumulator. */ + XOR_Z = 0x85, /* XOR Zero Matrix. */ + CMP_Z = 0x86, /* CMP Zero Matrix. */ + DEC_Z = 0x88, /* DEC Zero Matrix. */ + INY_IMP = 0x89, /* INcrement Y register. */ + TSX_IMP = 0x8A, /* Transfer Stack pointer to X. */ + CMP_IN = 0x8C, /* CMP Indirect */ + PHA_IMP = 0x8E, /* PusH Accumulator to stack. */ + BCS_REL = 0x90, /* Branch if Carry Set. */ + XOR_AB = 0x91, /* XOR Absolute. */ + CMP_AB = 0x92, /* CMP Absolute. */ + DEC_AB = 0x94, /* DEC Absolute. */ + XOR_B = 0x95, /* XOR B Register. */ + CMP_B = 0x96, /* CMP B Register. */ + DEB_IMP = 0x99, /* Decrement B register. */ + TXS_IMP = 0x9A, /* Transfer X to Stack pointer. */ + STY_IN = 0x9C, /* STY Indirect */ + PLA_IMP = 0x9E, /* PuLl Accumulator from stack. */ + BCC_REL = 0xA0, /* Branch if Carry Clear. */ + LSL_IMM = 0xA1, /* Logical Shift Left. */ + LDY_IMM = 0xA2, /* LoaD Y register. */ + INC_IMP = 0xA4, /* INCrement accumulator. */ + LSL_Z = 0xA5, /* LSL Zero Matrix. */ + LDY_Z = 0xA6, /* LDY Zero Matrix. */ + INC_Z = 0xA8, /* INC Zero Matrix. */ + INB_IMP = 0xA9, /* Increment B register. */ + CMP_IX = 0xAA, /* CMP Indexed Indirect. */ + LDY_IN = 0xAC, /* LDY Indirect */ + PHB_IMP = 0xAE, /* PusH B register to stack. */ + BEQ_REL = 0xB0, /* Branch if EQual. */ + LSL_AB = 0xB1, /* LSL Absolute. */ + LDY_AB = 0xB2, /* LDY Absolute. */ + INC_AB = 0xB4, /* INC Absolute. */ + LSL_B = 0xB5, /* LSL B Register. */ + DEX_IMP = 0xB9, /* DEcrement X register. */ + CPB_IX = 0xBA, /* CPB Indexed Indirect. */ + LDX_IN = 0xBC, /* LDX Indirect */ + PLB_IMP = 0xBE, /* PuLl B register to stack. */ + BNE_REL = 0xC0, /* Branch if Not Equal. */ + LSR_IMM = 0xC1, /* Logical Shift Right. */ + LDA_IMM = 0xC2, /* LoaD Accumulator. */ + LDA_IN = 0xC4, /* LDA Indirect */ + LSR_Z = 0xC5, /* LSR Zero Matrix. */ + LDA_Z = 0xC6, /* LDA Zero Matrix. */ + LDA_ZX = 0xC8, /* LDA Zero Marrix, Indexed with X. */ + INX_IMP = 0xC9, /* INcrement X register. */ + STA_IY = 0xCA, /* STA Indirect Indexed. */ + STX_IN = 0xCC, /* STX Indirect */ + PHY_IMP = 0xCE, /* PusH Y register to stack. */ + BVS_REL = 0xD0, /* Branch if oVerflow Set. */ + LSR_AB = 0xD1, /* LSR Absolute. */ + LDA_AB = 0xD2, /* LDA Absolute. */ + STA_IN = 0xD4, /* STA Indirect */ + LSR_B = 0xD5, /* LSR B Register. */ + LDA_ZY = 0xD6, /* LDA Zero Marrix, Indexed with Y. */ + LDA_IX = 0xD8, /* LDA Indexed Indirect. */ + LDA_IY = 0xD9, /* LDA Indirect Indexed. */ + STB_IY = 0xDA, /* STB Indirect Indexed. */ + JSR_IN = 0xDC, /* JSR Indirect */ + PLY_IMP = 0xDE, /* PuLl Y register from stack. */ + BVC_REL = 0xE0, /* Branch if oVerflow Clear. */ + ROL_IMM = 0xE1, /* ROtate Left. */ + LDB_IMM = 0xE2, /* LoaD B register. */ + LDB_IN = 0xE4, /* LDB Indirect */ + ROL_Z = 0xE5, /* ROL Zero Matrix. */ + LDB_Z = 0xE6, /* LDB Zero Matrix. */ + LDB_ZX = 0xE8, /* LDB Zero Marrix, Indexed with X. */ + LDB_IY = 0xE9, /* LDB Indirect Indexed. */ + NOP_IMP = 0xEA, /* No OPeration. */ + JMP_IN = 0xEC, /* JMP Indirect */ + PHX_IMP = 0xEE, /* PusH X register to stack. */ + BRA_REL = 0xF0, /* BRanch Always. */ + ROL_AB = 0xF1, /* ROL Absolute. */ + LDB_AB = 0xF2, /* LDB Absolute. */ + STB_IN = 0xF4, /* STB Indirect */ + ROL_B = 0xF5, /* ROL B Register. */ + LDB_ZY = 0xF6, /* LDB Zero Marrix, Indexed with Y. */ + LDB_IX = 0xF8, /* LDB Indexed Indirect. */ + CMP_IY = 0xF9, /* CMP Indirect Indexed. */ + CPB_IY = 0xFA, /* CPB Indirect Indexed. */ + PLX_IMP = 0xFE /* PuLl X register from stack. */ +}; + +enum base_ext { + LEA_AY = 0x03, /* LEA Absolute, indexed with Y. */ + ADD_IMM = 0x06, /* ADD without carry. */ + LEA_Z = 0x07, /* Load Effective Address. */ + CPE_IMM = 0x08, /* ComPare Effective address register. */ + CLZ_Z = 0x09, /* Count Leading Zeros. */ + ADD_Z = 0x0A, /* ADD Zero Matrix. */ + STB_E = 0x0B, /* STB E Indirect. */ + CPE_Z = 0x0C, /* CPE Zero Matrix. */ + LNG_IMM = 0x0D, /* Load accumulator, if NeGative. */ + LNG_E = 0x0E, /* LNG E Indirect. */ + JMP_E = 0x10, /* JMP E Indirect. */ + ADC_E = 0x11, /* ADC E Indirect. */ + ROR_E = 0x12, /* ROR E Indirect. */ + LEA_AB = 0x13, /* LEA Absolute. */ + CLZ_AB = 0x15, /* CLZ Absolute. */ + ADD_AB = 0x16, /* ADD Absolute. */ + LEA_ZY = 0x17, /* LEA Zero Matrix, indexed with Y. */ + CPE_AB = 0x18, /* CPE Absolute. */ + CLZ_E = 0x19, /* CLZ E Indirect. */ + ADD_E = 0x1A, /* ADD E Indirect. */ + LDX_E = 0x1B, /* LDX E Indirect. */ + SNG_E = 0x1E, /* Store accumulator, if NeGative. */ + PEA_AY = 0x23, /* PEA Absolute, indexed with Y. */ + SUB_IMM = 0x26, /* SUBtract without carry. */ + PEA_Z = 0x27, /* Push Effective Address. */ + CLO_Z = 0x29, /* Count Leading Ones. */ + SUB_Z = 0x2A, /* SUB Zero Matrix. */ + STX_E = 0x2B, /* STX E Indirect. */ + ICE_Z = 0x2C, /* Interlocked Compare, and Exchange. */ + LPO_IMM = 0x2D, /* Load accumulator, if POsitive. */ + LPO_E = 0x2E, /* LPO E Indirect. */ + JSR_E = 0x30, /* JSR E Indirect. */ + SBC_E = 0x31, /* SBC E Indirect. */ + MUL_E = 0x32, /* MUL E Indirect. */ + PEA_AB = 0x33, /* PEA Absolute. */ + CLO_AB = 0x34, /* CLO Absolute. */ + SUB_AB = 0x35, /* SUB Absolute. */ + PEA_ZY = 0x37, /* PEA Zero Matrix, indexed with Y. */ + ICE_AB = 0x38, /* ICE Absolute. */ + CLO_E = 0x39, /* CLO E Indirect. */ + SUB_E = 0x3A, /* SUB E Indirect. */ + CPB_E = 0x3B, /* CPB E Indirect. */ + ICE_E = 0x3C, /* ICE E Indirect. */ + SPO_E = 0x3E, /* Store accumulator, if POsitive. */ + LDS_IMM = 0x40, /* LoaD Stack pointer. */ + LEA_AI = 0x43, /* LEA Absolute Indirect. */ + LDS_Z = 0x44, /* LDS Zero Matrix. */ + ADE_IMM = 0x46, /* ADd Effective address register. */ + LEA_IN = 0x47, /* LEA Indirect. */ + BIT_Z = 0x49, /* BIt Test. */ + ADE_Z = 0x4A, /* ADE Zero Matrix. */ + CPX_E = 0x4B, /* CPX E Indirect. */ + LLM_Z = 0x4C, /* Logical shift Left, on Memory. */ + LCS_IMM = 0x4D, /* Load accumulator, if Carry Set. */ + LCS_E = 0x4E, /* LCS E Indirect. */ + LDS_AB = 0x50, /* LDS Absolute. */ + AND_E = 0x51, /* AND E Indirect. */ + DIV_E = 0x52, /* DIV E Indirect. */ + LEA_AX = 0x53, /* LEA Absolute, indexed with X. */ + LDS_E = 0x54, /* LDS E Indirect. */ + BIT_AB = 0x55, /* BIT Absolute. */ + ADE_AB = 0x56, /* ADE Absolute. */ + LEA_ZX = 0x57, /* LEA Zero Matrix, indexed with X. */ + LLM_AB = 0x58, /* LLM Absolute. */ + BIT_E = 0x59, /* BIT E Indirect. */ + CPY_E = 0x5B, /* CPY E Indirect. */ + LLM_E = 0x5C, /* LLM E Indirect. */ + SCS_E = 0x5E, /* Store accumulator, if Carry Set. */ + SCO_IMM = 0x60, /* Start one, or more COre(s). */ + PEA_AI = 0x63, /* PEA Absolute Indirect. */ + SCO_Z = 0x64, /* SCO Zero Matrix. */ + SBE_IMM = 0x66, /* SuBtract Effective address register. */ + PEA_IN = 0x67, /* PEA Indirect. */ + SBE_Z = 0x6A, /* SBE Zero Matrix. */ + PHE_IMP = 0x6B, /* PusH Effective address register to stack. */ + LRM_Z = 0x6C, /* Logical shift Right, on Memory. */ + LCC_IMM = 0x6D, /* Load accumulator, if Carry Clear. */ + LCC_E = 0x6E, /* LCC E Indirect. */ + SCO_AB = 0x70, /* SCO Absolute. */ + ORA_E = 0x71, /* ORA E Indirect. */ + ASR_E = 0x72, /* ASR E Indirect. */ + PEA_AX = 0x73, /* PEA Absolute, indexed with X. */ + SCO_E = 0x74, /* SCO E Indirect. */ + SBE_AB = 0x76, /* SBE Absolute. */ + PEA_ZX = 0x77, /* PEA Zero Matrix, indexed with X. */ + LRM_AB = 0x78, /* LRM Absolute. */ + PLE_IMP = 0x7B, /* PuLl Effective address register from stack. */ + LRM_E = 0x7C, /* LRM E Indirect. */ + SCC_E = 0x7E, /* Store accumulator, if Carry Clear. */ + ECO_IMM = 0x80, /* End one, or more COre(s). */ + DEC_E = 0x82, /* DEC E Indirect. */ + LEA_AIY = 0x83, /* LEA Absolute Indirect Indexed. */ + ECO_Z = 0x84, /* ECO Zero Matrix. */ + ADS_IMM = 0x86, /* ADd Stack pointer. */ + LEA_IY = 0x87, /* LEA Indirect Indexed. */ + ADS_Z = 0x8A, /* ADS Zero Matrix. */ + DEE_IMP = 0x8B, /* DEcrement Effective address register. */ + RLM_Z = 0x8C, /* Rotate Left, on Memory. */ + LEQ_IMM = 0x8D, /* Load accumulator, if EQual. */ + LEQ_E = 0x8E, /* LEQ E Indirect. */ + ECO_AB = 0x90, /* ECO Absolute. */ + XOR_E = 0x91, /* XOR E Indirect. */ + CMP_E = 0x92, /* CMP E Indirect. */ + LEA_AIX = 0x93, /* LEA Absolute Indexed Indirect. */ + ECO_E = 0x94, /* ECO E Indirect. */ + ADS_AB = 0x96, /* ADS Absolute. */ + LEA_IX = 0x97, /* LEA Indexed Indirect. */ + RLM_AB = 0x98, /* RLM Absolute. */ + ADS_E = 0x9A, /* ADS E Indirect. */ + INE_IMP = 0x9B, /* INcrement Effective address register. */ + RLM_E = 0x9C, /* RLM E Indirect. */ + SEQ_E = 0x9E, /* Store accumulator, if EQual. */ + INC_E = 0xA2, /* INC E Indirect. */ + PEA_AIY = 0xA3, /* PEA Absolute Indirect Indexed. */ + STS_Z = 0xA4, /* STore Stack pointer. */ + SBS_IMM = 0xA6, /* SuBtract Stack pointer. */ + PEA_IY = 0xA7, /* PEA Indirect Indexed. */ + SBS_Z = 0xAA, /* SBS Zero Matrix. */ + DES_IMP = 0xAB, /* DEcrement Stack pointer. */ + RRM_Z = 0xAC, /* Rotate Right, on Memory. */ + LNE_IMM = 0xAD, /* Load accumulator, if Not Equal. */ + LNE_E = 0xAE, /* LNE E Indirect. */ + STS_AB = 0xB0, /* STS Absolute. */ + LSL_E = 0xB1, /* LSL E Indirect. */ + LDY_E = 0xB2, /* LDY E Indirect. */ + PEA_AIX = 0xB3, /* PEA Absolute Indexed Indirect. */ + STS_E = 0xB4, /* STS E Indirect. */ + SBS_AB = 0xB6, /* SBS Absolute. */ + PEA_IX = 0xB7, /* PEA Indexed Indirect. */ + RRM_AB = 0xB8, /* RRM Absolute. */ + SBS_E = 0xBA, /* SBS E Indirect. */ + INS_IMP = 0xBB, /* INcrement Stack pointer. */ + RRM_E = 0xBC, /* RRM E Indirect. */ + REP_REL = 0xBD, /* REPeat until counter is zero. */ + SNE_E = 0xBE, /* Store accumulator, if Not Equal. */ + STY_E = 0xC2, /* STY E Indirect. */ + STE_Z = 0xC4, /* STore Effective address register. */ + NOT_A = 0xC6, /* bitwise NOT with accumulator. */ + NOT_Z = 0xCA, /* NOT Zero Matrix. */ + MMV_IMP = 0xCB, /* Memory MoVe. */ + ARM_Z = 0xCC, /* Arithmetic shift Right, on Memory. */ + REQ_REL = 0xCD, /* Repeat until either counter is zero, or zero flag isn't set. */ + STE_AB = 0xD0, /* STE Absolute. */ + LSR_E = 0xD1, /* LSR E Indirect. */ + LDA_E = 0xD2, /* LDA E Indirect. */ + NOT_AB = 0xD6, /* NOT Absolute. */ + ARM_AB = 0xD8, /* ARM Absolute. */ + NOT_E = 0xDA, /* NOT E Indirect. */ + ARM_E = 0xDC, /* ARM E Indirect. */ + RNE_REL = 0xDD, /* Repeat until either counter is zero, or zero flag is set. */ + STA_E = 0xE2, /* STA E Indirect. */ + STZ_Z = 0xE4, /* STore Zero. */ + SWP_A = 0xE6, /* SWaP lower half, with upper half. */ + SWP_Z = 0xEA, /* SWP Zero Matrix. */ + PCN_Z = 0xEC, /* Population CouNt. */ + STZ_AB = 0xF0, /* STZ Absolute. */ + ROL_E = 0xF1, /* ROL E Indirect. */ + LDB_E = 0xF2, /* LDB E Indirect. */ + STZ_E = 0xF4, /* STZ E Indirect. */ + SWP_AB = 0xF6, /* SWP Absolute. */ + PCN_AB = 0xF8, /* PCN Absolute. */ + SWP_E = 0xFA, /* SWP E Indirect. */ + PCN_E = 0xFC /* PCN E Indirect. */ +}; diff --git a/lexer/backup/lexer.c b/lexer/backup/lexer.c new file mode 100644 index 0000000..1654f44 --- /dev/null +++ b/lexer/backup/lexer.c @@ -0,0 +1,937 @@ +#include "asmmon.h" +#include "lexer.h" + +uint8_t lex_type; +uint16_t sym_count = 0; +token *tokens = NULL; +token *last_tok = NULL; +symbol *locals = NULL; +symbol *last_loc = NULL; +symbol *cur_sym = NULL; +symbol *struct_sym = NULL; + +line *tmp_line = NULL; + +symbol *mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t islocal, uint8_t useid, uint16_t id, uint8_t dbg) { + uint16_t i = 0; + symbol *s = (!islocal) ? symbols : locals; + uint8_t flag = 0; + for (; s; s = s->next, i++) { + if (!useid && name[0] != s->name[0]) { + continue; + } + flag = (useid) ? (id == s->id) : !strcmp(name, s->name); + if (flag) { + if (def) { + if (s->def) { + if (dbg) { + printf("mksymbol(): oof, you cannot redefine the symbol: %s\n", name); + } + defined = 1; + } else { + defined = 0; + } + s->def = def; + s->val = val; + s->id = i; + if (dbg) { + printf("mksymbol(): def: %u, val: $%016"PRIX64", name: %s\n", def, val, name); + printf("mksymbol(): i: $%X, id: $%04X\n", i, s->id); + } + } + return s; + } + } + size_t str_size = strlen(name)+1; + s = malloc(sizeof(symbol)); + s->down = NULL; + if (!islocal) { + (last_sym) ? (last_sym->next = s) : (symbols = s); + if (last_sym) { + last_sym->next->prev = last_sym; + last_sym->next->up = last_sym->up; + last_sym->next->down = NULL; + } else { + symbols->prev = NULL; + symbols->up = NULL; + symbols->down = NULL; + } + } else { + (last_loc) ? (last_loc->next = s) : (locals = s); + if (last_loc) { + last_loc->next->prev = last_loc; + last_loc->next->up = last_loc->up; + last_loc->next->down = NULL; + } else { + locals->prev = NULL; + locals->down = NULL; + } + } + s->name = malloc(str_size); + s->def = def; + s->val = val; + s->count = 0; + s->isstruct = 0; + memcpy(s->name, name, str_size); + s->next = NULL; + s->id = sym_count++; + (!islocal) ? (last_sym = s) : (last_loc = s); + if (!islocal) { + s->down = NULL; + /*if (def) { + locals = NULL; + last_loc = NULL; + }*/ + } else { + cur_sym->count++; + } + defined = 0; + if (dbg) { + printf("mksymbol(): def: %u, val: $%016"PRIX64", name: %s, id: $%04X\n", def, val, name, sym_count-1); + } + return s; +} + +uint16_t fixup_cnt = 0; +symbol *get_sym(const char *name, uint64_t val, token *t, uint8_t islocal, uint8_t dbg) { + symbol *s = mksymbol(name, 0, 0, islocal, 0, 0, dbg); + if (dbg) { + printf("get_sym(): Symbol ID: $%X.\n", s->id); + } + if (s->def) { + return s; + } else { + if (dbg) { + printf("get_sym(): oof, symbol %s, does not exist, yet.\n", name); + } + fixup *f = malloc(sizeof(fixup)); + (last_fix) ? (last_fix->next = f) : (fixups = f); + f->adr = val; + f->t = t; + f->s = s; + f->next = NULL; + last_fix = f; + fixup_cnt++; + return NULL; + } +} + +symbol *find_member(char *name, symbol* root, uint8_t dbg) { + /*for (; root->up; root = root->up);*/ + symbol *s = root; + if (s->down == NULL && s->up != NULL) { + s = s->up; + } + do { + s = s->down; + for (symbol *m = s; m; m = m->next) { + size_t len1 = strlen(name); + size_t len2 = strlen(m->name); + if (len1 == len2 && name[0] == m->name[0] && !strcmp(name, m->name)) { + return m; + } + } + for (; s->next && !s->down; s = s->next); + } while (s->down); + return NULL; +} + +uint16_t reslv_fixups(uint8_t dbg) { + fixup *f = fixups; + symbol *ls; + uint16_t i = 0, j = 0; + for (; f; f = f->next) { + if (f->s->def) { + if (dbg) { + printf("reslv_fixups(): Symbol ID: $%X, Symbol Name: %s, Symbol Value: $%"PRIX64".\n", f->s->id, f->s->name, f->s->val); + } + f->t->sym = f->s; + } else { + if (dbg) { + printf("reslv_fixups(): oof, undefined reference to '%s', at $%016"PRIX64".\n", f->s->name, f->adr); + } + i++; + } + } + return i; + +} + +uint16_t get_comment(const char *com, uint8_t dbg) { + uint16_t i = 0; + for (; comment[i] && i < comidx; i++) { + if (com[0] == comment[i][0] && !strcmp(com, comment[i])) { + break; + } + } + if (comment[i] == NULL) { + if (dbg) { + printf("get_comment(): oof, the index $%04X is NULL.\n", i); + printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", com); + } + size_t size = strlen(com)+1; + comment[comidx] = malloc(size); + memcpy(comment[comidx], com, size); + return comidx++; + + } + if (dbg) { + if (strcmp(com, comment[i])) { + printf("get_comment(): oof, the comment \"%s\" is somehow not in the comment table, even though it should be at index $%04X.\n", com, i); + } + printf("get_comment(): The return value of strcmp(com, comment[$%04X]) is %i.\n", i, strcmp(com, comment[i])); + printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", com, i); + } + return i; +} + +uint16_t get_string(const char *str, uint8_t dbg) { + uint16_t i = 0; + uint8_t isstr = 0; + for (; i < stridx; i++) { + if (isstr || string[i] == NULL) { + break; + } else if (str[0] == string[i][0]) { + isstr = !strcmp(str, string[i]); + } + } + if (string[i] == NULL || i == stridx) { + if (dbg) { + printf("get_string(): oof, the index $%04X is NULL.\n", i); + printf("get_string(): oof, the string \"%s\", was not found in the string table.\n", str); + } + return 0xFFFF; + } + if (dbg) { + printf("get_string(): Found string \"%s\", in the table, at index $%04X.\n", str, i); + } + return i; +} + +line *find_line(uint32_t ln, uint8_t dbg) { + uint32_t i = 0; + line *l = lines; + for (; l && l->linenum != ln; l = l->next); + if (l != NULL) { + if (l->linenum == ln) { + if (dbg) { + printf("find_line(): Found line number %u.\n", ln); + } + return l; + } + } else { + if (dbg) { + printf("find_line(): oof, could not find line number %u.\n", ln); + } + return NULL; + } + return l; +} + +int is_struct = 0; +int is_anon = 0; + +void create_struct(symbol *c_sym, line *l, token *t, token *lt, char *name, uint8_t dbg) { + uint8_t ismember = !(is_struct == 1 && lt && lt->id == TOK_DIR); + mksymbol(name, 0, 1, ismember, 0, 0, dbg); + if (isfixup) { + isfixup = reslv_fixups(dbg); + } + t->sym = get_sym(name, 0, t, ismember, dbg); + if (lt && lt->id == TOK_DIR) { + t->sym->isstruct = 1; + t->id = (lt->type == DIR_STRUCT) ? TOK_STRUCT : TOK_UNION; + tmp_line = l; + } else { + t->id = TOK_MEMBER; + t->sym->isanon = (is_anon > 0); + } + isfixup += (t->sym == NULL); + int is_top = (c_sym == NULL); + c_sym = (!ismember && !c_sym) ? last_sym : c_sym; + if (!ismember) { + if (!is_top) { + c_sym = t->sym; + locals = NULL; + last_loc = NULL; + } else { + c_sym->down = locals; + } + } else { + if (lt && lt->id == TOK_DIR) { + if (lt->type == DIR_UNION || lt->type == DIR_STRUCT) { + c_sym->down = locals; + c_sym->down->up = c_sym; + last_loc->up = c_sym; + c_sym = last_loc; + locals = NULL; + last_loc = NULL; + } + } + } + cur_sym = c_sym; +} + +void end_struct(symbol *c_sym, symbol *s_sym, uint8_t dbg) { + int skip = 0; + if (is_anon > 0) { + if ((c_sym && c_sym->isanon) || (c_sym->up && !c_sym->up->isanon) || (c_sym && s_sym->isanon)) { + is_anon--; + } else if (is_struct <= 0) { + is_anon = 0; + } + skip = (!is_anon); + } + if (((is_struct-is_anon) > 0 && !skip) || (is_anon <= 0 && is_struct <= 0)) { + symbol *s; + for (s = locals; s; s = s->next) { + if (s->up == NULL) { + s->up = c_sym; + } + if (dbg) { + printf("s: %p, s->up: %p, c_sym: %p, last_loc: %p\n", s, s->up, c_sym, last_loc); + } + } + if (c_sym->down == NULL) { + c_sym->down = locals; + } + } + if ((is_anon <= 0 || is_struct <= 0)) { + for (s_sym = c_sym; s_sym->prev && !s_sym->isanon; s_sym = s_sym->prev); + struct_sym = s_sym; + } + if ((is_struct-is_anon) > 0 && !skip) { + symbol *s = c_sym; + for (; s->prev; s = s->prev) { + if (s->up == NULL && c_sym->up) { + s->up = c_sym->up; + } + if (dbg) { + printf("s: %p, s->up: %p, c_sym->up: %p, last_loc: %p\n", s, s->up, c_sym->up, last_loc); + } + } + if (c_sym->up) { + cur_sym = c_sym->up; + } + for (locals = locals->up; locals->prev; locals = locals->prev); + for (last_loc = locals; last_loc->next; last_loc = last_loc->next); + } +} + +uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { + char sym[0x100]; + uint16_t i = 0; + uint16_t j = 0; + uint16_t comid = 0; + uint16_t strid = 0; + uint16_t symid = 0; + uint64_t value = 0; + lex_type = 0xFF; + + uint8_t k = 0; + uint8_t k2 = 0; + union reg ch; + ch.u64 = 0; + uint8_t rs = 0; + uint8_t of = 0; + uint8_t base = 0; + + uint8_t islocal = 0; + + uint8_t isop = 0; + int num = 0; + int isch = 0; + uint8_t isesc = 0; + uint8_t islinenum; + + int16_t ln = -1; + + char lnum[6]; + + uint8_t space = 0; + uint8_t tab = 0; + uint8_t fall = 0; + uint8_t done = 0; + + + /*uint8_t is_newcom = 0;*/ + line *l = NULL; + token *st = NULL; + token *t = NULL; + token *lt = NULL; + symbol *tmp_sym = NULL; + symbol *tsym = NULL; + + while (isdigit(str[i]) && isdelm(str[i], dbg) != 16) { + lnum[j++] = str[i++]; + } + islinenum = i; + if (i) { + lnum[j] = '\0'; + ln = strtol(lnum, NULL, 10); + j = 0; + l = find_line(ln, dbg); + } else { + ln = linenum; + l = NULL; + } + if (l) { + address = l->addr; + } else { + l = malloc(sizeof(line)); + (last_line) ? (last_line->next = l) : (lines = l); + l->tok = NULL; + l->next = NULL; + l->count = 0; + l->bline = bline; + last_line = l; + + } + l->addr = address; + while (isdelm(str[i], dbg) != 1) { + uint8_t offset = 0; + base = 0; + space = 0; + tab = 0; + while (isdelm(str[i+j], dbg) == 16) { + tab += str[i+j] == '\t'; + space += str[i+j] == ' '; + j++; + } + j = 0; + if (dbg) { + printf("lex(): tab: %u, space: %u\n", tab, space); + } + if (isdelm(str[i], dbg) == 16) { + for (; isdelm(str[i], dbg) == 16; i++); + } + uint8_t ptok = get_ptok(str[i], dbg); + if (is_altok(ptok, dbg)) { + offset++; + if (((ptok == PTOK_S || ptok == PTOK_B) && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C')) { + offset++; + } + switch (get_ptok(str[i+offset], dbg)) { + case PTOK_B : + case PTOK_E : + case PTOK_X : + case PTOK_Y : + case PTOK_S : + case PTOK_P : + case PTOK_A : + case PTOK_C : + case PTOK_D : + case PTOK_F : + case PTOK_R : + case PTOK_ALPHA : ptok = PTOK_ALPHA; break; + case PTOK_NUMBER: + if (ptok == PTOK_R) { + char reg_num[3]; + for (int isnum = 0; isdigit(str[i+offset]) && !(isdelm(str[i+offset], dbg) & 0x03) && isnum < 2; offset++, isnum++) { + reg_num[isnum] = str[i+offset]; + } + reg_num[isnum] = '\0'; + if (isnum == 2) { + int regnum = strtoul(reg_num, NULL, 10); + ptok = (regnum < 11 || regnum > 15) ? PTOK_ALPHA : ptok; + } else { + ptok = PTOK_ALPHA; + } + } else { + ptok = PTOK_ALPHA; + } + break; + } + if ((ptok == PTOK_S && str[i+1] && toupper(str[i+1]) != 'P') || (ptok == PTOK_P && toupper(str[i+1]) != 'C')) { + ptok = PTOK_ALPHA; + } + } + /*i = ptok_handler[ptok](str, i, lex_type, l, t, dbg);*/ + switch (ptok) { + case PTOK_DOT: + i++; + for (; !(isdelm(str[i+j], dbg) & 17); j++); + memcpy(lexeme, str+i, j); + lexeme[j] = '\0'; + i += j; + if (!isop) { + for (k = 0; k < 11; k++) { + if (tolower(lexeme[0]) == dir_t[k][0] && !strcasecmp(lexeme, dir_t[k])) { + lex_type = TOK_DIR; + uint16_t tmp = j; + for (j = 0; isdelm(str[i+j], dbg) & 16; j++); + uint8_t ret = get_ptok(str[i+j], dbg); + j = tmp; + + if ((k == DIR_STRUCT || k == DIR_UNION) && (ret != PTOK_ALPHA || (is_anon && ret == PTOK_ALPHA))) { + is_anon++; + } + is_struct += (k == DIR_STRUCT || k == DIR_UNION); + is_struct -= (k == DIR_ENDSTRUCT || k == DIR_ENDUNION); + if ((k == DIR_ENDSTRUCT || k == DIR_ENDUNION)) { + end_struct(cur_sym, struct_sym, dbg); + } + break; + } + } + if (lex_type != TOK_DIR && lt && lt->id == TOK_SYM) { + lex_type = TOK_MEMBER; + i -= j; + } else { + l->count++; + t = make_token(lex_type, k, space, tab, 0, "", NULL); + } + } else { + lex_type = TOK_RS; + switch (tolower(lexeme[j-1])) { + case '2': + case 'w': + rs = 1; + break; + case '4': + case 'd': + rs = 2; + break; + case '8': + case 'q': + rs = 3; + break; + } + l->count++; + t = make_token(lex_type, rs, space, tab, 0, "", NULL); + isop = 0; + } + break; + case PTOK_DQUOTE: + i++; + for (; isdelm(str[i+j], dbg) != 4 || isesc; j++) { + isesc = (str[i+j] == '\\' && str[i+(j-1)] != '\\'); + } + memcpy(lexeme, str+i, j); + lexeme[j] = '\0'; + i += j; + strid = get_string(lexeme, dbg); + if (strid == 0xFFFF) { + strid = stridx; + string[strid] = malloc(j+1); + memcpy(string[strid], lexeme, j+1); + stridx++; + } else { + } + if (dbg) { + printf("lex(): str[0x%04X]: %s\n", strid, string[strid]); + } + if (lt->id == TOK_DIR && lt->type == DIR_INCLUDE) { + incl[inc_count+inc_file] = strid; + inc_file++; + } + lex_type = TOK_STRING; + l->count++; + t = make_token(lex_type, 0, space, tab, 0, string[strid], NULL); + break; + case PTOK_DOLLAR: + case PTOK_PERCENT: + case PTOK_NUMBER: + value = 0; + switch (ptok) { + case PTOK_DOLLAR : base = 16; lex_type = TOK_HEX; i++; break; + case PTOK_PERCENT: base = 2; lex_type = TOK_BIN; i++; break; + case PTOK_NUMBER : base = 10; lex_type = TOK_DEC; /**/ break; + } + for (; isxdigit(str[i+j]) && !(isdelm(str[i+j], dbg) & 0x03); j++); + memcpy(lexeme, str+i, j); + lexeme[j] = '\0'; + i += j; + value = strtoull(lexeme, NULL, base); + if (lt->id == TOK_SYM) { + tsym = mksymbol(sym, value, 1, islocal, 0, 0, dbg); + if (lt) { + lt->sym = get_sym(sym, address, lt, islocal, dbg); + } + if (!islocal) { + cur_sym = last_sym; + } + tsym = NULL; + islocal = 0; + isfixup += (lt->sym == NULL); + if (dbg) { + printf("lex(): isfixup: %u\n", isfixup); + } + } + l->count++; + t = make_token(lex_type, 0, space, tab, value, "", NULL); + t->digits = (lt->id != TOK_SYM) ? j : 0; + break; + case PTOK_SQUOTE: + i++; + k = 0; + j = 0; + while (isdelm(str[i], dbg) != 8 || isesc) { + isesc = (str[i] == '\\' && str[i-1] != '\\'); + lexeme[j++] = str[i++]; + } + isesc = 0; + lexeme[j] = '\0'; + for (j = 0; lexeme[k] != '\0' && j < 7; k++) { + switch (lexeme[k]) { + case '\\': + switch (lexeme[++k]) { + case 'n' : ch.u8[j++] = '\n'; break; + case 'r' : ch.u8[j++] = '\r'; break; + case 't' : ch.u8[j++] = '\t'; break; + case 'b' : ch.u8[j++] = '\b'; break; + case '\'': ch.u8[j++] = '\''; break; + case '\"': ch.u8[j++] = '\"'; break; + case '\\': ch.u8[j++] = '\\'; break; + } + break; + default: ch.u8[j++] = lexeme[k]; + } + } + lex_type = TOK_CHAR; + l->count++; + t = make_token(lex_type, 0, space, tab, ch.u64, "", NULL); + break; + case PTOK_LBRACK: + case PTOK_HASH : + /*l->tok->type = (ptok == PTOK_LBRACK) ? IND : IMM; + lex_type = (ptok == PTOK_LBRACK) ? TOK_IND : TOK_IMM;*/ + lex_type = TOK_MEM; + value = (ptok == PTOK_LBRACK) ? MEM_IND : MEM_IMM; + l->count++; + t = make_token(lex_type, value, space, tab, 0, "", NULL); + lex_type = (ptok == PTOK_LBRACK) ? TOK_IND : TOK_IMM; + memset(lexeme, 0, strlen(lexeme)+1); + lexeme[j++] = str[i]; + /*(t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab);*/ + break; + case PTOK_PLUS: + case PTOK_MINUS: + case PTOK_GT: + case PTOK_LT: + case PTOK_PIPE: + lex_type = TOK_EXPR; + switch (ptok) { + case PTOK_PLUS : value = EXPR_PLUS ; break; + case PTOK_MINUS: value = EXPR_MINUS; break; + case PTOK_PIPE : value = EXPR_OR ; break; + case PTOK_GT : value = (get_ptok(str[i+1], dbg) == PTOK_GT) ? (EXPR_RSHFT) : (EXPR_LOW) ; break; + case PTOK_LT : value = (get_ptok(str[i+1], dbg) == PTOK_LT) ? (EXPR_LSHFT) : (EXPR_HIGH); break; + } + l->count++; + t = make_token(lex_type, value, space, tab, 0, "", NULL); + memset(lexeme, 0, strlen(lexeme)+1); + lexeme[j++] = str[i]; + if (value == EXPR_LSHFT || value == EXPR_RSHFT) { + lexeme[j++] = str[++i]; + } + break; + case PTOK_EQU: + i++; + lex_type = TOK_SYM; + memset(lexeme, 0, strlen(lexeme)+1); + lexeme[j] = str[i]; + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); + break; + case PTOK_RBRACK: + i++; + lex_type = TOK_IND; + lexeme[j] = ')'; + lexeme[j+1] = '\0'; + lexeme[j+2] = '\0'; + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); + break; + case PTOK_COMMA: + i++; + if (lex_type != TOK_IND && lex_type != TOK_OF) { + lex_type = TOK_CSV; + } + lexeme[j] = ','; + lexeme[j+1] = '\0'; + lexeme[j+2] = '\0'; + break; + case PTOK_B: + case PTOK_E: + case PTOK_X: + case PTOK_Y: + case PTOK_S: + case PTOK_A: + case PTOK_C: + case PTOK_D: + case PTOK_F: + case PTOK_R: + lexeme[j+0] = str[i++]; + lexeme[j+1] = (ptok == PTOK_R || ((ptok == PTOK_S || ptok == PTOK_B) && get_ptok(str[i], dbg) == PTOK_P)) ? str[i++] : '\0'; + lexeme[j+2] = (ptok == PTOK_R) ? str[i++] : '\0'; + lexeme[j+3] = '\0'; + lex_type = TOK_REG; + switch (ptok) { + case PTOK_A: value = REG_A; break; + case PTOK_X: value = REG_X; break; + case PTOK_Y: value = REG_Y; break; + case PTOK_E: value = REG_E; break; + case PTOK_C: value = REG_C; break; + case PTOK_D: value = REG_D; break; + case PTOK_S: + case PTOK_B: + if (get_ptok(lexeme[j+1], dbg) == PTOK_P) { + value = (ptok == PTOK_S) ? REG_SP : REG_BP; + } else { + value = (ptok == PTOK_S) ? REG_S : REG_B; + } + break; + case PTOK_F: value = REG_F; break; + case PTOK_R: value = strtoull(lexeme+j+1, NULL, 10); break; + } + l->count++; + t = make_token(lex_type, value, space, tab, 0, "", NULL); + /*(t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab);*/ + break; + case PTOK_P: + lexeme[j] = str[i++]; + lexeme[j+1] = (str[i] != ',') ? str[i++] : '\0'; + lexeme[j+2] = '\0'; + /*switch (ptok) { + case PTOK_S: of = 1; break; + case PTOK_P: of = 2; break; + }*/ + of = 2; + lex_type = TOK_OF; + l->count++; + t = make_token(lex_type, of, space, tab, 0, "", NULL); + break; + case PTOK_AT: + memset(lexeme, 0, strlen(lexeme)+1); + lexeme[j] = '@'; + islocal = 1; + lex_type = TOK_LOCAL; + if (lt || t) { + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); + } + break; + case PTOK_COLON: + i++; + lexeme[j] = ':'; + lexeme[j+1] = '\0'; + lex_type = TOK_LABEL; + tsym = mksymbol(sym, address, 1, islocal, 0, 0, dbg); + if (isfixup) { + isfixup = reslv_fixups(dbg); + } + if (lt) { + lt->id = lex_type; + lt->type = islocal; + lt->sym = get_sym(sym, address, t, islocal, dbg); + isfixup += (lt->sym == NULL); + } + if (!islocal) { + cur_sym = last_sym; + locals = NULL; + last_loc = NULL; + } else if (cur_sym->down == NULL && cur_sym == last_sym) { + cur_sym->down = locals; + cur_sym->down->up = cur_sym; + } + tsym = NULL; + islocal = 0; + if (dbg) { + printf("lex(): isfixup: %u\n", isfixup); + } + break; + case PTOK_SCOLON: + i++; + for (; isdelm(str[i+j], dbg) != 1; j++); + if (!j) { + lexeme[j] = ' '; + lexeme[j+1] = '\0'; + + } else { + memcpy(lexeme, str+i, j); + lexeme[j] = '\0'; + i += j; + comid = get_comment(lexeme, dbg); + /*is_newcom = (comid == 0xFFFF); + if (comid == 0xFFFF) { + if (line != lineidx && l[line].com != 0xFFFF) { + comid = l[line].com; + } else { + comid = comidx; + } + comid = comidx; + comment[comid] = malloc(j+1); + memcpy(comment[comid], lexeme, j+1); + comidx++; + }*/ + if (dbg) { + printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]); + } + } + lex_type = TOK_COMMENT; + l->count++; + if (j) { + t = make_token(lex_type, 0, space, tab, 0, comment[comid], NULL); + } else { + t = make_token(lex_type, 0, space, tab, 0, "" , NULL); + } + + break; + case PTOK_ALPHA: + for (; !isdelm2(str[i+j], dbg); j++); + memcpy(lexeme, str+i, j); + lexeme[j] = '\0'; + i += j; + isch = 0; + isop = 0; + if (j == 3 && str[i] != ':' && !is_struct) { + for (k = 0; k < OPNUM; k++) { + int find_ext = (k < EXT_OPNUM); + int find_ortho = (k < ORTHO_OPNUM); + int upper = toupper(lexeme[0]); + int isbase = (upper == mne[k][0]); + int isext = (find_ext && upper == ext_mne[k][0]); + int isortho = (find_ortho && upper == ortho_mne[k][0]); + + if (isbase || isext || isortho) { + int is_base = !strcasecmp(lexeme, mne[k]); + int is_ext = (find_ext && !strcasecmp(lexeme, ext_mne[k])); + int is_ortho = (find_ortho && !strcasecmp(lexeme, ortho_mne[k])); + if (is_base || is_ext || is_ortho) { + lex_type = (is_base) ? TOK_OPCODE : lex_type; + lex_type = (is_ext) ? TOK_EXTOP : lex_type; + lex_type = (is_ortho) ? TOK_ORTHO : lex_type; + isop = 1; + l->count++; + t = make_token(lex_type, 0xFF, space, tab, k, "", NULL); + break; + } + } + } + } + if (!isop) { + uint8_t spaces = 0; + if (l->tok->type == TOK_ORTHO && l->tok->byte == SET) { + for (k = 0; k < 8; k++) { + int upper = toupper(lexeme[0]); + if (upper == set_cc[k][0]) { + if (!strcasecmp(lexeme, set_cc[k])) { + lex_type = TOK_CC; + l->count++; + t = make_token(lex_type, 0xFF, space, tab, k, "", NULL); + } + } + } + } + for (; isdelm(str[i+spaces], dbg) == 16; spaces++); + uint8_t ret = get_ptok(str[i+spaces], dbg); + if (ret == PTOK_COLON || ret == PTOK_EQU) { + islocal = (lex_type == TOK_LOCAL); + } + lex_type = TOK_SYM; + l->count++; + t = make_token(lex_type, islocal, space, tab, 0, "", NULL); + memcpy(sym, lexeme, j+1); + if (dbg) { + printf("lex(): spaces: %u\n", spaces); + } + if (is_struct) { + create_struct(cur_sym, l, t, lt, sym, dbg); + islocal = 0; + } else if ((str[i+spaces] != ':' && str[i+spaces] != '=')) { + uint8_t sym_struct = 0; + symbol *s; + /*tmp_sym = (s && s->isstruct) ? NULL : tmp_sym;*/ + if (tmp_sym) { + t->sym = find_member(lexeme, tmp_sym, dbg); + tmp_sym = NULL; + } else { + t->sym = get_sym(lexeme, address, t, islocal, dbg); + } + isfixup += (t && t->sym == NULL); + islocal = 0; + if (dbg) { + printf("lex(): isfixup: %u\n", isfixup); + } + } + if (!is_struct && t && t->sym && t->sym->isstruct) { + tmp_sym = t->sym; + } + } + break; + } + if (!l->tok && t) { + l->tok = tokens; + } + if (dbg) { + printf("lex(): lexeme: %s, lex_type: %s\n", lexeme, (lex_type != 0xFF) ? lex_tok[lex_type] : "TOK_NONE"); + } + j = 0; + if ((lex_type == TOK_OPCODE || lex_type == TOK_EXTOP) && !isop) { + j = 0; + } else if (lex_type == TOK_EXPR || (lex_type != TOK_MEMBER && !isdelm2(str[i], dbg))) { + i++; + } + switch (lex_type) { + default: + lex_type = 0xFF; + case TOK_CSV: + case TOK_IND: + case TOK_LOCAL: + memset(lexeme, 0, strlen(lexeme)+1); + case TOK_SYM: + break; + } + if (t) { + lt = t; + t = t->next; + } + } + if (i) { + l->tok = tokens; + token *tok = tokens; + if (tok->id == TOK_SYM && tok->next) { + symbol *s = tok->sym; + for (; tok; tok = tok->next) { + switch (tok->id) { + case TOK_HEX : + case TOK_BIN : + case TOK_DEC : + case TOK_CHAR: + case TOK_EXPR: + s->val = get_val(tok, address, 3, dbg); + if (tok->next) { + tok = skip_expr(tok, dbg); + } + break; + } + } + } + tokens = NULL; + last_tok = NULL; + bytecount dummy; + if (!is_struct) { + l = (tmp_line) ? tmp_line : l; + address = parse_tokens(l->tok, &l, &dummy, 0, address, dbg); + if (tmp_line) { + tmp_line = NULL; + } + } + if (dbg) { + printf("lex(): Next address: $%"PRIX64"\n", address); + } + if (ln > linenum || islinenum) { + l->linenum = ln; + if (ln > linenum) { + linenum+=(10+(ln & 10)); + } + } else if (!islinenum) { + l->linenum = linenum; + linenum += 10; + } + } + return address; +} diff --git a/lexer/backup/lexer.h b/lexer/backup/lexer.h new file mode 100644 index 0000000..2595158 --- /dev/null +++ b/lexer/backup/lexer.h @@ -0,0 +1,228 @@ +static uint8_t isdelm(char c, uint8_t dbg) { + switch (c) { + default : return 0x00; + case '\0': + case '\n': return 0x01; + case ',' : return 0x02; + case '\"': return 0x04; + case '\'': return 0x08; + case '\t': + case ' ' : return 0x10; + } +} + +static uint8_t isdelm2(char c, uint8_t dbg) { + switch (c) { + default : return 0; + case ')' : + case ',' : + case '.' : + case '+' : + case '<' : + case '|' : + case '>' : + case '-' : + case ':' : + case '=' : + case ';' : + case '\0': + case '\n': return 1; + case '\t': + case ' ' : return 2; + } +} + +static uint8_t get_ptok(char c, uint8_t dbg) { + switch (c) { + case '.' : return PTOK_DOT ; + case '@' : return PTOK_AT ; + case ':' : return PTOK_COLON ; + case '=' : return PTOK_EQU ; + case '+' : return PTOK_PLUS ; + case '-' : return PTOK_MINUS ; + case '>' : return PTOK_GT ; + case '<' : return PTOK_LT ; + case '|' : return PTOK_PIPE ; + case '(' : return PTOK_LBRACK ; + case ')' : return PTOK_RBRACK ; + case ',' : return PTOK_COMMA ; + case 'B': case 'b' : return PTOK_B ; + case 'E': case 'e' : return PTOK_E ; + case 'X': case 'x' : return PTOK_X ; + case 'Y': case 'y' : return PTOK_Y ; + case 'S': case 's' : return PTOK_S ; + case 'P': case 'p' : return PTOK_P ; + case 'A': case 'a' : return PTOK_A ; + case 'C': case 'c' : return PTOK_C ; + case 'D': case 'd' : return PTOK_D ; + case 'F': case 'f' : return PTOK_F ; + case 'R': case 'r' : return PTOK_R ; + case '\"': return PTOK_DQUOTE ; + case '\'': return PTOK_SQUOTE ; + case '#' : return PTOK_HASH ; + case ';' : return PTOK_SCOLON ; + case '$' : return PTOK_DOLLAR ; + case '%' : return PTOK_PERCENT; + default : + if (isdigit(c)) { + return PTOK_NUMBER; + } else if (isalpha(c) || c == '_') { + return PTOK_ALPHA; + } else { + return PTOK_OTHER; + } + } +} + +static uint8_t is_altok(uint8_t ptok, uint8_t dbg) { + switch (ptok) { + case PTOK_B: + case PTOK_E: + case PTOK_X: + case PTOK_Y: + case PTOK_S: + case PTOK_P: return 1; + default : return 0; + } +} + +#if 0 +static int handle_dot(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_at(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_colon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_equ(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_plus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_minus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_gt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_pipe(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_rbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_comma(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_b(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_e(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_x(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_y(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_s(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_p(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dquote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_squote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_hash(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_scolon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dollar(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_percent(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} +static int handle_number(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_alpha(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_other(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + return idx+1; +} + +typedef int (*ptok_func)(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg); + +static ptok_func ptok_handler[PTOK_OTHER+1] = { + [PTOK_DOT ] = handle_dot, + [PTOK_AT ] = handle_at, + [PTOK_COLON ] = handle_colon, + [PTOK_EQU ] = handle_equ, + [PTOK_PLUS ] = handle_plus, + [PTOK_MINUS ] = handle_minus, + [PTOK_GT ] = handle_gt, + [PTOK_LT ] = handle_lt, + [PTOK_PIPE ] = handle_pipe, + [PTOK_LBRACK ] = handle_lbrack, + [PTOK_RBRACK ] = handle_rbrack, + [PTOK_COMMA ] = handle_comma, + [PTOK_B ] = handle_b, + [PTOK_E ] = handle_e, + [PTOK_X ] = handle_x, + [PTOK_Y ] = handle_y, + [PTOK_S ] = handle_s, + [PTOK_P ] = handle_p, + [PTOK_DQUOTE ] = handle_dquote, + [PTOK_SQUOTE ] = handle_squote, + [PTOK_HASH ] = handle_hash, + [PTOK_SCOLON ] = handle_scolon, + [PTOK_DOLLAR ] = handle_dollar, + [PTOK_PERCENT] = handle_percent, + [PTOK_NUMBER ] = handle_number, + [PTOK_ALPHA ] = handle_alpha, + [PTOK_OTHER ] = handle_other +}; +#endif diff --git a/lexer/cpu/sux/cpu.c b/lexer/cpu/sux/cpu.c new file mode 100644 index 0000000..cd6d364 --- /dev/null +++ b/lexer/cpu/sux/cpu.c @@ -0,0 +1,30 @@ +#include <ctype.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> + +static char current_ext; + +int is_ext(char c) { + return (c && c != '.' && !isspace(c)); +} + +void cpu_error(int code) { + +} + +char *lex_inst(char *s, int *inst_len, char **ext, int *ext_len, int *ext_count) { + char *inst = s; + int count = *ext_count; + for (; is_ext(*s); s++); + *inst_len = s - inst; + for (; *s++ == '.' && count < MAX_QUALIFIERS;) { + ext[count] = s; + for (; is_ext(*s); s++); + ext_len[count] = s - ext[count]; + (ext_len[count] <= 0) ? (cpu_error(34)) : (count++); + } + *ext_count = count; + current_ext = (count > 0) ? tolower(ext[0][0]) : '\0'; + return s; +} diff --git a/lexer/enums.h b/lexer/enums.h new file mode 100644 index 0000000..07338ee --- /dev/null +++ b/lexer/enums.h @@ -0,0 +1,540 @@ +enum am { + /* Part of Base ISA. */ + IMM, /* Immediate Data. */ + ZM, /* Zero Matrix. */ + ZMX, /* Zero Matrix, indexed with X. */ + ZMY, /* Zero Matrix, indexed with Y. */ + IND, /* Indirect. */ + INDX, /* Indexed Indirect. */ + INDY, /* Indirect Indexed. */ + ABS, /* Absolute. */ + REL, /* Relative to Program Counter. */ + BREG, /* B Register. */ + IMPL, /* Implied. */ + /* Part of Base Extension. */ + ABSX, /* Absolute, Indexed with X. */ + ABSY, /* Absolute, Indexed with Y. */ + AIND, /* Absolute Indirect. */ + AINDX, /* Absolute Indexed Indirect. */ + AINDY, /* Absolute Indirect Indexed. */ + EIND, /* Effective Address Register, Indirect. */ +}; + +/* Part of the Orthogonal Extension. */ +enum ortho_reg { + REG_A, + REG_B, + REG_X, + REG_Y, + REG_E, + REG_C, + REG_D, + REG_S, + REG_F, + REG_SP, + REG_BP, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15, +}; + +enum ortho_mem { + MEM_ABS, /* Absolute. */ + MEM_ZM, /* Zero Matrix. */ + MEM_ABSR, /* Absolute, Indexed with register. */ + MEM_ZMR, /* Zero Matrix, Indexed with register. */ + MEM_ZINDR, /* Zero Matrix, Indirect Indexed Register. */ + MEM_ZRIND, /* Zero Matrix, Indexed Indirect Register. */ + MEM_AINDR, /* Absolute, Indirect Indexed Register. */ + MEM_ARIND, /* Absolute, Indexed Indirect Register. */ + MEM_RIND, /* Register Indirect. */ + MEM_SIB, /* Scale Index Base. */ +}; + +enum mne { + ADC, + AND, + ASR, + BCC, + BCS, + BEQ, + BNE, + BNG, + BPO, + BRA, + BRK, + BVC, + BVS, + CLC, + CLI, + CLV, + CMP, + CPB, + CPS, + CPX, + CPY, + DEB, + DEC, + DEX, + DEY, + DIV, + INB, + INC, + INX, + INY, + JMP, + JSR, + LDA, + LDB, + LDX, + LDY, + LSL, + LSR, + MUL, + NOP, + ORA, + PHA, + PHB, + PHP, + PHX, + PHY, + PLA, + PLB, + PLP, + PLX, + PLY, + ROL, + ROR, + RTI, + RTS, + SBC, + SEC, + SEI, + STA, + STB, + STX, + STY, + TAB, + TAX, + TAY, + TBA, + TSX, + TXA, + TXS, + TXY, + TYA, + TYX, + WAI, + XOR +}; + +enum ext_mne { + LEA, + PEA, + ADD, + SUB, + ADE, + SBE, + ADS, + SBS, + NOT, + LLM, + LRM, + RLM, + RRM, + ARM, + PHE, + PLE, + CPE, + ICE, + LDS, + DEE, + INE, + DES, + INS, + STS, + STE, + STZ, + SCO, + ECO, + CLZ, + CLO, + BIT, + MMV, + SWP, + PCN, + REP, + REQ, + RNE, + LNG, + LPO, + LCS, + LCC, + LEQ, + LNE, + SNG, + SPO, + SCS, + SCC, + SEQ, + SNE +}; + +enum ortho_mne { + MNG, + MPO, + MCS, + MCC, + MEQ, + MNE, + MVS, + MVC, + OR , + MOV, + IML, + IDV, + PSH, + PUL, + NEG, + SET +}; + +enum base_isa { + CPS_IMP = 0x00, /* Clear Processor Status. */ + ADC_IMM = 0x01, /* ADd with Carry. */ + ROR_IMM = 0x02, /* ROtate Right. */ + CPB_IMM = 0x04, /* ComPare B register. */ + ADC_Z = 0x05, /* ADC Zero Matrix. */ + ROR_Z = 0x06, /* ROR Zero Matrix. */ + CPB_Z = 0x08, /* CPB Zero Matrix. */ + CLC_IMP = 0x09, /* CLear Carry flag. */ + TAB_IMP = 0x0A, /* Transfer Accumulator to B. */ + STY_Z = 0x0C, /* STore Y register. */ + JMP_AB = 0x10, /* JMP Absolute. */ + ADC_AB = 0x11, /* ADC Absolute. */ + ROR_AB = 0x12, /* ROR Absolute. */ + CPB_AB = 0x14, /* CPB Absolute. */ + ADC_B = 0x15, /* ADC B Register. */ + ROR_B = 0x16, /* ROR B Register. */ + STY_AB = 0x18, /* STY Absolute. */ + SEC_IMP = 0x19, /* SEt Carry flag. */ + TBA_IMP = 0x1A, /* Transfer B to Accumulator. */ + JMP_Z = 0x20, /* JuMP to memory location. */ + SBC_IMM = 0x21, /* SuBtract with Carry. */ + MUL_IMM = 0x22, /* MULtiply accumulator. */ + CPX_IMM = 0x24, /* ComPare X register. */ + SBC_Z = 0x25, /* SBC Zero Matrix. */ + MUL_Z = 0x26, /* MUL Zero Matrix. */ + CPX_Z = 0x28, /* CPX Zero Matrix. */ + CLI_IMP = 0x29, /* CLear Interupt flag. */ + TAY_IMP = 0x2A, /* Transfer Accumulator to Y. */ + STA_Z = 0x2C, /* STore Accumulator. */ + STA_ZX = 0x2E, /* STA Zero Marrix, Indexed with X. */ + JSR_AB = 0x30, /* JSR Absolute. */ + SBC_AB = 0x31, /* SBC Absolute. */ + MUL_AB = 0x32, /* MUL Absolute. */ + CPX_AB = 0x34, /* CPX Absolute. */ + SBC_B = 0x35, /* SBC B Register. */ + MUL_B = 0x36, /* MUL B Register. */ + STA_AB = 0x38, /* STA Absolute. */ + SEI_IMP = 0x39, /* SEt Interupt flag. */ + TYA_IMP = 0x3A, /* Transfer Y to Accumulator. */ + STA_ZY = 0x3C, /* STA Zero Marrix, Indexed with Y. */ + STA_IX = 0x3E, /* STA Indexed Indirect. */ + JSR_Z = 0x40, /* Jump to SubRoutine. */ + AND_IMM = 0x41, /* bitwise AND with accumulator. */ + DIV_IMM = 0x42, /* DIVide with accumulator. */ + CPY_IMM = 0x44, /* ComPare Y register. */ + AND_Z = 0x45, /* AND Zero Matrix. */ + DIV_Z = 0x46, /* DIV Zero Matrix. */ + CPY_Z = 0x48, /* CPY Zero Matrix. */ + CLV_IMP = 0x49, /* CLear oVerflow flag. */ + TAX_IMP = 0x4A, /* Transfer Accumulator to X. */ + STB_Z = 0x4C, /* STore B register. */ + STB_ZX = 0x4E, /* STB Zero Marrix, Indexed with X. */ + RTS_IMP = 0x50, /* ReTurn from Subroutine. */ + AND_AB = 0x51, /* AND Absolute. */ + DIV_AB = 0x52, /* DIV Absolute. */ + CPY_AB = 0x54, /* CPY Absolute. */ + AND_B = 0x55, /* AND B Register. */ + DIV_B = 0x56, /* DIV B Register. */ + STB_AB = 0x58, /* STB Absolute. */ + WAI_IMP = 0x59, /* WAit for Interrupt. */ + TXA_IMP = 0x5A, /* Transfer X to Accumulator. */ + STB_ZY = 0x5C, /* STB Zero Marrix, Indexed with Y. */ + STB_IX = 0x5E, /* STB Indexed Indirect. */ + RTI_IMP = 0x60, /* ReTurn from Interrupt. */ + ORA_IMM = 0x61, /* bitwise OR with Accumulator. */ + ASR_IMM = 0x62, /* Arithmetic Shift Right. */ + LDX_IMM = 0x64, /* LoaD X register. */ + ORA_Z = 0x65, /* ORA Zero Matrix. */ + ASR_Z = 0x66, /* ASR Zero Matrix. */ + LDX_Z = 0x68, /* LDX Zero Matrix. */ + BRK_IMP = 0x69, /* BReaK. */ + TYX_IMP = 0x6A, /* Transfer Y to X. */ + STX_Z = 0x6C, /* STore X register. */ + PHP_IMP = 0x6E, /* PusH Processor status to stack. */ + BPO_REL = 0x70, /* Branch if POsitive. */ + ORA_AB = 0x71, /* ORA Absolute. */ + ASR_AB = 0x72, /* ASR Absolute. */ + LDX_AB = 0x74, /* LDX Absolute. */ + ORA_B = 0x75, /* ORA B Register. */ + ASR_B = 0x76, /* ASR B Register. */ + STX_AB = 0x78, /* STX Absolute. */ + DEY_IMP = 0x79, /* DEcrement Y register. */ + TXY_IMP = 0x7A, /* Transfer X to Y. */ + CPB_IN = 0x7C, /* CPB Indirect */ + PLP_IMP = 0x7E, /* PuLl Processor status from stack. */ + BNG_REL = 0x80, /* Branch if NeGative. */ + XOR_IMM = 0x81, /* bitwise XOR with accumulator. */ + CMP_IMM = 0x82, /* CoMPare accumulator. */ + DEC_IMP = 0x84, /* DECrement accumulator. */ + XOR_Z = 0x85, /* XOR Zero Matrix. */ + CMP_Z = 0x86, /* CMP Zero Matrix. */ + DEC_Z = 0x88, /* DEC Zero Matrix. */ + INY_IMP = 0x89, /* INcrement Y register. */ + TSX_IMP = 0x8A, /* Transfer Stack pointer to X. */ + CMP_IN = 0x8C, /* CMP Indirect */ + PHA_IMP = 0x8E, /* PusH Accumulator to stack. */ + BCS_REL = 0x90, /* Branch if Carry Set. */ + XOR_AB = 0x91, /* XOR Absolute. */ + CMP_AB = 0x92, /* CMP Absolute. */ + DEC_AB = 0x94, /* DEC Absolute. */ + XOR_B = 0x95, /* XOR B Register. */ + CMP_B = 0x96, /* CMP B Register. */ + DEB_IMP = 0x99, /* Decrement B register. */ + TXS_IMP = 0x9A, /* Transfer X to Stack pointer. */ + STY_IN = 0x9C, /* STY Indirect */ + PLA_IMP = 0x9E, /* PuLl Accumulator from stack. */ + BCC_REL = 0xA0, /* Branch if Carry Clear. */ + LSL_IMM = 0xA1, /* Logical Shift Left. */ + LDY_IMM = 0xA2, /* LoaD Y register. */ + INC_IMP = 0xA4, /* INCrement accumulator. */ + LSL_Z = 0xA5, /* LSL Zero Matrix. */ + LDY_Z = 0xA6, /* LDY Zero Matrix. */ + INC_Z = 0xA8, /* INC Zero Matrix. */ + INB_IMP = 0xA9, /* Increment B register. */ + CMP_IX = 0xAA, /* CMP Indexed Indirect. */ + LDY_IN = 0xAC, /* LDY Indirect */ + PHB_IMP = 0xAE, /* PusH B register to stack. */ + BEQ_REL = 0xB0, /* Branch if EQual. */ + LSL_AB = 0xB1, /* LSL Absolute. */ + LDY_AB = 0xB2, /* LDY Absolute. */ + INC_AB = 0xB4, /* INC Absolute. */ + LSL_B = 0xB5, /* LSL B Register. */ + DEX_IMP = 0xB9, /* DEcrement X register. */ + CPB_IX = 0xBA, /* CPB Indexed Indirect. */ + LDX_IN = 0xBC, /* LDX Indirect */ + PLB_IMP = 0xBE, /* PuLl B register to stack. */ + BNE_REL = 0xC0, /* Branch if Not Equal. */ + LSR_IMM = 0xC1, /* Logical Shift Right. */ + LDA_IMM = 0xC2, /* LoaD Accumulator. */ + LDA_IN = 0xC4, /* LDA Indirect */ + LSR_Z = 0xC5, /* LSR Zero Matrix. */ + LDA_Z = 0xC6, /* LDA Zero Matrix. */ + LDA_ZX = 0xC8, /* LDA Zero Marrix, Indexed with X. */ + INX_IMP = 0xC9, /* INcrement X register. */ + STA_IY = 0xCA, /* STA Indirect Indexed. */ + STX_IN = 0xCC, /* STX Indirect */ + PHY_IMP = 0xCE, /* PusH Y register to stack. */ + BVS_REL = 0xD0, /* Branch if oVerflow Set. */ + LSR_AB = 0xD1, /* LSR Absolute. */ + LDA_AB = 0xD2, /* LDA Absolute. */ + STA_IN = 0xD4, /* STA Indirect */ + LSR_B = 0xD5, /* LSR B Register. */ + LDA_ZY = 0xD6, /* LDA Zero Marrix, Indexed with Y. */ + LDA_IX = 0xD8, /* LDA Indexed Indirect. */ + LDA_IY = 0xD9, /* LDA Indirect Indexed. */ + STB_IY = 0xDA, /* STB Indirect Indexed. */ + JSR_IN = 0xDC, /* JSR Indirect */ + PLY_IMP = 0xDE, /* PuLl Y register from stack. */ + BVC_REL = 0xE0, /* Branch if oVerflow Clear. */ + ROL_IMM = 0xE1, /* ROtate Left. */ + LDB_IMM = 0xE2, /* LoaD B register. */ + LDB_IN = 0xE4, /* LDB Indirect */ + ROL_Z = 0xE5, /* ROL Zero Matrix. */ + LDB_Z = 0xE6, /* LDB Zero Matrix. */ + LDB_ZX = 0xE8, /* LDB Zero Marrix, Indexed with X. */ + LDB_IY = 0xE9, /* LDB Indirect Indexed. */ + NOP_IMP = 0xEA, /* No OPeration. */ + JMP_IN = 0xEC, /* JMP Indirect */ + PHX_IMP = 0xEE, /* PusH X register to stack. */ + BRA_REL = 0xF0, /* BRanch Always. */ + ROL_AB = 0xF1, /* ROL Absolute. */ + LDB_AB = 0xF2, /* LDB Absolute. */ + STB_IN = 0xF4, /* STB Indirect */ + ROL_B = 0xF5, /* ROL B Register. */ + LDB_ZY = 0xF6, /* LDB Zero Marrix, Indexed with Y. */ + LDB_IX = 0xF8, /* LDB Indexed Indirect. */ + CMP_IY = 0xF9, /* CMP Indirect Indexed. */ + CPB_IY = 0xFA, /* CPB Indirect Indexed. */ + PLX_IMP = 0xFE /* PuLl X register from stack. */ +}; + +enum base_ext { + LEA_AY = 0x03, /* LEA Absolute, indexed with Y. */ + ADD_IMM = 0x06, /* ADD without carry. */ + LEA_Z = 0x07, /* Load Effective Address. */ + CPE_IMM = 0x08, /* ComPare Effective address register. */ + CLZ_Z = 0x09, /* Count Leading Zeros. */ + ADD_Z = 0x0A, /* ADD Zero Matrix. */ + STB_E = 0x0B, /* STB E Indirect. */ + CPE_Z = 0x0C, /* CPE Zero Matrix. */ + LNG_IMM = 0x0D, /* Load accumulator, if NeGative. */ + LNG_E = 0x0E, /* LNG E Indirect. */ + JMP_E = 0x10, /* JMP E Indirect. */ + ADC_E = 0x11, /* ADC E Indirect. */ + ROR_E = 0x12, /* ROR E Indirect. */ + LEA_AB = 0x13, /* LEA Absolute. */ + CLZ_AB = 0x15, /* CLZ Absolute. */ + ADD_AB = 0x16, /* ADD Absolute. */ + LEA_ZY = 0x17, /* LEA Zero Matrix, indexed with Y. */ + CPE_AB = 0x18, /* CPE Absolute. */ + CLZ_E = 0x19, /* CLZ E Indirect. */ + ADD_E = 0x1A, /* ADD E Indirect. */ + LDX_E = 0x1B, /* LDX E Indirect. */ + SNG_E = 0x1E, /* Store accumulator, if NeGative. */ + PEA_AY = 0x23, /* PEA Absolute, indexed with Y. */ + SUB_IMM = 0x26, /* SUBtract without carry. */ + PEA_Z = 0x27, /* Push Effective Address. */ + CLO_Z = 0x29, /* Count Leading Ones. */ + SUB_Z = 0x2A, /* SUB Zero Matrix. */ + STX_E = 0x2B, /* STX E Indirect. */ + ICE_Z = 0x2C, /* Interlocked Compare, and Exchange. */ + LPO_IMM = 0x2D, /* Load accumulator, if POsitive. */ + LPO_E = 0x2E, /* LPO E Indirect. */ + JSR_E = 0x30, /* JSR E Indirect. */ + SBC_E = 0x31, /* SBC E Indirect. */ + MUL_E = 0x32, /* MUL E Indirect. */ + PEA_AB = 0x33, /* PEA Absolute. */ + CLO_AB = 0x34, /* CLO Absolute. */ + SUB_AB = 0x35, /* SUB Absolute. */ + PEA_ZY = 0x37, /* PEA Zero Matrix, indexed with Y. */ + ICE_AB = 0x38, /* ICE Absolute. */ + CLO_E = 0x39, /* CLO E Indirect. */ + SUB_E = 0x3A, /* SUB E Indirect. */ + CPB_E = 0x3B, /* CPB E Indirect. */ + ICE_E = 0x3C, /* ICE E Indirect. */ + SPO_E = 0x3E, /* Store accumulator, if POsitive. */ + LDS_IMM = 0x40, /* LoaD Stack pointer. */ + LEA_AI = 0x43, /* LEA Absolute Indirect. */ + LDS_Z = 0x44, /* LDS Zero Matrix. */ + ADE_IMM = 0x46, /* ADd Effective address register. */ + LEA_IN = 0x47, /* LEA Indirect. */ + BIT_Z = 0x49, /* BIt Test. */ + ADE_Z = 0x4A, /* ADE Zero Matrix. */ + CPX_E = 0x4B, /* CPX E Indirect. */ + LLM_Z = 0x4C, /* Logical shift Left, on Memory. */ + LCS_IMM = 0x4D, /* Load accumulator, if Carry Set. */ + LCS_E = 0x4E, /* LCS E Indirect. */ + LDS_AB = 0x50, /* LDS Absolute. */ + AND_E = 0x51, /* AND E Indirect. */ + DIV_E = 0x52, /* DIV E Indirect. */ + LEA_AX = 0x53, /* LEA Absolute, indexed with X. */ + LDS_E = 0x54, /* LDS E Indirect. */ + BIT_AB = 0x55, /* BIT Absolute. */ + ADE_AB = 0x56, /* ADE Absolute. */ + LEA_ZX = 0x57, /* LEA Zero Matrix, indexed with X. */ + LLM_AB = 0x58, /* LLM Absolute. */ + BIT_E = 0x59, /* BIT E Indirect. */ + CPY_E = 0x5B, /* CPY E Indirect. */ + LLM_E = 0x5C, /* LLM E Indirect. */ + SCS_E = 0x5E, /* Store accumulator, if Carry Set. */ + SCO_IMM = 0x60, /* Start one, or more COre(s). */ + PEA_AI = 0x63, /* PEA Absolute Indirect. */ + SCO_Z = 0x64, /* SCO Zero Matrix. */ + SBE_IMM = 0x66, /* SuBtract Effective address register. */ + PEA_IN = 0x67, /* PEA Indirect. */ + SBE_Z = 0x6A, /* SBE Zero Matrix. */ + PHE_IMP = 0x6B, /* PusH Effective address register to stack. */ + LRM_Z = 0x6C, /* Logical shift Right, on Memory. */ + LCC_IMM = 0x6D, /* Load accumulator, if Carry Clear. */ + LCC_E = 0x6E, /* LCC E Indirect. */ + SCO_AB = 0x70, /* SCO Absolute. */ + ORA_E = 0x71, /* ORA E Indirect. */ + ASR_E = 0x72, /* ASR E Indirect. */ + PEA_AX = 0x73, /* PEA Absolute, indexed with X. */ + SCO_E = 0x74, /* SCO E Indirect. */ + SBE_AB = 0x76, /* SBE Absolute. */ + PEA_ZX = 0x77, /* PEA Zero Matrix, indexed with X. */ + LRM_AB = 0x78, /* LRM Absolute. */ + PLE_IMP = 0x7B, /* PuLl Effective address register from stack. */ + LRM_E = 0x7C, /* LRM E Indirect. */ + SCC_E = 0x7E, /* Store accumulator, if Carry Clear. */ + ECO_IMM = 0x80, /* End one, or more COre(s). */ + DEC_E = 0x82, /* DEC E Indirect. */ + LEA_AIY = 0x83, /* LEA Absolute Indirect Indexed. */ + ECO_Z = 0x84, /* ECO Zero Matrix. */ + ADS_IMM = 0x86, /* ADd Stack pointer. */ + LEA_IY = 0x87, /* LEA Indirect Indexed. */ + ADS_Z = 0x8A, /* ADS Zero Matrix. */ + DEE_IMP = 0x8B, /* DEcrement Effective address register. */ + RLM_Z = 0x8C, /* Rotate Left, on Memory. */ + LEQ_IMM = 0x8D, /* Load accumulator, if EQual. */ + LEQ_E = 0x8E, /* LEQ E Indirect. */ + ECO_AB = 0x90, /* ECO Absolute. */ + XOR_E = 0x91, /* XOR E Indirect. */ + CMP_E = 0x92, /* CMP E Indirect. */ + LEA_AIX = 0x93, /* LEA Absolute Indexed Indirect. */ + ECO_E = 0x94, /* ECO E Indirect. */ + ADS_AB = 0x96, /* ADS Absolute. */ + LEA_IX = 0x97, /* LEA Indexed Indirect. */ + RLM_AB = 0x98, /* RLM Absolute. */ + ADS_E = 0x9A, /* ADS E Indirect. */ + INE_IMP = 0x9B, /* INcrement Effective address register. */ + RLM_E = 0x9C, /* RLM E Indirect. */ + SEQ_E = 0x9E, /* Store accumulator, if EQual. */ + INC_E = 0xA2, /* INC E Indirect. */ + PEA_AIY = 0xA3, /* PEA Absolute Indirect Indexed. */ + STS_Z = 0xA4, /* STore Stack pointer. */ + SBS_IMM = 0xA6, /* SuBtract Stack pointer. */ + PEA_IY = 0xA7, /* PEA Indirect Indexed. */ + SBS_Z = 0xAA, /* SBS Zero Matrix. */ + DES_IMP = 0xAB, /* DEcrement Stack pointer. */ + RRM_Z = 0xAC, /* Rotate Right, on Memory. */ + LNE_IMM = 0xAD, /* Load accumulator, if Not Equal. */ + LNE_E = 0xAE, /* LNE E Indirect. */ + STS_AB = 0xB0, /* STS Absolute. */ + LSL_E = 0xB1, /* LSL E Indirect. */ + LDY_E = 0xB2, /* LDY E Indirect. */ + PEA_AIX = 0xB3, /* PEA Absolute Indexed Indirect. */ + STS_E = 0xB4, /* STS E Indirect. */ + SBS_AB = 0xB6, /* SBS Absolute. */ + PEA_IX = 0xB7, /* PEA Indexed Indirect. */ + RRM_AB = 0xB8, /* RRM Absolute. */ + SBS_E = 0xBA, /* SBS E Indirect. */ + INS_IMP = 0xBB, /* INcrement Stack pointer. */ + RRM_E = 0xBC, /* RRM E Indirect. */ + REP_REL = 0xBD, /* REPeat until counter is zero. */ + SNE_E = 0xBE, /* Store accumulator, if Not Equal. */ + STY_E = 0xC2, /* STY E Indirect. */ + STE_Z = 0xC4, /* STore Effective address register. */ + NOT_A = 0xC6, /* bitwise NOT with accumulator. */ + NOT_Z = 0xCA, /* NOT Zero Matrix. */ + MMV_IMP = 0xCB, /* Memory MoVe. */ + ARM_Z = 0xCC, /* Arithmetic shift Right, on Memory. */ + REQ_REL = 0xCD, /* Repeat until either counter is zero, or zero flag isn't set. */ + STE_AB = 0xD0, /* STE Absolute. */ + LSR_E = 0xD1, /* LSR E Indirect. */ + LDA_E = 0xD2, /* LDA E Indirect. */ + NOT_AB = 0xD6, /* NOT Absolute. */ + ARM_AB = 0xD8, /* ARM Absolute. */ + NOT_E = 0xDA, /* NOT E Indirect. */ + ARM_E = 0xDC, /* ARM E Indirect. */ + RNE_REL = 0xDD, /* Repeat until either counter is zero, or zero flag is set. */ + STA_E = 0xE2, /* STA E Indirect. */ + STZ_Z = 0xE4, /* STore Zero. */ + SWP_A = 0xE6, /* SWaP lower half, with upper half. */ + SWP_Z = 0xEA, /* SWP Zero Matrix. */ + PCN_Z = 0xEC, /* Population CouNt. */ + STZ_AB = 0xF0, /* STZ Absolute. */ + ROL_E = 0xF1, /* ROL E Indirect. */ + LDB_E = 0xF2, /* LDB E Indirect. */ + STZ_E = 0xF4, /* STZ E Indirect. */ + SWP_AB = 0xF6, /* SWP Absolute. */ + PCN_AB = 0xF8, /* PCN Absolute. */ + SWP_E = 0xFA, /* SWP E Indirect. */ + PCN_E = 0xFC /* PCN E Indirect. */ +}; diff --git a/lexer/lexer.c b/lexer/lexer.c new file mode 100644 index 0000000..1bc7144 --- /dev/null +++ b/lexer/lexer.c @@ -0,0 +1,311 @@ +#include "asmmon.h" +#include "cpu/sux/cpu.h" +#include "lexer.h" + +/* Name: isidstart() + * Desc: Checks if the character is the start of a valid identifier. + * Args: + * c: The character to check. + * Return value: Returns true if the character is the start of a valid identifier, and false if not. + */ + +int isidstart(char c) { + return (isalpha(c) || c == '@' || c == '_'); +} + +/* Name: isidchar() + * Desc: Checks if the character is a valid identifier character. + * Args: + * c: The character to check. + * Return value: Returns true if the character is a valid identifier character, and false if not. + */ + +int isidchar(char c) { + return (isalnum(c) || c == '_'); +} + +/* Name: skip() + * Desc: Skips any whitespace within a string. + * Args: + * s: The string to check. + * Return value: Returns a pointer to the content after the whitespace. + */ + +char *skip(char *s) { + for (; isspace(*s); s++); + return s; +} + +/* Name: iseol() + * Desc: Checks if the character is an end of line character. + * Args: + * c: The character to check. + * Return value: Returns true if the character is an end of line character, and false if not. + */ + +int iseol(char c) { + return (c == '\0' || c == ';'); +} + +/* Name: eol() + * Desc: Checks for end of line, and issues an error, if end of line wasn't found. + * Args: + * s: The string to check. + * Return value: None. + */ + +void eol(char *s) { + if (ignore_trail) { + if (!iseol(*s) && !isspace(*s)) { + syntax_error(6); /* End of line was not found. */ + } + } else { + s = skip(s); + if (!iseol(*s)) { + syntax_error(6); /* End of line was not found. */ + } + } +} + +/* Name: isbadid() + * Desc: Checks if the string is an invalid identifier. + * Args: + * p: The string to check. + * len: Length of the string. + * Return value: Returns true if the string is an invalid identifier, and false if not. + */ + +int isbadid(char *p, int len) { + return (len == 1 && (*p == '@' || *p == '_')); +} + +/* Name: skip_operand() + * Desc: Skips the contents of an operand within a string, gives an error if there + * are either too many closing brackets, or missing closing brackets. + * Args: + * inst_op: Instruction operand flag. + * s: The string to check. + * Return value: Returns the content after the operand. + */ + +char *skip_operand(int inst_op, char *s) { + int brack_count = 0; /* Bracket count. */ + int done = 0; /* Loop done flag. */ + + for (char c = 0;; s++) { + c = *s; + switch (c) { + case '(': brack_count++; break; + case ')': + if (brack_count > 0) { + brack_count--; + } else { + syntax_error(3); /* Too many closing brackets. */ + } + break; + case '\'': + case '\"': s = skip_string(s, c, NULL) - 1; break; + case '\0': + case ';' : done = 1; break; + default : + if ((!inst_op || (inst_op && OPERSEP_COMMA)) && c == ',' && !brack_count) { + done = 1; + break; + } else if (inst_op && OPERSEP_WHITESPACE && isspace(c) && !brack_count) { + done = 1; + break; + } + break; + } + if (done) { + break; + } + } + if (brack_count) { + syntax_error(4); /* Missing closing brackets. */ + } + return s; +} + +/* Name: skip_local() + * Desc: Skips the contents of a local label within a string. + * Args: + * p: The string to check. + * Return value: Returns either a pointer to the content after the local label, or NULL. + */ + +char *skip_local(char *p) { + if (isidstart(*p) || isdigit(*p)) { + for (p++; isidchar(*p); p++); + } else { + p = NULL; + } + return p; +} + +/* Name: get_local_label() + * Desc: Finds a local label within a line. + * Args: + * start: The start of the line. + * Return value: Returns either the name of the local label, or NULL. + */ + +char *get_local_label(char **start) { + char *s = *start; + char *p = skip_local(s); + char *name = NULL; + if (p != NULL && *p == '@' && isidchar(p[1]) && isidstart(*s) && *s != '@') { + /* Skips the local part of a global@local label. */ + s = p+1; + p = skip_local(p); + name = make_local_label(*start, (s-1) - *start, s, p-s); + *start = skip(p); + } else if (p != NULL && p > s+1 && *s == '@') { /* @label */ + s++; + name = make_local_label(NULL, 0, s, p-s); + *start = skip(p); + } + return name; +} + +/* Name: parse_label_or_pc() + * Desc: Finds a global/local label, or the current pc character within a line. + * Args: + * start: The line to parse. + * Return value: Returns either the name of a global/local label, the current pc character, or NULL. + */ + +char *parse_label_or_pc(char **start) { + char *s = skip(*start); + char *name = parse_labeldef(start, 0); + if (name == NULL && *s == current_pc_char && !isidchar(s[1])) { + name = cnvstr(s, 1); + s = skip(s+1); + } + *start = (name) ? s : *start; + return name; +} + +/* Name: lex() + * Desc: Lexically analyze/Tokenize a line into a stream of tokens. + * Args: + * line: The line that will be lexed/tokenized. + * address: Current address of the program counter. + * bline: Current number of blank lines before the current line. + * dbg: Debugging flag. + * Return value: Returns the address of the next line. + */ + +uint64_t lex(char *line, uint64_t address, uint16_t bline, uint8_t dbg) { + char *s; + char *inst; + char *label_name; + char *ext[MAX_QUALIFIERS ? MAX_QUALIFIERS : 1]; + char *op[MAX_OPERANDS]; + int ext_len[MAX_QUALIFIERS ? MAX_QUALIFIERS : 1]; + int op_len[MAX_OPERANDS]; + int ext_cnt; + int op_cnt; + int inst_len; + s = line; + instruction *ip; + + while (isdelm(*s, dbg) != 1) { + label_name = parse_label_or_pc(&s); + if (label_name) { + /* We found a global/local label, or the current pc character. */ + symbol *label; + int equ_len = (*s == '='); + if (equ_len) { + /* Found an equate directive. */ + if (*label_name == current_pc_char) { + handle_org(skip(s+equ_len)); + continue; + } else { + s = skip(s+equ_len); + label = new_equate(label_name, parse_expr_tmplab(&s)); + } + } else { + /* It's just a label. */ + label = new_label_sym(0, label_name); + add_atom(0, new_label_atom(label)); + } + if (!is_local_label(label_name) && autoexport) { + label->flags |= EXPORT; + } + free(label_name); + } + /* Check for directives first. */ + s = skip(s); + if (*s == ';') { + continue; + } + if (*s == current_pc_char && s[1] == '=') { /* "*=" org directive. */ + handle_org(skip(s+2)); + continue; + } + if (handle_directive(s)) { + continue; + } + s = skip(s); + if (iseol(s)) { + continue; + } + /* Read the mnemonic name. */ + inst = s; + if (!isidstart(*s)) { + syntax_error(10); /* Identifier was expected. */ + continue; + } + #if !MAX_QUALLIFIERS + for (; *s && !isspace(*s); s++); + inst_len = s - inst; + #else + s = lex_inst(s, &inst_len, ext, ext_len, &ext_cnt); + #endif + if (!isspace(*s) && *s != '\0') { + syntax_error(2); /* No space before operand. */ + } + s = skip(s); + if (handle_struct(inst, inst_len, s)) { + continue; + } + /* Read the operand(s), separated by comma, or whitespace (unless within brackets). */ + op_cnt = 0; + while (!iseol(*s) && op_cnt < MAX_OPERANDS) { + op[op_cnt] = s; + s = skip_operand(1, s); + op_len[op_cnt] = oplen(s, op[op_cnt]); + op_cnt++; + if (ignore_trail) { + if (*s != ',') { + break; + } + s++; + } else { + s = skip(s); + if (OPERSEP_COMMA) { + if (*s == ',') { + s = skip(s+1); + } else if (!(OPERSEP_WHITESPACE)) { + break; + } + } + } + } + eol(s); + ip = new_inst(inst, inst_len, op_cnt, op, op_len); + if (ip) { + #if MAX_QUALIFIERS > 0 + int i; + for (i = 0; i < ext_cnt; i++) { + ip->qualifiers[i] = cnvstr(ext[i], ext_len[i]); + } + for (; i < MAX_QUALIFIERS; i++) { + ip->qualifiers[i] = NULL; + } + #endif + add_atom(0, new_inst_atom(ip)); + } + } +} diff --git a/lexer/lexer.h b/lexer/lexer.h new file mode 100644 index 0000000..2595158 --- /dev/null +++ b/lexer/lexer.h @@ -0,0 +1,228 @@ +static uint8_t isdelm(char c, uint8_t dbg) { + switch (c) { + default : return 0x00; + case '\0': + case '\n': return 0x01; + case ',' : return 0x02; + case '\"': return 0x04; + case '\'': return 0x08; + case '\t': + case ' ' : return 0x10; + } +} + +static uint8_t isdelm2(char c, uint8_t dbg) { + switch (c) { + default : return 0; + case ')' : + case ',' : + case '.' : + case '+' : + case '<' : + case '|' : + case '>' : + case '-' : + case ':' : + case '=' : + case ';' : + case '\0': + case '\n': return 1; + case '\t': + case ' ' : return 2; + } +} + +static uint8_t get_ptok(char c, uint8_t dbg) { + switch (c) { + case '.' : return PTOK_DOT ; + case '@' : return PTOK_AT ; + case ':' : return PTOK_COLON ; + case '=' : return PTOK_EQU ; + case '+' : return PTOK_PLUS ; + case '-' : return PTOK_MINUS ; + case '>' : return PTOK_GT ; + case '<' : return PTOK_LT ; + case '|' : return PTOK_PIPE ; + case '(' : return PTOK_LBRACK ; + case ')' : return PTOK_RBRACK ; + case ',' : return PTOK_COMMA ; + case 'B': case 'b' : return PTOK_B ; + case 'E': case 'e' : return PTOK_E ; + case 'X': case 'x' : return PTOK_X ; + case 'Y': case 'y' : return PTOK_Y ; + case 'S': case 's' : return PTOK_S ; + case 'P': case 'p' : return PTOK_P ; + case 'A': case 'a' : return PTOK_A ; + case 'C': case 'c' : return PTOK_C ; + case 'D': case 'd' : return PTOK_D ; + case 'F': case 'f' : return PTOK_F ; + case 'R': case 'r' : return PTOK_R ; + case '\"': return PTOK_DQUOTE ; + case '\'': return PTOK_SQUOTE ; + case '#' : return PTOK_HASH ; + case ';' : return PTOK_SCOLON ; + case '$' : return PTOK_DOLLAR ; + case '%' : return PTOK_PERCENT; + default : + if (isdigit(c)) { + return PTOK_NUMBER; + } else if (isalpha(c) || c == '_') { + return PTOK_ALPHA; + } else { + return PTOK_OTHER; + } + } +} + +static uint8_t is_altok(uint8_t ptok, uint8_t dbg) { + switch (ptok) { + case PTOK_B: + case PTOK_E: + case PTOK_X: + case PTOK_Y: + case PTOK_S: + case PTOK_P: return 1; + default : return 0; + } +} + +#if 0 +static int handle_dot(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_at(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_colon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_equ(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_plus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_minus(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_gt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lt(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_pipe(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_lbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_rbrack(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_comma(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_b(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_e(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_x(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_y(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_s(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_p(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dquote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_squote(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_hash(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_scolon(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_dollar(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_percent(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} +static int handle_number(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_alpha(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + +} + +static int handle_other(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg) { + return idx+1; +} + +typedef int (*ptok_func)(char *str, int idx, uint8_t lex_type, line *l, token *t, uint8_t dbg); + +static ptok_func ptok_handler[PTOK_OTHER+1] = { + [PTOK_DOT ] = handle_dot, + [PTOK_AT ] = handle_at, + [PTOK_COLON ] = handle_colon, + [PTOK_EQU ] = handle_equ, + [PTOK_PLUS ] = handle_plus, + [PTOK_MINUS ] = handle_minus, + [PTOK_GT ] = handle_gt, + [PTOK_LT ] = handle_lt, + [PTOK_PIPE ] = handle_pipe, + [PTOK_LBRACK ] = handle_lbrack, + [PTOK_RBRACK ] = handle_rbrack, + [PTOK_COMMA ] = handle_comma, + [PTOK_B ] = handle_b, + [PTOK_E ] = handle_e, + [PTOK_X ] = handle_x, + [PTOK_Y ] = handle_y, + [PTOK_S ] = handle_s, + [PTOK_P ] = handle_p, + [PTOK_DQUOTE ] = handle_dquote, + [PTOK_SQUOTE ] = handle_squote, + [PTOK_HASH ] = handle_hash, + [PTOK_SCOLON ] = handle_scolon, + [PTOK_DOLLAR ] = handle_dollar, + [PTOK_PERCENT] = handle_percent, + [PTOK_NUMBER ] = handle_number, + [PTOK_ALPHA ] = handle_alpha, + [PTOK_OTHER ] = handle_other +}; +#endif diff --git a/lexer/misc.c b/lexer/misc.c new file mode 100644 index 0000000..9014421 --- /dev/null +++ b/lexer/misc.c @@ -0,0 +1,14 @@ +/* Name: cnvstr() + * Desc: Converts a pointer, and length pair into a null-terminated string. + * Args: + * s: Pointer to convert. + * len: Length to convert. + * Return value: Returns a null-terminated string. + */ + +char *cnvstr(char *s, int len) { + char *p = malloc(len+1); + memcpy(p, s, len); + p[len] = '\0'; + return p; +} diff --git a/lexer/parse.c b/lexer/parse.c new file mode 100644 index 0000000..0f26a0e --- /dev/null +++ b/lexer/parse.c @@ -0,0 +1,171 @@ +/* Name: handle_escape() + * Desc: Handles parsing an escape sequence. + * Args: + * s: The string to check. + * code: Pointer to save the handled escape code into, if not NULL. + * Return value: Returns the content after the escape sequence. + */ + +char *handle_escape(char *s, char *code) { + char dummy; + int count; + char *end; + int base = 0; + unsigned int value; + + if (*s++ != '\\') { + ierror(0); /* Start of escape sequence not found. */ + } + if (code == NULL) { + code = &dummy; + } + if (!esc_sequences) { + *code = '\\'; + return s; + } + + switch (*s) { + case 'b' : *code = '\b'; return s+1; + case 'f' : *code = '\f'; return s+1; + case 'n' : *code = '\n'; return s+1; + case 'r' : *code = '\r'; return s+1; + case 't' : *code = '\t'; return s+1; + case '\\': *code = '\\'; return s+1; + case '\"': *code = '\"'; return s+1; + case '\'': *code = '\''; return s+1; + case 'e' : *code = '\x1B'; return s+1; + case 'x' : case 'X' : base = 16; s++; /* Falls Through. */ + case '0' : case '1' : case '2' : case '3' : case '4' : + case '5' : case '6' : case '7' : case '8' : case '9' : + base = (!base) ? 8 : base; + value = strtoull(s, &end, base); + *code = value; + return end; + default : + general_error(35, *s); /* No valid escape sequence was found. */ + return s; + } +} + +/* Name: skip_string() + * Desc: Skips the contents of some delimited string. + * Args: + * s: The string to check. + * delm: Delimiter of the string. + * size: Pointer to save the size of the string into, if not NULL. + * Return value: Returns the content after the string. + */ + +char *skip_string(char *s, char delm, size_t *size) { + size_t n = 0; + + if (*s != delm) { + general_error(6, delm); /* Delimiter was expected. */ + } else { + s++; + } + for (; *s; n++) { + if (*s == '\\') { + s = handle_escape(s, NULL); + } else { + if (*s++ = delm) { + if (*s == delm) { + s++; /* Allow multiple delimiters in a row to be recognized as a single delimiter. */ + } else { + break; + } + } + } + } + if (*(s-1) != delm) { + general_error(6, delm); /* Delimiter was expected. */ + } + if (size) { + *size = n; + } + return s; +} + +/* Name: skip_identifier() + * Desc: Skips the contents of an identifier within a string. + * Args: + * s: The string to check. + * Return value: Returns either a pointer to the content after the identifier, or NULL. + */ + +char *skip_identifier(char *s) { + char *name = s; + if (isidstart(*s) || isdigit(*s)) { + for (s++; isidchar(*s); s++); + if (s) { + if (isbadid(name, s-name)) { + return s; + } + } + } + return NULL; +} + +/* Name: parse_identifier() + * Desc: Parses an indentifier within a line. + * Args: + * s: The line to be parsed. + * Return value: Returns either a pointer to the start of the identifier, or NULL. + */ + +char *parse_identifier(char **s) { + char *name = *s; + char *end_name = skip_identifier(name); + /*char *endgame;*/ /* LOL LE EPIC FUNNY MARVEL THANOS MEME. XDDDDDD */ + if (end_name) { + *s = end_name; + return cnvstr(name, end_name-name); + } + return NULL; +} + +/* Name: parse_symbol() + * Desc: Parses a symbol within a line. + * Args: + * s: The line to be parse. + * Return value: Returns either a pointer to an allocated local/global symbol string, or NULL. + */ + +char *parse_symbol(char **s) { + char *name = get_local_label(s); + name = (name == NULL) ? parse_identifier(s) : name; + return name; +} + +/* Name: parse_labeldef() + * Desc: Parses either a global, or local label definition, at the begining of a line. + * Args: + * line: The line that will be parsed. + * colreq: Require a trailing colon, when true. + * Return value: Returns a pointer to the allocated buffer, when valid. + */ + +char **parse_labeldef(char **line, int colreq) { + char *s = *line; + char *label_name; + + if (isspace(*s)) { + s = skip(s); + colreq = 1; /* Colon required, if label doesn't start at the first column. */ + } + label_name = parse_symbol(&s); + if (label_name) { + s = skip(s); + if (*s == ':') { + s++; + colreq = 0; + } + if (colreq) { + free(label_name); + label_name = NULL; + } else { + *line = s; + } + } + return label_name; +} diff --git a/lexer/symbol.c b/lexer/symbol.c new file mode 100644 index 0000000..7a8001f --- /dev/null +++ b/lexer/symbol.c @@ -0,0 +1,42 @@ +/* Name: make_local_label() + * Desc: Constructs a local label of the form: + * " " + global_name + " " + local_name + * Args: + * global: Global label name. + * global_len: Length of Global label name. + * local: Local label name. + * local_len: Length of Local label name. + * Return value: Returns the constructed local label. + */ + +char make_local_label(char *global, int global_len, char *local, int local_len) { + char *name; + char *p; + + if (!global_len) { + /* Use last defined global. */ + global = last_global; + global_len = strlen(last_global); + } + name = malloc(local_len+global_len+3); + p = name; + *p++ = ' '; + if (global_len) { + memcpy(p, global, global_len); + p += global_len; + } + *p++ = ' '; + memcpy(p, local, local_len); + p[local_len] = '\0'; + return name; +} + +/* Name: + * Desc: + * Args: + * + * + * + * + * Return value: + */ @@ -11,6 +11,7 @@ #define OPNUM 74 #define EXT_OPNUM 49 +#define ORTHO_OPNUM 16 #define C (1 << 0) /* Carry flag. */ #define Z (1 << 1) /* Zero flag. */ diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s index 74ad654..3dc9d63 100644 --- a/programs/sub-suite/libc.s +++ b/programs/sub-suite/libc.s @@ -126,53 +126,49 @@ isdigit: sbc #'0' ; Subtract $30 from the passed character. and #$FF ; Make sure that we have only one byte. cmp #10 ; Is the subtracted value, less than 10? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. -@end: + lcc #1 ; Yes, so return true. + lcs #0 ; No, so return false. +; bcs @false ; No, so return false. +;@true: +; lda #1 ; Yes, so return true. +; bra @end ; We are done. +;@false: +; lda #0 ; Return false. +;@end: rts ; End of isdigit. isxdigit: pha ; Preserve the character. jsr isdigit ; Is this character, a decimal digit? pla ; Get the character back. - bne @true ; Yes, so return true. + bne @end ; Yes, so return true. @alpha: - sec ; No, so prepare for a non carrying subtract. - ora #$20 ; Convert it to lowercase. - sbc #'a' ; Subtract $61 from the character. + ora #$20 ; No, so convert it to lowercase. + sub #'a' ; Subtract $61 from the character. and #$FF ; Make sure that we have only one byte. cmp #6 ; Is the subtracted value, less than 6? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. + lcc #1 ; Yes, so return true. + lcs #0 ; No, so return false. +; bcs @false ; No, so return false. +;@true: +; lda #1 ; Yes, so return true. +; bra @end ; We are done. +;@false: +; lda #0 ; Return false. @end: rts ; End of isxdigit. isupper: - sec ; Prepare for a non carrying subtraction. - sbc #'A' ; Subtract $41 from the passed character. + sub #'A' ; Subtract $41 from the passed character. bra isletter ; Check if it's less than 26. islower: - sec ; Prepare for a non carrying subtraction. - sbc #'a' ; Subtract $61 from the passed character. + sub #'a' ; Subtract $61 from the passed character. isletter: and #$FF ; Make sure that we have only one byte. cmp #26 ; Is the subtracted value, less than 26? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. -@end: + lcc #1 ; Yes, so return true. + lcs #0 ; No, so return false rts ; End of isletter. @@ -209,8 +205,7 @@ malloc: pha.q ; Preserve the size. and #0 ; Reset A. tay ; Reset Y. - pha.q ; Create two more local variables. - pha.q ; + sbs #$10 ; Allocate 2 local variables onto the stack. lda.q sp+17 ; Get the size. ora.d sp+21 ; Is the size zero? beq @end ; Yes, so we're done. @@ -300,9 +295,7 @@ malloc: clc ; Prepare for a non carrying add. adc #ublk ; Return the pointer to the real memory block. @end: - ply.q ; Clean up the stack frame. - ply.q ; - ply.q ; + ads #$18 ; Clean up the stack frame. ply.q ; Restore Y. rts ; End of malloc. @@ -320,9 +313,7 @@ free: pha.q ; Push the pointer argument to the stack. and #0 ; Reset A. tay ; Reset Y. - pha.q ; Add 3 more local variables. - pha.q ; - pha.q ; + sbs #$18 ; Allocate 3 local variables onto the stack. lda.q sp+25 ; Get the passed pointer. ora.d sp+29 ; Is the passed pointer NULL? bne @getrealblk ; No, so get the real block. @@ -373,10 +364,7 @@ free: ldy #fblk.next ; Delete the next block. sta.q (sp+25), y; @end: - pla.q ; Clean up the stack frame. - pla.q ; - pla.q ; - pla.q ; + ads #$20 ; Clean up the stack frame. ply.q ; Restore Y. plb.q ; Restore B. pla.q ; Restore A. @@ -500,10 +488,7 @@ free: ldy #fblk.prev ; Set the previous block, to the left pointer. sta.q (sp+25), y; @end2: - pla.q ; Clean up the stack frame. - pla.q ; - pla.q ; - pla.q ; + ads #$20 ; Clean up the stack frame. ply.q ; Restore Y. plb.q ; Restore B. pla.q ; Restore A. @@ -534,8 +519,6 @@ memcpy: beq @end ; The size is zero, so we're done. bra @loop ; Keep looping. @end: - pla.q ; Clean up the stack frame. - pla.q ; - pla.q ; + ads #$18 ; Clean up the stack frame. pla.q ; Restore the return value. rts ; End of memcpy. diff --git a/programs/sub-suite/shift_line.c b/programs/sub-suite/shift_line.c new file mode 100644 index 0000000..255d21b --- /dev/null +++ b/programs/sub-suite/shift_line.c @@ -0,0 +1,79 @@ +#include <stdint.h> + +const uint8_t bits[8] = { + 0x80, + 0x40, + 0x20, + 0x10, + 0x08, + 0x04, + 0x02, + 0x01 +}; + +int maxcol = 80; +int scr_str = 0; +int scr_row = 0; +int scr_col = 0; +uint8_t bitabl[16]; + +uint8_t bitpos(unsigned int row, uint8_t *mask) { + uint8_t bit = row & 7; + *mask = bits[bit]; + return row >> 3; + +} + +void setbit(unsigned int row) { + uint8_t mask; + uint8_t byte = bitpos(row, &mask); + bitabl[byte] |= mask; +} + +void clrbit(unsigned int row) { + uint8_t mask; + uint8_t byte = bitpos(row, &mask); + bitabl[byte] &= ~mask; +} + +int find_end(char *str, int start) { + int i; + for (i = start; str[i]; i++); + return i; +} + +void shift_line(char *str, int cursor, int left) { + /*int cursor = ((scr_row+scr_str)*maxcol)+scr_col;*/ + int end = find_end(str, cursor); + if (left) { + int i = end-1; + int j = end; + for (; i > cursor; i--, j--) { + if (i < 0) { + i = 0; + str[i] = 0; + break; + } + str[j] = str[i]; + str[i] = 0; + + } + /*str[i+1] = (!str[i+1]) ? ' ' : str[i+1];*/ + end = find_end(str, i+2); + /*str[i+1] = (str[i+1] == ' ') ? 0 : str[i+1];*/ + if ((end/maxcol) > scr_row) { + setbit(end/maxcol); + } + } else { + int i = cursor; + int j = cursor-1; + for (; str[i]; i++, j++) { + str[j] = str[i]; + str[i] = 0; + } + end = find_end(str, i); + if ((end % maxcol) == 0 && (end/maxcol) > scr_row) { + clrbit(end/maxcol); + } + } +} diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s index 0a3ee80..7b2b8b9 100644 --- a/programs/sub-suite/subasm.s +++ b/programs/sub-suite/subasm.s @@ -16,21 +16,17 @@ subasm: jsr lex ; No, so start lexing this line. bra @end ; We are done. @cmd: - ldb #1 ; Set the second pointer - lda.d #cmd_srt ; to the command subroutine table. - jsr set_ptr ; - deb ; Reset B. - tba ; Reset A. lda regf ; Get the command ID. cmp #8 ; Is the command ID greater than the command count? bcs @end ; Yes, so we're done. lsl #1 ; No, so multiply the command ID by two. - tay ; Set the index to the offset that we just calculated. - lda.w (ptr2), y ; Get the command subroutine, from the command subroutine table. - ldb #2 ; Save it in the third pointer. - jsr set_ptr ; - ldb #0 ; Reset B. - jsr (ptr3) ; Run the command's subroutine. + phx.q ; Preserve X. + tax ; Set the index to the offset that we just calculated. + lea.w (cmd_srt, x); Get the pointer, from the command subroutine table. + plx.q ; Restore X. + and #0 ; Reset A. + tab ; Reset B. + jsr (e) ; Run the command's subroutine. @end: and #0 ; Reset A. jsr update_ptr ; Get the screen buffer index. @@ -39,12 +35,14 @@ subasm: rts ; End of subasm. chk_shcmd: - tba ; Reset A. - inb ; Set the second pointer - lda.w #sh_cmds ; to the shortend command table. - jsr set_ptr ; - deb ; Reset B. - tba ; Reset A. + and #0 ; Reset A. + tab ; Reset B. +; inb ; Set the second pointer +; lda.w #sh_cmds ; to the shortend command table. +; jsr set_ptr ; +; deb ; Reset B. +; tba ; Reset A. + lea sh_cmds ; Get the address of the short command table. phy.w ; Preserve the screen buffer position. txy ; Set our index to zero. lda (ptr), y ; Is there nothing in the command buffer? @@ -53,27 +51,31 @@ chk_shcmd: beq @false ; Yes, so return that we failed. jsr tolower ; No, so convert it to lowercase. @loop: - ldb (ptr2), y ; Are we at the end of the table? +; ldb (ptr2), y ; Are we at the end of the table? + ldb (e) ; Are we at the end of the table? beq @false ; Yes, so return that we failed. cmp b ; No, so did the character match? beq @found ; Yes, so check if there are any arguments. - iny ; No, so check the next command. + ine ; No, so check the next command. + iny ; bra @loop ; Keep looping. @found: sty regf ; Save the command ID. - ldy #1 ; Check the next character in the command buffer. - lda (ptr), y ; Is this the end of the buffer? - beq @true ; Yes, so return that we succeded. + lea (ptr) ; Get the address of the next character. + ine ; +; ldy #1 ; Check the next character in the command buffer. +; lda (ptr), y ; Is this the end of the buffer? + lda (e) ; Is this the end of the buffer? + beq @true ; Yes, so return true. cmp #' ' ; No, but is this a space? - beq @true ; Yes, so return that we succeded. - bra @false ; No, so return that we failed. -@true: - lda #1 ; Return true. - bra @end ; We are done. + beq @true ; Yes, so return true. @false: ldb #0 ; Reset B. tba ; Return false. tax ; Reset X. + bra @end ; We are done. +@true: + lda #1 ; Return true. @end: ply.w ; Get back the screen buffer position. rts ; End of chk_shcmd. @@ -130,8 +132,9 @@ viewmem: jsr print_char ; jsr print_hi ; Place the address in the string buffer. jsr print_chunk ; Place the next 16 bytes in the string buffer. - lda.d #strbuf ; Print the string buffer. - jsr print_str ; + lea strbuf ; Print the string buffer. +; jsr print_str ; + jsr print_sfast ; inc idx1 ; Increment the chunk count. ldb idx1 ; Get the chunk count. cpb #$10 ; Did we print 16 chunks? diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index bec3f41..43768f7 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -6,18 +6,18 @@ .org $8000 reset: cps ; Reset the processor status register. - ldx.d #$2FFFF ; Reset the stack pointer. - txs ; + lds.d #$2FFFF ; Reset the stack pointer. + lea 0 ; Reset E. ldy #0 ; Reset Y. tyx ; Reset X. jsr init_heap ; Initialize the heap. tax ; Set the stack pointer to the end of RAM. txs ; - sec ; Prepare for a non borrowing subtract. - sbc.d #STKSIZE ; Subtract the stack size, from the end of RAM. + sub.d #STKSIZE ; Subtract the stack size, from the end of RAM. sta.q heapend ; Save the end of the heap. and #0 ; Reset A. tax ; Reset X. + clc ; Reset the carry flag, just in case. jsr init_tables ; Initialize the main tables. ; jsr test_free ; jsr clr_scr ; Clear the screen. @@ -26,14 +26,9 @@ reset: init_heap: - and #0 ; Reset A. - lda.d #HEAPORG ; Get the heap's starting point. - sta.q heapptr ; - phb.q ; Preserve the value in B. - phx.q ; Preserve the value in X. + lea HEAPORG ; Get the heap's starting point. + ste.q heapptr ; jsr findramend ; Find the end of the heap. - plb.q ; Restore the value in B. - plx.q ; Restore the value in X. rts ; End of init_heap. @@ -79,50 +74,32 @@ init_tables: clr_arr: - phb ; Preserve whatever was in B. - ldb #0 ; Clear B. - jsr set_ptr ; Set the first pointer to the parameter. - adc #8 ; Set the second pointer to the parameter, plus eight. - inb ; Tell set_ptr to set the second pointer. - jsr set_ptr ; - deb ; Set B back to zero. - tba ; -@loop: - cpy.w scr_ptr ; Did we clear all of the array? - bcs @end ; Yes, so we're done. - sta.q (ptr), y ; No, so clear eight bytes. - sta.q (ptr2), y ; Clear eight more bytes. - tya ; Copy the array index. - adc #$10 ; Increment the index by 16. - tay ; Update the index. - tba ; Reset the Accumulator. - sta.q (ptr), y ; Do this one more time, to clear 32 bytes. - sta.q (ptr2), y ; - tya ; - adc #$10 ; - tay ; - tba ; - bra @loop ; Keep looping. + stz.q (e) ; Clear eight bytes. + ade #8 ; Increment the pointer by 8. + stz.q (e) ; Clear eight bytes. + ade #8 ; Increment the pointer by 8. + sub #$10 ; Subtract 16 from the size. + bcc @end ; We've reached the end of the array, so we're done. + beq @end ; + bra clr_arr ; Keep looping. @end: - ldy.w zero ; Set the index back to zero. - plb ; Get whatever was in the B register, back. rts ; End of clr_arr. pnt_strt: - lda.w #ed_name ; Print the name of the editor. + lea ed_name ; Print the name of the editor. jsr print_str ; - lda.w #ver_str ; Print the version text. + lea ver_str ; Print the version text. jsr print_str ; - lda.w #ed_ver ; Print the version number. + lea ed_ver ; Print the version number. jsr print_str ; - lda.w #ed_sver ; Print the sub version number. + lea ed_sver ; Print the sub version number. jsr print_str ; lda #'\n' ; Print a newline. jsr print_char ; - lda.w #made ; Print the "Created by" text. + lea made ; Print the "Created by" text. jsr print_str ; - lda.w #author ; Print the name of the author. + lea author ; Print the name of the author. jsr print_str ; lda #'\n' ; Print a newline. jsr print_char ; @@ -133,8 +110,7 @@ clr_cmd: and #0 ; Reset A. tay ; Reset Y. lda.w #CMDSIZE ; Set the clear count to CMDSIZE. - sta.w scr_ptr ; - lda.q cmd_buf ; Set the array to be cleared to the command buffer. + lea (cmd_buf) ; Set the array to be cleared to the command buffer. jsr clr_arr ; Clear the command buffer. rts ; End of clr_cmd. @@ -173,37 +149,59 @@ getchar: print_str: - ldx #0 ; Reset X. - sta.q end ; Save the parameter. -@reset: - lda.q end ; Get the parameter. - ldb #0 ; Clear the B register. - jsr set_ptr ; Set the first pointer to the parameter. - tba ; Clear the Accumulator. + and #0 ; Reset A. + tba ; Reset B. @loop: ldb #1 ; Enable replace mode. stb regb ; - lda.q ptr ; Get the first pointer. - cmp.q end ; Did the pointer change? - bne @reset ; Yes, so set it back. and #0 ; No, reset the accumulator. - txy ; Copy the string index into Y. - ldb (ptr), y ; Are we at the end of the string? + ldb (e) ; Are we at the end of the string? beq @end ; Yes, so we're done. jsr update_ptr ; No, so get the screen buffer index. tay ; Save it in Y. tba ; Get the character back. - inx ; Increment the string index. - phx ; Preserve the string index. + ine ; Increment the string pointer. jsr print_char ; Print the character. - plx ; Get the string index back. bra @loop ; Keep looping. @end: - ldb #0 ; Enable insert mode. - stb regb ; - tba ; Reset A. + stz regb ; Enable insert mode. + and #0 ; Reset A. + tab ; Reset B. rts ; End of print_str. + +;print_str: +; ldx #0 ; Reset X. +; sta.q end ; Save the parameter. +;@reset: +; lda.q end ; Get the parameter. +; ldb #0 ; Clear the B register. +; jsr set_ptr ; Set the first pointer to the parameter. +; tba ; Clear the Accumulator. +;@loop: +; ldb #1 ; Enable replace mode. +; stb regb ; +; lda.q ptr ; Get the first pointer. +; cmp.q end ; Did the pointer change? +; bne @reset ; Yes, so set it back. +; and #0 ; No, reset the accumulator. +; txy ; Copy the string index into Y. +; ldb (ptr), y ; Are we at the end of the string? +; beq @end ; Yes, so we're done. +; jsr update_ptr ; No, so get the screen buffer index. +; tay ; Save it in Y. +; tba ; Get the character back. +; inx ; Increment the string index. +; phx ; Preserve the string index. +; jsr print_char ; Print the character. +; plx ; Get the string index back. +; bra @loop ; Keep looping. +;@end: +; stz regb ; Enable insert mode. +; and #0 ; Reset A. +; tab ; Reset B. +; rts ; End of print_str. + getbit: clc ; Clear the carry flag. lda scr_str ; Has the screen been scrolled? @@ -432,21 +430,27 @@ findend: print_char: + phe.q ; Preserve E. sta rega ; Preserve the character. ldb #2 ; Make sure that set_ptr sets the third pointer. lda.q buffer ; Set the third pointer to the start of the screen buffer. jsr set_ptr ; deb ; Set B to one. tba ; Reset A. +; inc step ; lda rega ; Get the character back. jsr get_ctrlidx ; Get the control code jump table index. lsl #1 ; Multiply the return value by two, to get the index. tax ; - lda.w ct_jtb, x ; Get the address of the control code handler. - jsr set_ptr ; Set the second pointer to the control code handler. + lea.w (ct_jtb, x); Get the address of the control code handler. +; pha.q ; +; ple.q ; +; jsr set_ptr ; Set the second pointer to the control code handler. deb ; Reset B. tba ; Reset A. - jmp (ptr2) ; Jump to the handler for that control code. + jsr (e) ; Jump to the handler for that control code. + ple.q ; Restore E. + rts printc: lda #0 ; start trying to print a character. sta regd ; @@ -567,24 +571,19 @@ nl: clr_scr: lda #maxrow ; sta scr_end ; - lda #0 ; - sta scr_str ; + stz scr_str ; tay ; lda.w #LWSIZE ; Set the clear count to LWSIZE. - sta.w scr_ptr ; - lda.q bitabl ; Set the array to be cleared to the linewrap table. + lea (bitabl) ; Set the array to be cleared to the linewrap table. jsr clr_arr ; Clear the linewrap table. lda.w #SCRSIZE ; Set the clear count to SCRSIZE. - sta.w scr_ptr ; - lda.q buffer ; Set the array to be cleared to the screen buffer. + lea (buffer) ; Set the array to be cleared to the screen buffer. jsr clr_arr ; Clear the screen buffer. -; tay ; ; lda.w #CMDSIZE ; Set the clear count to CMDSIZE. -; sta.w scr_ptr ; -; lda.d #cmd_buf ; Set the array to be cleared to the command buffer. +; lea (cmd_buf) ; Set the array to be cleared to the command buffer. ; jsr clr_arr ; Clear the screen buffer. - sta scr_col ; - sta scr_row ; + stz scr_col ; + stz scr_row ; jsr update_pos ; lda #$C ; sta scr ; @@ -767,6 +766,7 @@ shftln: @end5: rts ; End of shftln. + esc: lda status ; Get the next character. lda kbd ; diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s index d28b4f2..b276209 100644 --- a/programs/sub-suite/subsuite.s +++ b/programs/sub-suite/subsuite.s @@ -17,7 +17,8 @@ .qword reset a ;l a -;.org reset +;.org reset+$F50 ;v +;f "subsuite.bin" $8000 ;q d diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s index 21539eb..3813a05 100644 --- a/programs/sub-suite/utils.s +++ b/programs/sub-suite/utils.s @@ -48,12 +48,20 @@ print_lo: pla ; Get the nibble offset back. bra @loop ; Keep looping. @end: - lda #0 ; Null terminate the string buffer. - sta strbuf, x ; + and #0 ; Reset A. + sta strbuf, x ; Null terminate the string buffer. tax ; Reset X. - lda.d #strbuf ; Print the string buffer. - jsr print_str ; + lea strbuf ; Print the string buffer. +; jsr print_str ; + jsr print_sfast ; Use the faster, but less robust print string routine. rts ; End of print_lo. +;@end: +; lda #0 ; Null terminate the string buffer. +; sta strbuf, x ; +; tax ; Reset X. +; lea strbuf ; Print the string buffer. +; jsr print_str ; +; rts ; End of print_lo. print_chunk: @@ -302,49 +310,76 @@ get_ptok: get_ctrlidx: - cmp #$7F ; Is this a delete character? - beq @del ; Yes, so return the same value as backspace. - sec ; Do a non borrowing subtract. - sbc #8 ; Subtract 8 from the character, to get the index. +; phe.q ; Preserve E. +; cmp #$7F ; Is this a delete character? +; beq @del ; Yes, so return the same value as backspace. +; sec ; Do a non borrowing subtract. +; sbc #8 ; Subtract 8 from the character, to get the index. + sub #8 ; Subtract 8 from the character, to get the index. tax ; Copy the index to X. and #0 ; Reset A. - cpx #19 ; Are we less than, or equal to the max size of the table? - bcc @get_rtval ; Yes, so get the return value from the table. - beq @get_rtval ; - rts ; End of get_ctrlidx. -@get_rtval: - lda ct_rtb, x ; Get the return value from the table. - rts ; End of get_ctrlidx. -@del: - lda #2 ; Return 2. + cpx #19 ; Are we within the range of the table? + lea ct_rtb, x ; Get the address of the value to return. + lcc (e) ; Read from the table if we're within the range of the table. + leq (e) ; + cmp #$7F ; Is this a delete character? + leq #2 ; Return 2 if this is the delete character. +; bcc @get_rtval ; Yes, so get the return value from the table. +; beq @get_rtval ; +; ple.q ; Restore E. rts ; End of get_ctrlidx. +;@get_rtval: +; lda ct_rtb, x ; Get the return value from the table. +; rts ; End of get_ctrlidx. +;@del: +; lda #2 ; Return 2. +; rts ; End of get_ctrlidx. findramend: - pha.q ; Set the end of RAM pointer to the argument. + phx.q ; Preserve X. and #0 ; Reset A. - tab ; Reset B. lda #MAGIC ; Set A to a magic number. @loop: - ldx (sp+1) ; Preserve the value. - sta (sp+1) ; Write the magic number to the current end of RAM. - cmp (sp+1) ; Is the value in RAM, the same as the magic number we wrote? + ldx (e) ; Preserve the value. + sta (e) ; Write the magic number to the current end of RAM. + cmp (e) ; Is the value in RAM, the same as the magic number we wrote? bne @moveback ; No, so move back until we find the last writable memory location. - stx (sp+1) ; Yes, so restore the previous value. - pha.q ; Preserve the magic number. - lda.q sp+9 ; Get the end of RAM pointer. - clc ; Prepare for a non carrying add. - adc.w #$4000 ; Increment the end of RAM pointer by 16K. - sta.q sp+9 ; Save the new end of RAM pointer. - pla.q ; Restore the magic number. + stx (e) ; Yes, so restore the previous value. + ade.w #$4000 ; Increment the end of RAM pointer by 16K. bra @loop ; Keep looping. @moveback: - dec.q sp+1 ; Decrement the end of RAM pointer. - ldx (sp+1) ; Preserve the value. - sta (sp+1) ; Write the magic number to the current end of RAM. - cmp (sp+1) ; Is the value in RAM, the same as the magic number we wrote? + dee ; Decrement the end of RAM pointer. + ldx (e) ; Preserve the value. + sta (e) ; Write the magic number to the current end of RAM. + cmp (e) ; Is the value in RAM, the same as the magic number we wrote? bne @moveback ; No, so keep looping. - stx (sp+1) ; Yes, so restore the previous value. + stx (e) ; Yes, so restore the previous value. @end: - pla.q ; Restore the argument. + phe.q ; Return the end of RAM pointer. + pla.q ; + plx.q ; Restore X. rts ; End of findramend. + + +print_sfast: +; inc step ; + pea (buffer), y ; Push the address of the cursor's postion in the screen buffer to the stack. +@loop: + lda (e) ; Get the character. + beq @end ; We've hit the end of the string, so we're done. + cmp #'\n' ; Did we get a newline? + beq @nl ; Yes, so move the cursor to the next line. + sta (sp+1) ; Print the character to the screen buffer. + sta scr ; Print the character to the screen. + inc scr_col ; Move the cursor left by one character. + ine ; Increment the string pointer. + inc.q sp+1 ; Increment the screen buffer pointer. + bra @loop ; Keep looping. +@nl: + stz scr_col ; Move the cursor to the start of the line. + inc scr_row ; Move the cursor down by one line. + bra @loop ; Keep looping. +@end: + ads #8 ; Cleanup the stack frame. + rts ; End of print_sfast. @@ -97,7 +97,9 @@ uint8_t is_extop(uint8_t opcode, uint8_t dbg) { case STY_E: case STA_E: case STB_E: - case STX_E: return 0; + case STX_E: + case JMP_E: + case JSR_E: return 0; } return 1; } @@ -178,16 +180,16 @@ void *run(void *args) { uint32_t instr = read_value(cpu, 0, cpu->pc, 3, 1, 0); uint8_t *tmp_inst = (uint8_t *)&instr; prefix = ((instr & 3) == 3) ? *tmp_inst++ : 0; - ext_prefix = ((*tmp_inst & 0xD) == 0xD) ? *tmp_inst++ : 0; + ext_prefix = ((*tmp_inst & 0xF) == 0xD) ? *tmp_inst++ : 0; opcode = *tmp_inst; - cpu->pc += ((instr & 3) == 3)+((ext_prefix & 0xD) == 0xD)+1; + cpu->pc += ((instr & 3) == 3)+((ext_prefix & 0xF) == 0xD)+1; address.u64 = cpu->pc; uint8_t am; uint8_t ext_id = 0; uint8_t tmp_opcode = opcode; uint8_t tmp_ext_prefix = ext_prefix; if (ext_prefix) { - ext_id = ((ext_prefix >> 4) & 0xF); + ext_id = (ext_prefix >> 4); switch (ext_id) { case 0x0: am = ext_optype[opcode]; @@ -220,6 +222,8 @@ void *run(void *args) { case STA_E: tmp_opcode = STA_Z; break; case STB_E: tmp_opcode = STB_Z; break; case STX_E: tmp_opcode = STX_Z; break; + case JMP_E: tmp_opcode = JMP_Z; break; + case JSR_E: tmp_opcode = JSR_Z; break; } } break; @@ -246,7 +250,7 @@ void *run(void *args) { addr[STEP_ADDR] = 1; step = 1; }*/ - if (isrw(opcode) && am != REL && isread(opcode)) { + if (isrw(opcode, ext_prefix) && am != REL && isread(opcode, ext_prefix)) { value.u64 = read_value(cpu, 0, address.u64, size, 1, check_io); } } @@ -254,12 +258,14 @@ void *run(void *args) { ext_prefix = tmp_ext_prefix; opcode = tmp_opcode; if (ext_prefix) { + uint8_t tmp = 0; switch (ext_id) { - case 0x0: exec_ext_inst(cpu, opcode, prefix, value, address, size, thread); break; + case 0x0: exec_ext_inst(cpu, opcode, prefix, value.u64, address.u64, size, thread); break; } } else { - exec_base_inst(cpu, opcode, prefix, value, address, size, thread); + exec_base_inst(cpu, opcode, prefix, value.u64, address.u64, size, thread); } + //usleep(1); #if !IO ins++; #endif @@ -55,7 +55,7 @@ extern void io(uint64_t address, uint8_t rw); extern void init_scr(); -static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { +static /*inline*/ uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { uint8_t id = (prefix & 0x0C) >> 2; switch (addrmode) { case ZM: @@ -88,72 +88,177 @@ static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { return 0xFF; } -static inline uint8_t isrw(uint8_t opcode) { - switch (opcode) { - case STA_AB: /* STA Absolute. */ - case STA_Z: /* STA Zero Matrix. */ - case STA_ZX: /* STA Zero Matrix, Indexed with X. */ - case STA_ZY: /* STA Zero Matrix, Indexed with Y. */ - case STA_IN: /* STA Indirect. */ - case STA_IX: /* STA Indexed Indirect. */ - case STA_IY: /* STA Indirect Indexed. */ - case STY_AB: /* STY Absolute. */ - case STY_Z: /* STY Zero Matrix. */ - case STY_IN: /* STY Indirect. */ - case STX_AB: /* STX Absolute. */ - case STX_Z: /* STX Zero Matrix. */ - case STX_IN: /* STX Indirect. */ - case STB_AB: /* STB Absolute. */ - case STB_Z: /* STB Zero Matrix. */ - case STB_ZX: /* STB Zero Matrix, Indexed with X. */ - case STB_ZY: /* STB Zero Matrix, Indexed with Y. */ - case STB_IN: /* STB Indirect. */ - case STB_IX: /* STB Indexed Indirect. */ - case STB_IY: /* STB Indirect Indexed. */ - case INC_AB: /* INC Absolute. */ - case INC_Z: /* INC Zero Matrix. */ - case DEC_AB: /* DEC Absolute. */ - case DEC_Z: /* DEC Zero Matrix. */ - return 0; /* Writing. */ - default: - return 1; /* Reading. */ +static /*inline*/ uint8_t isrw(uint8_t opcode, uint8_t ext_prefix) { + if ((ext_prefix & 0xD) == 0xD) { + switch (ext_prefix >> 4) { + case 0x0: + switch (opcode) { + case STA_E : + case STB_E : + case STX_E : + case STY_E : + case STE_AB: + case STE_Z : + case STS_AB: + case STS_Z : + case STS_E : + case STZ_AB: + case STZ_Z : + case STZ_E : + case SNG_E : + case SPO_E : + case SCC_E : + case SCS_E : + case SEQ_E : + case SNE_E : + case INC_E : + case DEC_E : + case NOT_AB: + case NOT_Z : + case NOT_E : + case SWP_AB: + case SWP_Z : + case SWP_E : + case LLM_AB: + case LLM_Z : + case LLM_E : + case LRM_AB: + case LRM_Z : + case LRM_E : + case RLM_AB: + case RLM_Z : + case RLM_E : + case RRM_AB: + case RRM_Z : + case RRM_E : + case ARM_AB: + case ARM_Z : + case ARM_E : return 0; + default : return 1; + } + } + } else { + switch (opcode) { + case STA_AB: /* STA Absolute. */ + case STA_Z: /* STA Zero Matrix. */ + case STA_ZX: /* STA Zero Matrix, Indexed with X. */ + case STA_ZY: /* STA Zero Matrix, Indexed with Y. */ + case STA_IN: /* STA Indirect. */ + case STA_IX: /* STA Indexed Indirect. */ + case STA_IY: /* STA Indirect Indexed. */ + case STY_AB: /* STY Absolute. */ + case STY_Z: /* STY Zero Matrix. */ + case STY_IN: /* STY Indirect. */ + case STX_AB: /* STX Absolute. */ + case STX_Z: /* STX Zero Matrix. */ + case STX_IN: /* STX Indirect. */ + case STB_AB: /* STB Absolute. */ + case STB_Z: /* STB Zero Matrix. */ + case STB_ZX: /* STB Zero Matrix, Indexed with X. */ + case STB_ZY: /* STB Zero Matrix, Indexed with Y. */ + case STB_IN: /* STB Indirect. */ + case STB_IX: /* STB Indexed Indirect. */ + case STB_IY: /* STB Indirect Indexed. */ + case INC_AB: /* INC Absolute. */ + case INC_Z: /* INC Zero Matrix. */ + case DEC_AB: /* DEC Absolute. */ + case DEC_Z: /* DEC Zero Matrix. */ + return 0; /* Writing. */ + default: + return 1; /* Reading. */ + } } } -static inline uint8_t isread(uint8_t opcode) { - switch (opcode) { - case LDA_IMM: /* LDA Immediate. */ - case LDA_AB: /* LDA Absolute. */ - case LDA_Z: /* LDA Zero Matrix. */ - case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */ - case LDA_ZY: /* LDA Zero Matrix, Indexed with Y. */ - case LDA_IN: /* LDA Indirect. */ - case LDA_IX: /* LDA Indexed Indirect. */ - case LDA_IY: /* LDA Indirect Indexed. */ - case LDB_IMM: /* LDB Immediate. */ - case LDB_AB: /* LDB Absolute. */ - case LDB_Z: /* LDB Zero Matrix. */ - case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */ - case LDB_ZY: /* LDB Zero Matrix, Indexed with Y. */ - case LDB_IN: /* LDB Indirect. */ - case LDB_IX: /* LDB Indexed Indirect. */ - case LDB_IY: /* LDB Indirect Indexed. */ - case LDY_IMM: /* LDY Immediate. */ - case LDY_AB: /* LDY Absolute. */ - case LDY_Z: /* LDY Zero Matrix. */ - case LDY_IN: /* LDY Indirect. */ - case LDX_IMM: /* LDX Immediate. */ - case LDX_AB: /* LDX Absolute. */ - case LDX_Z: /* LDX Zero Matrix. */ - case LDX_IN: /* LDX Indirect. */ - case JMP_AB: /* JMP Absolute. */ - case JMP_Z: /* JMP Zero Matrix. */ - case JMP_IN: /* JMP Indirect. */ - case JSR_IN: /* JSR Indirect. */ - case JSR_AB: /* Jump to SubRoutine. */ - case JSR_Z: /* JSR Zero Matrix. */ - return 0; - default: - return 1; +static /*inline*/ uint8_t isread(uint8_t opcode, uint8_t ext_prefix) { + if ((ext_prefix & 0xD) == 0xD) { + switch (ext_prefix >> 4) { + case 0x0: + switch (opcode) { + case LEA_AB : + case LEA_AX : + case LEA_AY : + case LEA_AI : + case LEA_AIX: + case LEA_AIY: + case LEA_Z : + case LEA_ZX : + case LEA_ZY : + case LEA_IN : + case LEA_IX : + case LEA_IY : + case PEA_AB : + case PEA_AX : + case PEA_AY : + case PEA_AI : + case PEA_AIX: + case PEA_AIY: + case PEA_Z : + case PEA_ZX : + case PEA_ZY : + case PEA_IN : + case PEA_IX : + case PEA_IY : + case LDS_IMM: + case LDS_AB : + case LDS_Z : + case LDS_E : + case LNG_IMM: + case LNG_E : + case LPO_IMM: + case LPO_E : + case LCC_IMM: + case LCC_E : + case LCS_IMM: + case LCS_E : + case LEQ_IMM: + case LEQ_E : + case LNE_IMM: + case LNE_E : + case LDA_E : + case LDB_E : + case LDX_E : + case LDY_E : + case JMP_E : + case JSR_E : return 0; + default : return 1; + } + } + } else { + switch (opcode) { + case LDA_IMM: /* LDA Immediate. */ + case LDA_AB: /* LDA Absolute. */ + case LDA_Z: /* LDA Zero Matrix. */ + case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */ + case LDA_ZY: /* LDA Zero Matrix, Indexed with Y. */ + case LDA_IN: /* LDA Indirect. */ + case LDA_IX: /* LDA Indexed Indirect. */ + case LDA_IY: /* LDA Indirect Indexed. */ + case LDB_IMM: /* LDB Immediate. */ + case LDB_AB: /* LDB Absolute. */ + case LDB_Z: /* LDB Zero Matrix. */ + case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */ + case LDB_ZY: /* LDB Zero Matrix, Indexed with Y. */ + case LDB_IN: /* LDB Indirect. */ + case LDB_IX: /* LDB Indexed Indirect. */ + case LDB_IY: /* LDB Indirect Indexed. */ + case LDY_IMM: /* LDY Immediate. */ + case LDY_AB: /* LDY Absolute. */ + case LDY_Z: /* LDY Zero Matrix. */ + case LDY_IN: /* LDY Indirect. */ + case LDX_IMM: /* LDX Immediate. */ + case LDX_AB: /* LDX Absolute. */ + case LDX_Z: /* LDX Zero Matrix. */ + case LDX_IN: /* LDX Indirect. */ + case JMP_AB: /* JMP Absolute. */ + case JMP_Z: /* JMP Zero Matrix. */ + case JMP_IN: /* JMP Indirect. */ + case JSR_IN: /* JSR Indirect. */ + case JSR_AB: /* Jump to SubRoutine. */ + case JSR_Z: /* JSR Zero Matrix. */ + return 0; + default: + return 1; + } } } @@ -178,7 +283,7 @@ static void *memcopy(void *restrict dst, const void *restrict src, unsigned int } -static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { +static /*inline*/ uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { #if getclk cpu->clk += inc_clk; #endif @@ -210,7 +315,7 @@ static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t addres } } -static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { +static /*inline*/ void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { if (address < mem_size) { size = (size > 7) ? 7 : size; #if 1 @@ -240,7 +345,7 @@ static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address #endif } -static inline uint64_t offset_addr(struct sux *cpu, uint64_t offset, uint8_t size, uint8_t inc_clk, uint8_t prefix) { +static /*inline*/ uint64_t offset_addr(struct sux *cpu, uint64_t offset, uint8_t size, uint8_t inc_clk, uint8_t prefix) { uint64_t of; switch (prefix >> 6) { case 1: of = cpu->sp; break; @@ -261,11 +366,11 @@ static inline uint64_t offset_addr(struct sux *cpu, uint64_t offset, uint8_t siz } } -static inline uint64_t imm_addr(struct sux *cpu) { +static /*inline*/ uint64_t imm_addr(struct sux *cpu) { return cpu->pc; } -static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { +static /*inline*/ uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { uint64_t address; uint8_t size = get_addrsize(prefix, type); if (prefix >> 6) { @@ -279,18 +384,18 @@ static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl return address; } -static inline uint64_t idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg) { +static /*inline*/ uint64_t idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg) { #if getclk cpu->clk += inc_clk; #endif return read_addr(cpu, prefix, inc_clk, type, inc_pc) + idx_reg; } -static inline uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { +static /*inline*/ uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { return read_value(cpu, 0, read_addr(cpu, prefix, inc_clk, type, inc_pc), 7, inc_clk, 0); } -static inline uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg, uint8_t pre_idx) { +static /*inline*/ uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg, uint8_t pre_idx) { #if getclk cpu->clk += inc_clk; #endif @@ -301,7 +406,7 @@ static inline uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc } } -static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { +static /*inline*/ uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { uint8_t rs = (prefix >> 4) & 3; uint8_t size = (1 << rs) - 1; uint64_t offset = read_value(cpu, 0, cpu->pc, size, inc_clk, 0); @@ -320,10 +425,10 @@ static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk } } -static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { +static /*inline*/ uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { uint64_t address = 0; uint8_t type; - if ((ext_prefix & 0xD) == 0xD) { + if ((ext_prefix & 0xF) == 0xD) { switch (ext_prefix >> 4) { case 0x0: type = ext_optype[opcode]; break; } @@ -376,7 +481,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, } -static inline uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t carry, uint8_t thread) { +static /*inline*/ uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t carry, uint8_t thread) { uint64_t sum = reg+value+carry; setflag(sum == 0, Z); setflag((sum >> 63), N); @@ -385,43 +490,43 @@ static inline uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t transfer(struct sux *cpu, uint64_t src, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t transfer(struct sux *cpu, uint64_t src, uint64_t value, uint8_t thread) { setflag(src == 0, Z); setflag(src >> 63, N); return src; } -static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { write_value(cpu, value, cpu->sp-size, size, 1, 0); cpu->sp -= size+1; } -static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, cpu->sp+1, size, 1, 0); cpu->sp += size+1; return value; } -static inline uint64_t and(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t and(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { reg &= value; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; } -static inline uint64_t or(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t or(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { reg |= value; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; } -static inline uint64_t xor(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t xor(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { reg ^= value; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; } -static inline uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum = (value < msb) ? reg << value : 0; @@ -431,7 +536,7 @@ static inline uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum = (value < msb) ? reg >> value : 0; @@ -441,7 +546,7 @@ static inline uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint8_t sign = reg >> (msb-1); @@ -452,7 +557,7 @@ static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum; @@ -468,7 +573,7 @@ static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum; @@ -484,7 +589,7 @@ static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { uint64_t sum = reg*value; setflag(sum == 0, Z); setflag(sum >> 63, N); @@ -492,7 +597,7 @@ static inline uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint64_t *rem, uint8_t thread) { +static /*inline*/ uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint64_t *rem, uint8_t thread) { uint64_t sum = reg/value; *rem = reg % value; setflag(sum == 0, Z); @@ -500,7 +605,7 @@ static inline uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint6 return sum; } -static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) { +static /*inline*/ void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) { uint64_t sum = reg-value; setflag(sum >> 63, N); setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); @@ -509,14 +614,14 @@ static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t th } /* Increment, or Decrement register. */ -static inline uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t thread) { +static /*inline*/ uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t thread) { reg += (inc) ? 1 : -1; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; } -static inline uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; if ((!bit && !value) || (bit && value == -1)) { @@ -528,13 +633,13 @@ static inline uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8 return j; } -static inline void bit_test(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ void bit_test(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { setflag((value >> 7) & 1, N); setflag((value >> 6) & 1, V); setflag((value & reg) == 0, Z); } -static inline uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t thread) { size = (size > 7) ? 7 : size; uint8_t half = ((size-1)*8) >> 1; uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); @@ -544,14 +649,14 @@ static inline uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t } -static inline uint64_t popcnt(struct sux *cpu, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t popcnt(struct sux *cpu, uint64_t value, uint8_t thread) { uint64_t count = 0; for (; value; count++, value &= value - 1); return count; } /* Increment, or Decrement memory. */ -static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) { +static /*inline*/ void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; uint64_t value; value = read_value(cpu, 0, address, size, 1, 0); @@ -568,7 +673,7 @@ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_ write_value(cpu, value, address, size, 1, 1); } -static inline void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft_cnt, uint64_t address, uint8_t prefix, uint8_t thread) { +static /*inline*/ void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft_cnt, uint64_t address, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; uint64_t value = read_value(cpu, 0, address, size, 1, 0); switch (shft_type) { @@ -581,22 +686,22 @@ static inline void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft write_value(cpu, value, address, size, 1, 1); } -static inline void not_mem(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t thread) { +static /*inline*/ void not_mem(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; write_value(cpu, ~read_value(cpu, 0, address, size, 1, 0), address, size, 1, 1); } -static inline void lbcnt_mem(struct sux *cpu, uint64_t address, uint8_t bit, uint8_t size, uint8_t thread) { +static /*inline*/ void lbcnt_mem(struct sux *cpu, uint64_t address, uint8_t bit, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, address, size, 1, 0); write_value(cpu, lbcnt(cpu, value, bit, size, thread), address, size, 1, 1); } -static inline void swap_mem(struct sux *cpu, uint64_t address, uint8_t size, uint8_t thread) { +static /*inline*/ void swap_mem(struct sux *cpu, uint64_t address, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, address, size, 1, 0); write_value(cpu, swap(cpu, value, size, thread), address, size, 1, 1); } -static inline uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint64_t src, uint8_t rep, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint64_t src, uint8_t rep, uint8_t size, uint8_t thread) { if (!rep) { uint64_t value = read_value(cpu, 0, src, size, 1, 1); write_value(cpu, value, dst, size, 1, 1); @@ -609,20 +714,20 @@ static inline uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint6 } } -static inline uint64_t load(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t load(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, reg, address, size, 1, 1); setflag(value == 0, Z); setflag(value >> 63, N); return value; } -static inline void store(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, uint8_t thread) { +static /*inline*/ void store(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; write_value(cpu, reg, address, size, 1, 1); } -static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, union reg value, union reg address, uint8_t size, uint8_t thread) { - uint8_t addr_size = get_addrsize(ext_optype[opcode], prefix); +static /*inline*/ void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t value, uint64_t address, uint8_t size, uint8_t thread) { + uint8_t addr_size = get_addrsize(prefix, ext_optype[opcode]); uint8_t tmp = 0; switch (opcode) { case LEA_AB : /* LEA Absolute. */ @@ -637,7 +742,12 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case LEA_IN : /* LEA Indirect. */ case LEA_IX : /* LEA Indexed Idirect. */ case LEA_IY : /* LEA Indirect Indexed. */ - cpu->e = address.u64; + do { + size = (!size) ? addr_size : size; + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + cpu->e = (address & mask); + //cpu->e = load(cpu, address, 0, size, thread); + } while (0); break; case PEA_AB : /* PEA Absolute. */ case PEA_AX : /* PEA Absolute, Indexed with X. */ @@ -651,41 +761,41 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case PEA_IN : /* PEA Indirect. */ case PEA_IX : /* PEA Indexed Idirect. */ case PEA_IY : /* PEA Indirect Indexed. */ - push(cpu, address.u64, 7, thread); + push(cpu, address, 7, thread); break; case ADD_IMM: /* ADD Immediate. */ case ADD_AB : /* ADD Absolute. */ case ADD_Z : /* ADD Zero Matrix. */ case ADD_E : /* ADD E Indirect. */ - cpu->a = adc(cpu, cpu->a, value.u64, 0, thread); + cpu->a = adc(cpu, cpu->a, value, 0, thread); break; case SUB_IMM: /* SUB Immediate. */ case SUB_AB : /* SUB Absolute. */ case SUB_Z : /* SUB Zero Matrix. */ case SUB_E : /* SUB E Indirect. */ - cpu->a = adc(cpu, cpu->a, ~value.u64, 1, thread); + cpu->a = adc(cpu, cpu->a, ~value, 1, thread); break; case ADE_IMM: /* ADE Immediate. */ case ADE_AB : /* ADE Absolute. */ case ADE_Z : /* ADE Zero Matrix. */ - cpu->e = adc(cpu, cpu->e, value.u64, 0, thread); + cpu->e = adc(cpu, cpu->e, value, 0, thread); break; case SBE_IMM: /* SBE Immediate. */ case SBE_AB : /* SBE Absolute. */ case SBE_Z : /* SBE Zero Matrix. */ - cpu->e = adc(cpu, cpu->e, ~value.u64, 1, thread); + cpu->e = adc(cpu, cpu->e, ~value, 1, thread); break; case ADS_IMM: /* ADS Immediate. */ case ADS_AB : /* ADS Absolute. */ case ADS_Z : /* ADS Zero Matrix. */ case ADS_E : /* ADS E Indirect. */ - cpu->sp = adc(cpu, cpu->sp, value.u64, 0, thread); + cpu->sp = adc(cpu, cpu->sp, value, 0, thread); break; case SBS_IMM: /* SBS Immediate. */ case SBS_AB : /* SBS Absolute. */ case SBS_Z : /* SBS Zero Matrix. */ case SBS_E : /* SBS E Indirect. */ - cpu->sp = adc(cpu, cpu->sp, ~value.u64, 1, thread); + cpu->sp = adc(cpu, cpu->sp, ~value, 1, thread); break; case NOT_A : /* NOT Accumulator. */ cpu->a = ~cpu->a; @@ -693,7 +803,7 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case NOT_AB: /* NOT Absolute. */ case NOT_Z : /* NOT Zero Matrix. */ case NOT_E : /* NOT E Indirect. */ - not_mem(cpu, address.u64, prefix, thread); + not_mem(cpu, address, prefix, thread); break; case LLM_AB: /* LLM Absolute. */ case LLM_Z : /* LLM Zero Matrix. */ @@ -727,14 +837,14 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case ARM_Z : case ARM_E : tmp = 4; break; } - bitshft_mem(cpu, tmp, cpu->b, address.u64, prefix, thread); + bitshft_mem(cpu, tmp, cpu->b, address, prefix, thread); break; case PHE_IMP: push(cpu, cpu->e, size, thread); break; /* PusH E register. */ - case PLE_IMP: pull(cpu, size, thread); break; /* PuLl E register. */ + case PLE_IMP: cpu->e = pull(cpu, size, thread); break; /* PuLl E register. */ case CPE_IMM: /* CPE Immediate. */ case CPE_AB : /* CPE Absolute. */ case CPE_Z : /* CPE Zero Matrix. */ - adc(cpu, cpu->e, ~value.u64, 1, thread); + adc(cpu, cpu->e, ~value, 1, thread); break; case ICE_AB : /* ICE Absolute. */ case ICE_Z : /* ICE Zero Matrix. */ @@ -744,7 +854,7 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case LDS_AB : /* LDS Absolute. */ case LDS_Z : /* LDS Zero Matrix. */ case LDS_E : /* LDS E Indirect. */ - cpu->sp = load(cpu, cpu->sp, address.u64, size, thread); + cpu->sp = load(cpu, cpu->sp, address, size, thread); break; case DEE_IMP: cpu->e = idr(cpu, cpu->e, 0, thread); break; /* DEcrement E register. */ case INE_IMP: cpu->e = idr(cpu, cpu->e, 1, thread); break; /* INcrement E register. */ @@ -753,16 +863,16 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case STS_AB: /* STS Absolute. */ case STS_Z : /* STS Zero Matrix. */ case STS_E : /* STS E Indirect. */ - store(cpu, address.u64, cpu->sp, prefix, thread); + store(cpu, address, cpu->sp, prefix, thread); break; case STE_AB: /* STE Absolute. */ case STE_Z : /* STE Zero Matrix. */ - store(cpu, address.u64, cpu->sp, prefix, thread); + store(cpu, address, cpu->sp, prefix, thread); break; case STZ_AB: /* STZ Absolute. */ case STZ_Z : /* STZ Zero Matrix. */ case STZ_E : /* STZ E Indirect. */ - store(cpu, address.u64, 0, prefix, thread); + store(cpu, address, 0, prefix, thread); break; case SCO_IMM: /* SCO Immediate. */ case SCO_AB : /* SCO Absolute. */ @@ -777,17 +887,17 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case CLZ_AB: /* CLZ Absolute. */ case CLZ_Z : /* CLZ Zero Matrix. */ case CLZ_E : /* CLZ E Indirect. */ - cpu->a = lbcnt(cpu, value.u64, 0, size, thread); + cpu->a = lbcnt(cpu, value, 0, size, thread); break; case CLO_AB: /* CLO Absolute. */ case CLO_Z : /* CLO Zero Matrix. */ case CLO_E : /* CLO E Indirect. */ - cpu->a = lbcnt(cpu, value.u64, 1, size, thread); + cpu->a = lbcnt(cpu, value, 1, size, thread); break; case BIT_AB: /* BIT Absolute. */ case BIT_Z : /* BIT Zero Matrix. */ case BIT_E : /* BIT E Indirect. */ - bit_test(cpu, cpu->a, value.u64, thread); + bit_test(cpu, cpu->a, value, thread); break; case MMV_IMP: /* Memory MoVe. */ cpu->b = mem_move(cpu, cpu->b, cpu->x, cpu->y, 0, size, thread); @@ -798,141 +908,141 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case SWP_AB: /* SWP Absolute. */ case SWP_Z : /* SWP Zero Matrix. */ case SWP_E : /* SWP E Indirect. */ - swap_mem(cpu, address.u64, size, thread); + swap_mem(cpu, address, size, thread); break; case PCN_AB: /* PCN Absolute. */ case PCN_Z : /* PCN Zero Matrix. */ case PCN_E : /* PCN E Indirect. */ - cpu->a = popcnt(cpu, value.u64, thread); + cpu->a = popcnt(cpu, value, thread); break; case REP_REL: /* REP Relative. */ if (cpu->b != 0) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case REQ_REL: /* REQ Relative. */ if (cpu->b != 0 && getflag(Z)) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case RNE_REL: /* RNE Relative. */ if (cpu->b != 0 && !getflag(Z)) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case LNG_IMM: /* LNG Immediate. */ case LNG_E : /* LNG E Indirect. */ if (getflag(N)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LPO_IMM: /* LPO Immediate. */ case LPO_E : /* LPO E Indirect. */ if (!getflag(N)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LCS_IMM: /* LCS Immediate. */ case LCS_E : /* LCS E Indirect. */ if (getflag(C)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LCC_IMM: /* LCC Immediate. */ case LCC_E : /* LCC E Indirect. */ if (!getflag(C)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LEQ_IMM: /* LEQ Immediate. */ case LEQ_E : /* LEQ E Indirect. */ if (getflag(Z)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LNE_IMM: /* LNE Immediate. */ case LNE_E : /* LNE E Indirect. */ if (!getflag(Z)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case SNG_E : /* SNG E Indirect. */ if (getflag(N)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SPO_E : /* SPO E Indirect. */ if (!getflag(N)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SCS_E : /* SCS E Indirect. */ if (getflag(C)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SCC_E : /* SCC E Indirect. */ if (!getflag(C)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SEQ_E : /* SEQ E Indirect. */ if (getflag(Z)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SNE_E : /* SNE E Indirect. */ if (!getflag(Z)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; } } -static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, union reg value, union reg address, uint8_t size, uint8_t thread) { +static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t value, uint64_t address, uint8_t size, uint8_t thread) { uint64_t *rem = 0; switch (opcode) { case CPS_IMP: /* Clear Processor Status. */ cpu->ps.u8[thread] = 0; break; case ADC_B: /* ADC B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ADC_IMM: /* ADC Immediate. */ case ADC_AB: /* ADC Absolute. */ case ADC_Z: /* ADC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, value.u64, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, value, getflag(C), thread); break; case PHP_IMP: push(cpu, cpu->ps.u8[thread], 0, thread); break; /* PusH Processor status to stack. */ case PHA_IMP: push(cpu, cpu->a , size, thread); break; /* PusH Accumulator to stack. */ case PHB_IMP: push(cpu, cpu->b , size, thread); break; /* PusH B register to stack. */ case PHY_IMP: push(cpu, cpu->y , size, thread); break; /* PusH Y register to stack. */ case PHX_IMP: push(cpu, cpu->x , size, thread); break; /* PusH X register to stack. */ - case TAY_IMP: cpu->y = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to Y. */ - case TAX_IMP: cpu->x = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to Y. */ - case TYX_IMP: cpu->x = transfer(cpu, cpu->y , value.u64, thread); break; /* Transfer Y to X. */ - case TYA_IMP: cpu->a = transfer(cpu, cpu->y , value.u64, thread); break; /* Transfer Y to Accumulator. */ - case TXA_IMP: cpu->a = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Accumulator. */ - case TXY_IMP: cpu->y = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Y. */ - case TAB_IMP: cpu->b = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to B. */ - case TSX_IMP: cpu->x = transfer(cpu, cpu->sp, value.u64, thread); break; /* Transfer Stack pointer to X. */ - case TBA_IMP: cpu->a = transfer(cpu, cpu->b , value.u64, thread); break; /* Transfer B to Accumulator. */ - case TXS_IMP: cpu->sp = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Stack pointer. */ + case TAY_IMP: cpu->y = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to Y. */ + case TAX_IMP: cpu->x = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to Y. */ + case TYX_IMP: cpu->x = transfer(cpu, cpu->y , value, thread); break; /* Transfer Y to X. */ + case TYA_IMP: cpu->a = transfer(cpu, cpu->y , value, thread); break; /* Transfer Y to Accumulator. */ + case TXA_IMP: cpu->a = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Accumulator. */ + case TXY_IMP: cpu->y = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Y. */ + case TAB_IMP: cpu->b = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to B. */ + case TSX_IMP: cpu->x = transfer(cpu, cpu->sp, value, thread); break; /* Transfer Stack pointer to X. */ + case TBA_IMP: cpu->a = transfer(cpu, cpu->b , value, thread); break; /* Transfer B to Accumulator. */ + case TXS_IMP: cpu->sp = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Stack pointer. */ case BRA_REL: /* BRA Relative. */ case JMP_AB: /* JMP Absolute. */ case JMP_Z: /* JMP Zero Matrix. */ case JMP_IN: /* JMP Indirect. */ - cpu->pc = address.u64; + cpu->pc = address; break; case SBC_B: /* SBC B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case SBC_IMM: /* SBC Immediate. */ case SBC_AB: /* SBC Absolute. */ case SBC_Z: /* SBC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, ~value.u64, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, ~value, getflag(C), thread); break; case PLP_IMP: cpu->ps.u8[thread] = pull(cpu, 0, thread); break; /* PuLl Processor status from stack. */ case PLA_IMP: cpu->a = pull(cpu, size, thread); break; /* PuLl Accumulator from stack. */ @@ -941,53 +1051,53 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case PLX_IMP: cpu->x = pull(cpu, size, thread); break; /* PuLl X register from stack. */ break; case AND_B: /* AND B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case AND_IMM: /* AND Immediate. */ case AND_AB: /* AND Absolute. */ case AND_Z: /* AND Zero Matrix. */ - cpu->a = and(cpu, cpu->a, value.u64, thread); + cpu->a = and(cpu, cpu->a, value, thread); break; case BPO_REL: /* BPO Relative. */ if (!getflag(N)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ORA_B: /* ORA B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ORA_IMM: /* ORA Immediate. */ case ORA_AB: /* ORA Absolute. */ case ORA_Z: /* ORA Zero Matrix. */ - cpu->a = or(cpu, cpu->a, value.u64, thread); + cpu->a = or(cpu, cpu->a, value, thread); break; case SEI_IMP: /* SEt Interrupt. */ setflag(1, I); break; case BNG_REL: /* BNG Relative. */ if (getflag(N)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case XOR_B: /* XOR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case XOR_IMM: /* XOR Immediate. */ case XOR_AB: /* XOR Absolute. */ case XOR_Z: /* XOR Zero Matrix. */ - cpu->a = xor(cpu, cpu->a, value.u64, thread); + cpu->a = xor(cpu, cpu->a, value, thread); break; case CLI_IMP: /* CLear Interrupt. */ setflag(0, I); break; case BCS_REL: /* BCS Relative. */ if (getflag(C)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case LSL_B: /* LSL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case LSL_IMM: /* LSL Immediate. */ case LSL_AB: /* LSL Absolute. */ case LSL_Z: /* LSL Zero Matrix. */ - cpu->a = lsl(cpu, cpu->a, value.u64, 8, thread); + cpu->a = lsl(cpu, cpu->a, value, 8, thread); break; case SEC_IMP: /* SEt Carry flag.*/ setflag(1, C); @@ -999,17 +1109,17 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case STA_IN: /* STA Indirect. */ case STA_IX: /* STA Indexed Indirect. */ case STA_IY: /* STA Indirect Indexed. */ - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); break; case STY_AB: /* STY Absolute. */ case STY_Z: /* STY Zero Matrix. */ case STY_IN: /* STY Indirect. */ - store(cpu, address.u64, cpu->y, prefix, thread); + store(cpu, address, cpu->y, prefix, thread); break; case STX_AB: /* STX Absolute. */ case STX_Z: /* STX Zero Matrix. */ case STX_IN: /* STX Indirect. */ - store(cpu, address.u64, cpu->x, prefix, thread); + store(cpu, address, cpu->x, prefix, thread); break; case STB_AB: /* STB Absolute. */ case STB_Z: /* STB Zero Matrix. */ @@ -1018,26 +1128,26 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case STB_IN: /* STB Indirect. */ case STB_IX: /* STB Indexed Indirect. */ case STB_IY: /* STB Indirect Indexed. */ - store(cpu, address.u64, cpu->b, prefix, thread); + store(cpu, address, cpu->b, prefix, thread); break; case BCC_REL: /* BCC Relative. */ if (!getflag(C)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case LSR_B: /* LSR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case LSR_IMM: /* LSR Immediate. */ case LSR_AB: /* LSR Absolute. */ case LSR_Z: /* LSR Zero Matrix. */ - cpu->a = lsr(cpu, cpu->a, value.u64, 8, thread); + cpu->a = lsr(cpu, cpu->a, value, 8, thread); break; case ASR_B: /* ASR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ASR_IMM: /* ASR Immediate. */ case ASR_AB: /* ASR Absolute. */ case ASR_Z: /* ASR Zero Matrix. */ - cpu->a = asr(cpu, cpu->a, value.u64, 8, thread); + cpu->a = asr(cpu, cpu->a, value, 8, thread); break; case CLC_IMP: /* CLear Carry flag. */ setflag(0, C); @@ -1050,7 +1160,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case LDB_IN: /* LDB Indirect. */ case LDB_IX: /* LDB Indexed Indirect. */ case LDB_IY: /* LDB Indirect Indexed. */ - cpu->b = load(cpu, cpu->b, address.u64, size, thread); + cpu->b = load(cpu, cpu->b, address, size, thread); break; case LDA_IMM: /* LDA Immediate. */ case LDA_AB: /* LDA Absolute. */ @@ -1060,59 +1170,59 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case LDA_IN: /* LDA Indirect. */ case LDA_IX: /* LDA Indexed Indirect. */ case LDA_IY: /* LDA Indirect Indexed. */ - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); break; case LDY_IMM: /* LDY Immediate. */ case LDY_AB: /* LDY Absolute. */ case LDY_Z: /* LDY Zero Matrix. */ case LDY_IN: /* LDY Indirect. */ - cpu->y = load(cpu, cpu->y, address.u64, size, thread); + cpu->y = load(cpu, cpu->y, address, size, thread); break; case LDX_IMM: /* LDX Immediate. */ case LDX_AB: /* LDX Absolute. */ case LDX_Z: /* LDX Zero Matrix. */ case LDX_IN: /* LDX Indirect. */ - cpu->x = load(cpu, cpu->x, address.u64, size, thread); + cpu->x = load(cpu, cpu->x, address, size, thread); break; case BEQ_REL: /* BEQ Relative. */ if (getflag(Z)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ROL_B: /* ROL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ROL_IMM: /* ROL Immediate. */ case ROL_AB: /* ROL Absolute. */ case ROL_Z: /* ROL Zero Matrix. */ - cpu->a = rol(cpu, cpu->a, value.u64, 8, thread); + cpu->a = rol(cpu, cpu->a, value, 8, thread); break; case BNE_REL: /* BNE Relative. */ if (!getflag(Z)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ROR_B: /* ROR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ROR_IMM: /* ROR Immediate. */ case ROR_AB: /* ROR Absolute. */ case ROR_Z: /* ROR Zero Matrix. */ - cpu->a = ror(cpu, cpu->a, value.u64, 8, thread); + cpu->a = ror(cpu, cpu->a, value, 8, thread); break; case BVS_REL: /* BVS Relative. */ if (getflag(V)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case MUL_B: /* MUL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case MUL_IMM: /* MUL Immediate. */ case MUL_AB: /* MUL Absolute. */ case MUL_Z: /* MUL Zero Matrix. */ - cpu->a = mul(cpu, cpu->a, value.u64, thread); + cpu->a = mul(cpu, cpu->a, value, thread); break; case BVC_REL: /* BVC Relative. */ if (!getflag(V)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case DIV_B: /* DIV B register. */ @@ -1120,7 +1230,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case DIV_AB: /* DIV Absolute. */ case DIV_Z: /* DIV Zero Matrix. */ rem = (opcode != DIV_B) ? &cpu->b : &cpu->x; - cpu->a = divd(cpu, cpu->a, value.u64, rem, thread); + cpu->a = divd(cpu, cpu->a, value, rem, thread); break; case CLV_IMP: /* CLear oVerflow flag. */ setflag(0, V); @@ -1131,27 +1241,27 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case CPB_IN: /* CPB Indirect. */ case CPB_IX: /* CPB Indexed Indirect. */ case CPB_IY: /* CPB Indirect Indexed. */ - adc(cpu, cpu->b, ~value.u64, 1, thread); + adc(cpu, cpu->b, ~value, 1, thread); break; case CMP_B: /* CMP B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case CMP_IMM: /* CMP Immediate. */ case CMP_AB: /* CMP Absolute. */ case CMP_Z: /* CMP Zero Matrix. */ case CMP_IN: /* CMP Indirect. */ case CMP_IX: /* CMP Indexed Indirect. */ case CMP_IY: /* CMP Indirect Indexed. */ - adc(cpu, cpu->a, ~value.u64, 1, thread); + adc(cpu, cpu->a, ~value, 1, thread); break; case CPY_IMM: /* CPY Immediate. */ case CPY_AB: /* CPY Absolute. */ case CPY_Z: /* CPY Zero Matrix. */ - adc(cpu, cpu->y, ~value.u64, 1, thread); + adc(cpu, cpu->y, ~value, 1, thread); break; case CPX_IMM: /* CPX Immediate. */ case CPX_AB: /* CPX Absolute. */ case CPX_Z: /* CPX Zero Matrix. */ - adc(cpu, cpu->x, ~value.u64, 1, thread); + adc(cpu, cpu->x, ~value, 1, thread); break; case INC_IMP: cpu->a = idr(cpu, cpu->a, 1, thread); break; case INB_IMP: cpu->b = idr(cpu, cpu->b, 1, thread); break; @@ -1165,11 +1275,11 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case JSR_AB: /* Jump to SubRoutine. */ case JSR_Z: /* JSR Zero Matrix. */ push(cpu, cpu->pc, (size) ? size : 7, thread); - cpu->pc = address.u64; + cpu->pc = address; break; case INC_AB: /* INC Absolute. */ case INC_Z: /* INC Zero Matrix. */ - idm(cpu, address.u64, prefix, 1, thread); + idm(cpu, address, prefix, 1, thread); break; case NOP_IMP: /* No OPeration. */ break; @@ -1181,7 +1291,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi break; case DEC_AB: /* DEC Absolute. */ case DEC_Z: /* DEC Zero Matrix. */ - idm(cpu, address.u64, prefix, 0, thread); + idm(cpu, address, prefix, 0, thread); break; case BRK_IMP: /* BReaK. */ case WAI_IMP: /* WAit for Interrupt. */ @@ -1196,11 +1306,11 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi push(cpu, cpu->pc, 7, thread); push(cpu, cpu->ps.u8[thread], 0, thread); setflag(1, I); - value.u64 = read_value(cpu, 0, (opcode == BRK) ? 0xFFE0 : 0xFFA0, 7, 1, 0); + value = read_value(cpu, 0, (opcode == BRK) ? 0xFFE0 : 0xFFA0, 7, 1, 0); if (opcode == WAI_IMP) { kbd_rdy &= (uint8_t)~(1 << thread); } - cpu->pc = value.u64; + cpu->pc = value; default: break; } diff --git a/test/base-ext.s b/test/base-ext.s index 8bf3d45..c6441ef 100644 --- a/test/base-ext.s +++ b/test/base-ext.s @@ -7,6 +7,8 @@ loop: inc (e) lda (e) lea ($FFC0) + pha.q + ads #8 bra loop .org $FFC0 |