From 5dd788d5a1acc7f23835882420d50e9f020728ac Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Mon, 18 May 2020 13:14:08 -0400 Subject: Did alot of stuff while I was up at the family trailer. - Moved the large enums, and large tables into separate header files. - Added enums for implementing the base extension - Fixed a bug in the assembler. - Worked more on SuBAsm. --- asmmon.c | 92 ++++++++---- asmmon.h | 99 +++++++------ enums.h | 333 +++++++++++++++++++++++++++++++++++++++++++ io.c | 1 + lexer.c | 8 +- opcode.h | 391 ++------------------------------------------------- programs/subasm-2.s | 242 ++++++++++++++++++++++++++----- programs/subeditor.s | 24 +++- sux.c | 20 ++- sux.h | 24 ++-- tables.h | 189 +++++++++++++++++++++++++ test/add-sub.s | 27 ++++ test/ind-addr.s | 24 ++-- 13 files changed, 951 insertions(+), 523 deletions(-) create mode 100644 enums.h create mode 100644 tables.h create mode 100644 test/add-sub.s diff --git a/asmmon.c b/asmmon.c index 198254c..dcffb67 100644 --- a/asmmon.c +++ b/asmmon.c @@ -9,6 +9,14 @@ uint8_t defined = 0; uint8_t isfixup = 0; +char lexeme[MAX_TOK]; +char *string[MAX_TOK]; +char *comment[MAX_TOK]; +uint16_t incl[MAX_TOK]; +struct line tokline[MAX_TOK]; +struct line tln[MAX_TOK]; +struct symbol *symbols[MAX_TOK]; +struct fixup *fixups[MAX_TOK]; static char tstr[2048]; @@ -319,8 +327,9 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln, } } -uint64_t assemble(struct line *line, uint8_t dbg) { - uint64_t bytecount = 0; +void assemble(struct line *line, bytecount *bc, uint8_t dbg) { + bc->progsize = 0; + bc->datasize = 0; uint64_t tmpaddr; uint64_t value; uint16_t flags = 0; @@ -406,14 +415,11 @@ uint64_t assemble(struct line *line, uint8_t dbg) { } opsize = 0; skip = 0; - if ((flags & 0x53) == 0x42) { + if ((flags & 0x53) == 0x42 || (flags & 0x51) == 0x41) { value = symbols[symid]->val; } else { value = op; } - if ((flags & 0x51) == 0x41) { - value = symbols[symid]->val; - } if (flags & 0x220) { switch (cm) { case 0: value += aop; break; @@ -449,15 +455,17 @@ uint64_t assemble(struct line *line, uint8_t dbg) { c = string[str][k]; break; } + bc->datasize++; addr[tmpaddr++] = c; } addr[tmpaddr] = '\0'; - if (dbg) { - printf("assemble(): "); - printf("Placed string \"%s\"", string[str]); - printf(", at address(es) $%"PRIX64"-$%"PRIX64".\n", address, tmpaddr); - } + if (dbg) { + printf("assemble(): "); + printf("Placed string \"%s\"", string[str]); + printf(", at address(es) $%"PRIX64"-$%"PRIX64".\n", address, tmpaddr); + } } else { + bc->datasize++; addr[tmpaddr++] = value & 0xFF; } break; @@ -467,14 +475,17 @@ uint64_t assemble(struct line *line, uint8_t dbg) { addr[tmpaddr+5] = value >> 0x28; addr[tmpaddr+4] = value >> 0x20; tmp+=4; + bc->datasize+=4; case DIR_DWORD: addr[tmpaddr+3] = value >> 0x18; addr[tmpaddr+2] = value >> 0x10; tmp+=2; + bc->datasize+=2; case DIR_WORD: addr[tmpaddr+1] = value >> 0x08; addr[tmpaddr ] = value & 0xFF; tmp+=2; + bc->datasize+=2; break; case DIR_INCLUDE: incl[inc_file++] = line[i].incl; @@ -502,7 +513,7 @@ uint64_t assemble(struct line *line, uint8_t dbg) { } else { am = IMPL; addr[tmpaddr++] = opcodes[ins][IMM]; - bytecount++; + bc->progsize++; if (dbg) { printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]); printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[IMM]); @@ -531,7 +542,7 @@ uint64_t assemble(struct line *line, uint8_t dbg) { puts("Prefix byte detected."); } addr[tmpaddr++] = prefix; - bytecount++; + bc->progsize++; if (dbg) { uint8_t addrsize = (prefix & 0x0C) >> 2; uint8_t regsize = (prefix & 0x30) >> 4; @@ -544,7 +555,7 @@ uint64_t assemble(struct line *line, uint8_t dbg) { } if (opcodes[ins][am] != 0xFF) { addr[tmpaddr++] = opcodes[ins][am]; - bytecount++; + bc->progsize++; if (dbg) { printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]); printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[am]); @@ -591,23 +602,27 @@ uint64_t assemble(struct line *line, uint8_t dbg) { break; } tmpaddr += tmp; - bytecount += tmp; + bc->progsize += tmp; tmp = 0; } } if (dbg) { printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address); printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr); + printf("assemble(): The program size is now at"); - printf(", %"PRIu64" bytes in decimal", bytecount); - printf(", and $%"PRIX64" bytes in hex.\n", bytecount); + printf(", %"PRIu64" bytes in decimal", bc->progsize); + printf(", and $%"PRIX64" bytes in hex.\n", bc->progsize); + + printf("assemble(): The data size is now at"); + printf(", %"PRIu64" bytes in decimal", bc->datasize); + printf(", and $%"PRIX64" bytes in hex.\n", bc->datasize); } } - return bytecount; } int asmmon(const char *fn) { - FILE *fp; + FILE *fp = NULL; FILE *fp2 = NULL; char *path = malloc(0x400); if (strcasecmp(fn, "stdin")) { @@ -631,7 +646,9 @@ int asmmon(const char *fn) { uint8_t done = 0; uint8_t use_lexer = 1; uint64_t address = 0; - uint64_t bytecount = 0; + bytecount bc; + uint64_t progsize = 0; + uint64_t datasize = 0; uint8_t dbg = 0; uint8_t isinclude = 0; uint16_t tmp_lineidx = 0; @@ -680,7 +697,9 @@ int asmmon(const char *fn) { switch (cmds) { case 0x01: free(path); - fclose(fp); + if (fp != NULL) { + fclose(fp); + } if (fp2 != NULL) { fclose(fp2); } @@ -764,17 +783,29 @@ int asmmon(const char *fn) { break; case 0x08: if (!isinclude) { - puts("Assembling program."); - bytecount = assemble(tokline, dbg); + printf("Assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program."); + assemble(tokline, &bc, dbg); + progsize = bc.progsize; + datasize = bc.datasize; + printf("Finished assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program."); + printf("%"PRIu64"/$%"PRIX64" bytes of program code.\n", progsize, progsize); + printf("%"PRIu64"/$%"PRIX64" bytes of data.\n", datasize, datasize); + putchar('\n'); } else { - bytecount += assemble(tln, dbg); + printf("Assembling %s\n", string[incl[inc_count]]); + assemble(tln, &bc, dbg); + progsize += bc.progsize; + datasize += bc.datasize; + printf("Finished assembling %s\n", string[incl[inc_count]]); + printf("%"PRIu64"/$%"PRIX64" bytes of program code.\n", bc.progsize, bc.progsize); + printf("%"PRIu64"/$%"PRIX64" bytes of data.\n", bc.datasize, bc.datasize); + putchar('\n'); } isinclude = (inc_file != 0); if (inc_file) { size = strlen(path)+strlen(string[incl[inc_count]])+1; char *fn2 = malloc(size+1); sprintf(fn2, "%s/%s", path, string[incl[inc_count]]); - printf("%s\n", fn2); if (!tmp_lineidx) { tmp_lineidx = lineidx; } @@ -795,8 +826,9 @@ int asmmon(const char *fn) { lineidx = tmp_lineidx; } if (!isinclude) { - puts("Finished assembling program."); - printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", bytecount, bytecount); + puts("Finished assembling."); + printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", progsize, progsize); + printf("Total Assembled Data Size: %"PRIu64"/$%"PRIX64" bytes.\n", datasize, datasize); } break; case 0x10: @@ -850,7 +882,11 @@ int asmmon(const char *fn) { } } free(path); - fclose(fp); + + if (fp != NULL) { + fclose(fp); + } + if (fp2 != NULL) { fclose(fp2); } diff --git a/asmmon.h b/asmmon.h index 58b4918..032830c 100644 --- a/asmmon.h +++ b/asmmon.h @@ -2,8 +2,55 @@ #include #include -char lexeme[0x1000]; -uint8_t lex_type; +#define MAX_TOK 0x1000 + +struct line { + uint8_t stab; + uint8_t sspace; + uint8_t dir; + uint8_t mne; + uint8_t rs; + uint8_t opbase; + uint8_t aopbase; + uint8_t am; + uint8_t cm; + uint8_t etab; + uint8_t espace; + uint8_t islabel; + uint8_t issym; + uint16_t sym; + uint16_t com; + uint16_t str; + uint16_t incl; + uint16_t linenum; + uint64_t op; + uint64_t aop; + uint64_t addr; +}; + +struct fixup { + struct symbol *s; + uint16_t ln; + uint64_t adr; +}; + +struct symbol { + uint64_t val; + uint8_t def; + char name[128]; + uint16_t id; +}; + +extern char lexeme[]; +extern char *string[]; +extern char *comment[]; +extern uint16_t incl[]; +extern struct line tokline[]; +extern struct line tln[]; +extern struct symbol *symbols[]; +extern struct fixup *fixups[]; + +extern uint8_t lex_type; enum { DIR_ORG, @@ -383,57 +430,17 @@ static const uint8_t amp[8] = { [7] = 0x0F }; -struct line { - uint8_t stab; - uint8_t sspace; - uint8_t dir; - uint8_t mne; - uint8_t rs; - uint8_t opbase; - uint8_t aopbase; - uint8_t am; - uint8_t cm; - uint8_t etab; - uint8_t espace; - uint8_t islabel; - uint8_t issym; - uint16_t sym; - uint16_t com; - uint16_t str; - uint16_t incl; - uint16_t linenum; - uint64_t op; - uint64_t aop; - uint64_t addr; -}; extern uint16_t linenum; extern uint16_t lineidx; extern uint16_t stridx; extern uint16_t comidx; -char *string[0x1000]; -char *comment[0x1000]; -uint16_t incl[0x1000]; - -struct line tokline[0x1000]; -struct line tln[0x1000]; - -struct fixup { - struct symbol *s; - uint16_t ln; - uint64_t adr; -}; - -struct symbol { - uint64_t val; - uint8_t def; - char name[128]; - uint16_t id; -}; +typedef struct { + uint64_t progsize; + uint64_t datasize; +} bytecount; -struct symbol *symbols[0x1000]; -struct fixup *fixups[0x1000]; extern uint8_t defined; extern uint8_t isfixup; diff --git a/enums.h b/enums.h new file mode 100644 index 0000000..f5d30a8 --- /dev/null +++ b/enums.h @@ -0,0 +1,333 @@ + +enum base_isa { + CPS = 0x00, /* Clear Processor Status. */ + ADC = 0x01, /* ADd with Carry. */ + AAB = 0x02, /* Add Accumulator with carry by B register. */ + ADC_AB = 0x04, /* ADC Absolute. */ + LDA_IN = 0x05, /* LDA Indirect. */ + ADC_Z = 0x06, /* ADC Zero Matrix. */ + PHP = 0x08, /* PusH Processor status to stack. */ + CPB = 0x09, /* ComPare B register. */ + PHB = 0x0A, /* PusH B register to stack. */ + DEC_AB = 0x0C, /* DEC Absolute. */ + DEC_Z = 0x0D, /* DEC Zero Matrix. */ + JMP_Z = 0x0E, /* JuMP to memory location. */ + JMP = 0x10, /* JMP Absolute. */ + SBC = 0x11, /* SuBtract with Carry. */ + SAB = 0x12, /* Subtract Accumulator with carry by B register. */ + SBC_AB = 0x14, /* SBC Absolute. */ + STA_IN = 0x15, /* STA Indirect. */ + SBC_Z = 0x16, /* SBC Zero Matrix. */ + ENT = 0x18, /* ENd Threads. */ + CPY = 0x19, /* ComPare Y register. */ + PLB = 0x1A, /* PuLl B register to stack. */ + INC_AB = 0x1C, /* INC Absolute. */ + INC_Z = 0x1D, /* INC Zero Matrix. */ + JSR = 0x1E, /* Jump to SubRoutine. */ + JSL = 0x20, /* Jump to Subroutine Long. */ + AND = 0x21, /* bitwise AND with accumulator. */ + ABA = 0x22, /* bitwise And with Accumulator, and B register. */ + AND_AB = 0x24, /* AND Absolute. */ + CMP_IN = 0x25, /* CMP Indirect. */ + AND_Z = 0x26, /* AND Zero Matrix. */ + PLP = 0x28, /* PuLl Processor status from stack. */ + CPX = 0x29, /* ComPare X register. */ + PHY = 0x2A, /* PusH Y register to stack. */ + CPB_AB = 0x2C, /* CPB Absolute. */ + CPB_Z = 0x2D, /* CPB Zero Matrix. */ + BPO_Z = 0x2E, /* Branch if POsitive. */ + BPO = 0x30, /* BPO Absolute. */ + ORA = 0x31, /* bitwise OR with Accumulator. */ + OAB = 0x32, /* bitwise Or with Accumulator, and B register. */ + ORA_AB = 0x34, /* ORA Absolute. */ + LDB_IN = 0x35, /* LDB Indirect. */ + ORA_Z = 0x36, /* ORA Zero Matrix. */ + STT = 0x38, /* STart Threads. */ + LDA_ZY = 0x39, /* LDA Zero Matrix, indexed with Y. */ + PLY = 0x3A, /* PuLl Y register from stack. */ + CPX_AB = 0x3C, /* CPX Absolute. */ + CPY_Z = 0x3D, /* CPY Zero Matrix. */ + BNG_Z = 0x3E, /* Branch if NeGative. */ + BNG = 0x40, /* BNG Absolute. */ + XOR = 0x41, /* bitwise XOR with accumulator. */ + XAB = 0x42, /* bitwise Xor with Accumulator, and B register. */ + XOR_AB = 0x44, /* XOR Absolute. */ + STB_IN = 0x45, /* STB Indirect. */ + XOR_Z = 0x46, /* XOR Zero Matrix. */ + PHA = 0x48, /* PusH Accumulator to stack. */ + STA_ZY = 0x49, /* STA Zero Matrix, indexed with Y. */ + PHX = 0x4A, /* PusH X register to stack. */ + CPY_AB = 0x4C, /* CPY Absolute. */ + CPX_Z = 0x4D, /* CPX Zero Matrix. */ + BCS_Z = 0x4E, /* Branch if Carry Set. */ + BCS = 0x50, /* BCS Absolute. */ + LSL = 0x51, /* Logical Shift Left. */ + LLB = 0x52, /* Logical shift Left accumulator by B. */ + LSL_AB = 0x54, /* LSL Absolute. */ + CPB_IN = 0x55, /* CPB Indirect. */ + LSL_Z = 0x56, /* LSL Zero Matrix. */ + CLC = 0x58, /* CLear Carry flag. */ + LDB_ZY = 0x59, /* LDB Zero Matrix, indexed with Y. */ + PLX = 0x5A, /* PuLl X register from stack. */ + LDA_IY = 0x5C, /* LDA Indirect Indexed. */ + LDA_IX = 0x5D, /* LDA Indexed Indirect. */ + BCC_Z = 0x5E, /* Branch if Carry Clear. */ + BCC = 0x60, /* BCC Absolute. */ + LSR = 0x61, /* Logical Shift Right. */ + LRB = 0x62, /* Logical shift Right accumulator by B. */ + LSR_AB = 0x64, /* LSR Absolute. */ + LDY_IN = 0x65, /* LDY Indirect. */ + LSR_Z = 0x66, /* LSR Zero Matrix. */ + PLA = 0x68, /* PuLl Accumulator from stack. */ + STB_ZY = 0x69, /* STB Zero Matrix, indexed with Y. */ + TAB = 0x6A, /* Transfer Accumulator to B. */ + STA_IY = 0x6C, /* STA Indirect Indexed. */ + STA_IX = 0x6D, /* STA Indexed Indirect. */ + BEQ_Z = 0x6E, /* Branch if EQual. */ + BEQ = 0x70, /* BEQ Absolute. */ + ROL = 0x71, /* ROtate Left. */ + RLB = 0x72, /* Rotate Left accumulator by B. */ + ROL_AB = 0x74, /* ROL Absolute. */ + STY_IN = 0x75, /* STY Indirect. */ + ROL_Z = 0x76, /* ROL Zero Matrix. */ + SEC = 0x78, /* SEt Carry flag. */ + LDA_ZX = 0x79, /* LDA Zero Matrix, indexed with X. */ + TBA = 0x7A, /* Transfer B to Accumulator. */ + CMP_IY = 0x7C, /* CMP Indirect Indexed. */ + CMP_IX = 0x7D, /* CMP Indexed Indirect. */ + BNE_Z = 0x7E, /* Branch if Not Equal. */ + BNE = 0x80, /* BNE Absolute. */ + ROR = 0x81, /* ROtate Right. */ + RRB = 0x82, /* Rotate Right accumulator by B. */ + ROR_AB = 0x84, /* ROR Absolute. */ + CPY_IN = 0x85, /* CPY Indirect. */ + ROR_Z = 0x86, /* ROR Zero Matrix. */ + DEY = 0x88, /* DEcrement Y register. */ + STA_ZX = 0x89, /* STA Zero Matrix, indexed with X. */ + TAY = 0x8A, /* Transfer Accumulator to Y. */ + LDB_IY = 0x8C, /* LDB Indirect Indexed. */ + LDB_IX = 0x8D, /* LDB Indexed Indirect. */ + BVS_Z = 0x8E, /* Branch if oVerflow Set. */ + BVS = 0x90, /* BVS Absolute. */ + MUL = 0x91, /* MULtiply accumulator. */ + MAB = 0x92, /* Multiply Accumulator by B. */ + MUL_AB = 0x94, /* MUL Absolute. */ + LDX_IN = 0x95, /* LDX Indirect. */ + MUL_Z = 0x96, /* MUL Zero Matrix. */ + CLI = 0x98, /* CLear Interupt flag. */ + LDB_ZX = 0x99, /* LDB Zero Matrix, indexed with X. */ + TYA = 0x9A, /* Transfer Y to Accumulator. */ + STB_IY = 0x9C, /* STB Indirect Indexed. */ + STB_IX = 0x9D, /* STB Indexed Indirect. */ + BVC_Z = 0x9E, /* Branch if oVerflow Clear. */ + BVC = 0xA0, /* BVC Absolute. */ + DIV = 0xA1, /* DIVide with accumulator. */ + DAB = 0xA2, /* Divide Accumulator by B. */ + DIV_AB = 0xA4, /* DIV Absolute. */ + STX_IN = 0xA5, /* STX Indirect. */ + DIV_Z = 0xA6, /* DIV Zero Matrix. */ + INY = 0xA8, /* INcrement Y register. */ + STB_ZX = 0xA9, /* STB Zero Matrix, indexed with X. */ + TAX = 0xAA, /* Transfer Accumulator to X. */ + CPB_IY = 0xAC, /* CPB Indirect Indexed. */ + CPB_IX = 0xAD, /* CPB Indexed Indirect. */ + RTS = 0xAE, /* ReTurn from Subroutine. */ + RTL = 0xB0, /* ReTurn from subroutine Long. */ + CMP = 0xB1, /* CoMPare accumulator. */ + CAB = 0xB2, /* Compare Accumulator, and B. */ + CMP_AB = 0xB4, /* CMP Absolute. */ + CPX_IN = 0xB5, /* CPX Indirect. */ + CMP_Z = 0xB6, /* CMP Zero Matrix. */ + SEI = 0xB8, /* SEt Interupt flag. */ + LDX = 0xB9, /* LoaD X register. */ + TXA = 0xBA, /* Transfer X to Accumulator. */ + LDX_AB = 0xBC, /* LDX Absolute. */ + LDX_Z = 0xBD, /* LDX Zero Matrix. */ + JSR_IN = 0xBE, /* JSR Indirect. */ + RTI = 0xC0, /* ReTurn from Interrupt. */ + LDA = 0xC1, /* LoaD Accumulator. */ + LDA_AB = 0xC4, /* LDA Absolute. */ + DEX = 0xC5, /* DEcrement X register. */ + LDA_Z = 0xC6, /* LDA Zero Matrix. */ + CLV = 0xC8, /* CLear oVerflow flag. */ + LDX_ZY = 0xC9, /* LDX Zero Matrix, indexed with Y. */ + TYX = 0xCA, /* Transfer Y to X. */ + STA = 0xCC, /* STA Absolute. */ + STA_Z = 0xCD, /* STore Accumulator. */ + JMP_IN = 0xCE, /* JMP Indirect. */ + TSX = 0xD0, /* Transfer Stack pointer to X. */ + LDB = 0xD1, /* LoaD B register. */ + LDB_AB = 0xD4, /* LDB Absolute. */ + INX = 0xD5, /* INcrement X register. */ + LDB_Z = 0xD6, /* LDB Zero Matrix. */ + WAI = 0xD8, /* WAit for Interrupt. */ + STX_ZY = 0xD9, /* STX Zero Matrix, indexed with Y. */ + TXY = 0xDA, /* Transfer X to Y. */ + STB = 0xDC, /* STB Absolute. */ + STB_Z = 0xDD, /* STore B register. */ + TXS = 0xE0, /* Transfer X to Stack pointer. */ + LDY = 0xE1, /* LoaD Y register. */ + LDY_AB = 0xE4, /* LDY Absolute. */ + DEC = 0xE5, /* DECrement accumulator. */ + LDY_Z = 0xE6, /* LDY Zero Matrix. */ + BRK = 0xE8, /* BReaK. */ + LDY_ZX = 0xE9, /* LDY Zero Matrix, indexed with X. */ + NOP = 0xEA, /* No OPeration. */ + STY = 0xEC, /* STY Absolute. */ + STY_Z = 0xED, /* STore Y register. */ + DEB = 0xEE, /* Decrement B register. */ + ASR = 0xF1, /* Arithmetic Shift Right. */ + ARB = 0xF2, /* Arithmetic shift Right accumulator by B. */ + ASR_AB = 0xF4, /* ASR Absolute. */ + INC = 0xF5, /* INCrement accumulator. */ + ASR_Z = 0xF6, /* ASR Zero Matrix. */ + STY_ZX = 0xF9, /* STY Zero Matrix, indexed with X. */ + STX = 0xFC, /* STX Absolute. */ + STX_Z = 0xFD, /* STore X register. */ + INB = 0xFE /* Increment B register. */ +}; + +enum base_ext { + ADC_E = 0x01, /* ADC E Indirect. */ + LEA_ZX = 0x02, /* LEA Zero Matrix, indexed with X. */ + LEA_SX = 0x03, /* LEA Stack Pointer, offset with X. */ + ADD = 0x04, /* ADD without carry. */ + LLM = 0x05, /* Logical shift Left, on Memory. */ + PHE = 0x08, /* PusH Effective address register to stack. */ + CPB_E = 0x09, /* CPB E Indirect. */ + DEC_E = 0x0C, /* DEC E Indirect. */ + JMP_E = 0x10, /* JMP E Indirect. */ + SBC_E = 0x11, /* SBC E Indirect. */ + LEA_ZY = 0x12, /* LEA Zero Matrix, indexed with Y. */ + LEA_SY = 0x13, /* LEA Stack Pointer, offset with Y. */ + ADD_E = 0x14, /* ADD E Indirect. */ + LLM_Z = 0x15, /* LLM Zero Matrix. */ + CPY_E = 0x19, /* CPY E Indirect. */ + INC_E = 0x1C, /* INC E Indirect. */ + JSR_E = 0x20, /* JSR E Indirect. */ + AND_E = 0x21, /* AND E Indirect. */ + PEA_ZX = 0x22, /* PEA Zero Matrix, indexed with X. */ + PEA_SX = 0x23, /* PEA Stack Pointer, offset with X. */ + SUB = 0x24, /* SUBtract without carry. */ + LLM_E = 0x25, /* LLM E Indirect. */ + PLE = 0x28, /* PuLl Effective address register from stack. */ + CPX_E = 0x29, /* CPX E Indirect. */ + DEE = 0x2C, /* DEcrement Effective address register. */ + BPO_E = 0x30, /* BPO E Indirect. */ + ORA_E = 0x31, /* ORA E Indirect. */ + PEA_ZY = 0x32, /* PEA Zero Matrix, indexed with Y. */ + PEA_SY = 0x33, /* PEA Stack Pointer, offset with Y. */ + SUB_E = 0x34, /* SUB E Indirect. */ + LRM = 0x35, /* Logical shift Right, on Memory. */ + CPE = 0x39, /* ComPare Effective address register. */ + INE = 0x3C, /* INcrement Effective address register. */ + BNG_E = 0x40, /* BNG E Indirect. */ + XOR_E = 0x41, /* XOR E Indirect. */ + LEA_AX = 0x42, /* LEA Absolute, indexed with X. */ + LEA_SI = 0x43, /* LEA Stack Pointer, Immediate offset. */ + ADE = 0x44, /* ADd Effective address register. */ + LRM_Z = 0x45, /* LRM Zero Matrix. */ + CPE_AB = 0x49, /* CPE Absolute. */ + DES = 0x4C, /* DEcrement Stack pointer. */ + BCS_E = 0x50, /* BCS E Indirect. */ + LSL_E = 0x51, /* LSL E Indirect. */ + LEA_AY = 0x52, /* LEA Absolute, indexed with Y. */ + LEA_RE = 0x53, /* LEA Relative. */ + ADE_A = 0x54, /* ADE with Accumulator. */ + LRM_E = 0x55, /* LRM E Indirect. */ + CPE_Z = 0x59, /* CPE Zero Matrix. */ + INS = 0x5C, /* INcrement Stack pointer. */ + BCC_E = 0x60, /* BCC E Indirect. */ + LSR_E = 0x61, /* LSR E Indirect. */ + PEA_AX = 0x62, /* PEA Absolute, indexed with X. */ + PEA_SI = 0x63, /* PEA Stack Pointer, Immediate offset. */ + SBE = 0x64, /* SuBtract Effective address register. */ + RLM = 0x65, /* Rotate Left, on Memory. */ + ICE = 0x69, /* Interlocked Compare, and Exchange. */ + BEQ_E = 0x70, /* BEQ E Indirect. */ + ROL_E = 0x71, /* ROL E Indirect. */ + PEA_AY = 0x72, /* PEA Absolute, indexed with Y. */ + PEA_RE = 0x73, /* PEA Relative. */ + RLM_Z = 0x75, /* RLM Zero Matrix. */ + ICE_Z = 0x79, /* ICE Zero Matrix. */ + STE = 0x7C, /* STore Effective address register. */ + BNE_E = 0x80, /* BNE E Indirect. */ + ROR_E = 0x81, /* ROR E Indirect. */ + LEA_IX = 0x82, /* LEA Indexed Indirect. */ + LEA_IN = 0x83, /* LEA Indirect. */ + ADS = 0x84, /* ADd Stack pointer. */ + RLM_E = 0x85, /* RLM E Indirect. */ + ICE_E = 0x89, /* ICE E Indirect. */ + STE_Z = 0x8C, /* STE Zero Matrix. */ + BVS_E = 0x90, /* BVS E Indirect. */ + MUL_E = 0x91, /* MUL E Indirect. */ + LEA_IY = 0x92, /* LEA Indirect Indexed. */ + LEA_AI = 0x93, /* LEA Absolute Indirect. */ + ADS_A = 0x94, /* ADS with Accumulator. */ + RRM = 0x95, /* Rotate Right, on Memory. */ + STZ = 0x9C, /* STore Zero. */ + BVC_E = 0xA0, /* BVC E Indirect. */ + DIV_E = 0xA1, /* DIV E Indirect. */ + PEA_IX = 0xA2, /* PEA Indexed Indirect. */ + PEA_IN = 0xA3, /* PEA Indirect. */ + SBS = 0xA4, /* SuBtract Stack pointer. */ + RRM_ZM = 0xA5, /* RRM Zero Matrix. */ + STZ_ZM = 0xAC, /* STZ Zero Matrix. */ + CMP_E = 0xB1, /* CMP E Indirect. */ + PEA_IY = 0xB2, /* PEA Indirect Indexed. */ + PEA_AI = 0xB3, /* PEA Absolute Indirect. */ + SBS_A = 0xB4, /* SBS with Accumulator. */ + RRM_E = 0xB5, /* RRM E Indirect. */ + LDX_E = 0xB9, /* LDX E Indirect. */ + STZ_E = 0xBC, /* STZ E Indirect. */ + LDA_E = 0xC1, /* LDA E Indirect. */ + LEA_AIX = 0xC2, /* LEA Absolute Indexed Indirect. */ + LEA_Z = 0xC3, /* LEA Zero Matrix. */ + NOT = 0xC4, /* bitwise NOT with accumulator. */ + ARM = 0xC5, /* Arithmetic shift Right, on Memory. */ + LDE = 0xC9, /* LoaD Effective address register. */ + STA_E = 0xCC, /* STA E Indirect. */ + LDB_E = 0xD1, /* LDB E Indirect. */ + LEA_AIY = 0xD2, /* LEA Absolute Indirect Indexed. */ + LEA = 0xD3, /* Load Effective Address. */ + NOT_AB = 0xD4, /* NOT Absolute. */ + ARM_Z = 0xD5, /* ARM Zero Matrix. */ + LDE_AB = 0xD9, /* LDE Absolute. */ + STB_E = 0xDC, /* STB E Indirect. */ + LDY_E = 0xE1, /* LDY E Indirect. */ + PEA_AIX = 0xE2, /* PEA Absolute Indexed Indirect. */ + PEA_Z = 0xE3, /* PEA Zero Matrix. */ + NOT_Z = 0xE4, /* NOT Zero Matrix. */ + ARM_E = 0xE5, /* ARM E Indirect. */ + LDE_Z = 0xE9, /* LDE Zero Matrix. */ + STY_E = 0xEC, /* STY E Indirect. */ + ASR_E = 0xF1, /* ASR E Indirect. */ + PEA_AIY = 0xF2, /* PEA Absolute Indirect Indexed. */ + PEA = 0xF3, /* Push Effective Address. */ + NOT_E = 0xF4, /* NOT E Indirect. */ + STX_E = 0xFC, /* STX E Indirect. */ +}; + +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. */ + IMPL, /* Implied. */ + /* Part of Base Extension. */ + ABSX, /* Absolute, Indexed with X. */ + ABSY, /* Absolute, Indexed with Y. */ + SPI, /* Stack Pointer, Immediate Offset. */ + SPX, /* Stack Pointer, Offset with X. */ + SPY, /* Stack Pointer, Offset with Y. */ + REL, /* Relative to Program Counter. */ + INA, /* Absolute Indirect. */ + INAX, /* Absolute Indexed Indirect. */ + INAY, /* Absolute Indirect Indexed. */ + EIND, /* Effective Address Register, Indirect. */ +}; diff --git a/io.c b/io.c index fcef5d9..9027da9 100644 --- a/io.c +++ b/io.c @@ -21,6 +21,7 @@ void io(uint64_t address, uint8_t *esc) { kbd_rdy = 0; break; case TX_ADDR: + getyx(scr, y, x); #if debug if (!subdbg) { scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0; diff --git a/lexer.c b/lexer.c index 6ed6cf4..4c398a4 100644 --- a/lexer.c +++ b/lexer.c @@ -1,5 +1,8 @@ #include "asmmon.h" +uint8_t lex_type; +uint16_t sym_count = 0; + void init_symbol() { uint16_t i = 0; for (; i < 0x1000; i++) { @@ -8,7 +11,6 @@ void init_symbol() { } } -uint16_t sym_count = 0; uint16_t mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, uint16_t id, uint8_t dbg) { uint16_t i = 0; uint8_t flag = 0; @@ -104,6 +106,7 @@ uint8_t set_symval(const char *name, uint16_t id, uint64_t val, uint8_t useid, u return 0; } } + return 0; } char *get_symname(uint16_t id, uint8_t dbg) { @@ -255,7 +258,7 @@ uint64_t update_addr(struct line *ln, uint64_t address, uint8_t fixup, uint16_t } return address; } - if (((flags & 0x53) == 0x42)) { + if ((flags & 0x53) == 0x42 || (flags & 0x51) == 0x41) { if (fixup && symid == 0xFFFF && (opcodes[mne][IMPL] == 0xFF)) { value = address; } else if (opcodes[mne][IMPL] != 0xFF && symid == 0xFFFF) { @@ -443,7 +446,6 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) { } else { ln = linenum; } - for (; isspace(str[i]); i++); line = find_line(l, ln, dbg); if (line != lineidx) { address = l[line].addr; diff --git a/opcode.h b/opcode.h index cd7a59b..1fb06ff 100644 --- a/opcode.h +++ b/opcode.h @@ -1,207 +1,24 @@ + #include #include #include #include #include +#include "tables.h" + #define getclk 0 #define keypoll 0 -#define CPS 0x00 /* Clear Processor Status. */ -#define ADC 0x01 /* ADd with Carry. */ -#define AAB 0x02 /* Add Accumulator with carry by B register. */ -#define ADC_AB 0x04 /* ADC Absolute. */ -#define LDA_IN 0x05 /* LDA Indirect. */ -#define ADC_Z 0x06 /* ADC Zero Matrix. */ -#define PHP 0x08 /* PusH Processor status to stack. */ -#define CPB 0x09 /* ComPare B register. */ -#define PHB 0x0A /* PusH B register to stack. */ -#define DEC_AB 0x0C /* DEC Absolute. */ -#define DEC_Z 0x0D /* DEC Zero Matrix. */ -#define JMP_Z 0x0E /* JuMP to memory location. */ -#define JMP 0x10 /* JMP Absolute. */ -#define SBC 0x11 /* SuBtract with Carry. */ -#define SAB 0x12 /* Subtract Accumulator with carry by B register. */ -#define SBC_AB 0x14 /* SBC Absolute. */ -#define STA_IN 0x15 /* STA Indirect. */ -#define SBC_Z 0x16 /* SBC Zero Matrix. */ -#define ENT 0x18 /* ENd Threads. */ -#define CPY 0x19 /* ComPare Y register. */ -#define PLB 0x1A /* PuLl B register to stack. */ -#define INC_AB 0x1C /* INC Absolute. */ -#define INC_Z 0x1D /* INC Zero Matrix. */ -#define JSR 0x1E /* Jump to SubRoutine. */ -#define JSL 0x20 /* Jump to Subroutine Long. */ -#define AND 0x21 /* bitwise AND with accumulator. */ -#define ABA 0x22 /* bitwise And with Accumulator, and B register. */ -#define AND_AB 0x24 /* AND Absolute. */ -#define CMP_IN 0x25 /* CMP Indirect. */ -#define AND_Z 0x26 /* AND Zero Matrix. */ -#define PLP 0x28 /* PuLl Processor status from stack. */ -#define CPX 0x29 /* ComPare X register. */ -#define PHY 0x2A /* PusH Y register to stack. */ -#define CPB_AB 0x2C /* CPB Absolute. */ -#define CPB_Z 0x2D /* CPB Zero Matrix. */ -#define BPO_Z 0x2E /* Branch if POsitive. */ -#define BPO 0x30 /* BPO Absolute. */ -#define ORA 0x31 /* bitwise OR with Accumulator. */ -#define OAB 0x32 /* bitwise Or with Accumulator, and B register. */ -#define ORA_AB 0x34 /* ORA Absolute. */ -#define LDB_IN 0x35 /* LDB Indirect. */ -#define ORA_Z 0x36 /* ORA Zero Matrix. */ -#define STT 0x38 /* STart Threads. */ -#define LDA_ZY 0x39 /* LDA Zero Matrix, indexed with Y. */ -#define PLY 0x3A /* PuLl Y register from stack. */ -#define CPX_AB 0x3C /* CPX Absolute. */ -#define CPY_Z 0x3D /* CPY Zero Matrix. */ -#define BNG_Z 0x3E /* Branch if NeGative. */ -#define BNG 0x40 /* BNG Absolute. */ -#define XOR 0x41 /* bitwise XOR with accumulator. */ -#define XAB 0x42 /* bitwise Xor with Accumulator, and B register. */ -#define XOR_AB 0x44 /* XOR Absolute. */ -#define STB_IN 0x45 /* STB Indirect. */ -#define XOR_Z 0x46 /* XOR Zero Matrix. */ -#define PHA 0x48 /* PusH Accumulator to stack. */ -#define STA_ZY 0x49 /* STA Zero Matrix, indexed with Y. */ -#define PHX 0x4A /* PusH X register to stack. */ -#define CPY_AB 0x4C /* CPY Absolute. */ -#define CPX_Z 0x4D /* CPX Zero Matrix. */ -#define BCS_Z 0x4E /* Branch if Carry Set. */ -#define BCS 0x50 /* BCS Absolute. */ -#define LSL 0x51 /* Logical Shift Left. */ -#define LLB 0x52 /* Logical shift Left accumulator by B. */ -#define LSL_AB 0x54 /* LSL Absolute. */ -#define CPB_IN 0x55 /* CPB Indirect. */ -#define LSL_Z 0x56 /* LSL Zero Matrix. */ -#define CLC 0x58 /* CLear Carry flag. */ -#define LDB_ZY 0x59 /* LDB Zero Matrix, indexed with Y. */ -#define PLX 0x5A /* PuLl X register from stack. */ -#define LDA_IY 0x5C /* LDA Indirect Indexed. */ -#define LDA_IX 0x5D /* LDA Indexed Indirect. */ -#define BCC_Z 0x5E /* Branch if Carry Clear. */ -#define BCC 0x60 /* BCC Absolute. */ -#define LSR 0x61 /* Logical Shift Right. */ -#define LRB 0x62 /* Logical shift Right accumulator by B. */ -#define LSR_AB 0x64 /* LSR Absolute. */ -#define LDY_IN 0x65 /* LDY Indirect. */ -#define LSR_Z 0x66 /* LSR Zero Matrix. */ -#define PLA 0x68 /* PuLl Accumulator from stack. */ -#define STB_ZY 0x69 /* STB Zero Matrix, indexed with Y. */ -#define TAB 0x6A /* Transfer Accumulator to B. */ -#define STA_IY 0x6C /* STA Indirect Indexed. */ -#define STA_IX 0x6D /* STA Indexed Indirect. */ -#define BEQ_Z 0x6E /* Branch if EQual. */ -#define BEQ 0x70 /* BEQ Absolute. */ -#define ROL 0x71 /* ROtate Left. */ -#define RLB 0x72 /* Rotate Left accumulator by B. */ -#define ROL_AB 0x74 /* ROL Absolute. */ -#define STY_IN 0x75 /* STY Indirect. */ -#define ROL_Z 0x76 /* ROL Zero Matrix. */ -#define SEC 0x78 /* SEt Carry flag. */ -#define LDA_ZX 0x79 /* LDA Zero Matrix, indexed with X. */ -#define TBA 0x7A /* Transfer B to Accumulator. */ -#define CMP_IY 0x7C /* CMP Indirect Indexed. */ -#define CMP_IX 0x7D /* CMP Indexed Indirect. */ -#define BNE_Z 0x7E /* Branch if Not Equal. */ -#define BNE 0x80 /* BNE Absolute. */ -#define ROR 0x81 /* ROtate Right. */ -#define RRB 0x82 /* Rotate Right accumulator by B. */ -#define ROR_AB 0x84 /* ROR Absolute. */ -#define CPY_IN 0x85 /* CPY Indirect. */ -#define ROR_Z 0x86 /* ROR Zero Matrix. */ -#define DEY 0x88 /* DEcrement Y register. */ -#define STA_ZX 0x89 /* STA Zero Matrix, indexed with X. */ -#define TAY 0x8A /* Transfer Accumulator to Y. */ -#define LDB_IY 0x8C /* LDB Indirect Indexed. */ -#define LDB_IX 0x8D /* LDB Indexed Indirect. */ -#define BVS_Z 0x8E /* Branch if oVerflow Set. */ -#define BVS 0x90 /* BVS Absolute. */ -#define MUL 0x91 /* MULtiply accumulator. */ -#define MAB 0x92 /* Multiply Accumulator by B. */ -#define MUL_AB 0x94 /* MUL Absolute. */ -#define LDX_IN 0x95 /* LDX Indirect. */ -#define MUL_Z 0x96 /* MUL Zero Matrix. */ -#define CLI 0x98 /* CLear Interupt flag. */ -#define LDB_ZX 0x99 /* LDB Zero Matrix, indexed with X. */ -#define TYA 0x9A /* Transfer Y to Accumulator. */ -#define STB_IY 0x9C /* STB Indirect Indexed. */ -#define STB_IX 0x9D /* STB Indexed Indirect. */ -#define BVC_Z 0x9E /* Branch if oVerflow Clear. */ -#define BVC 0xA0 /* BVC Absolute. */ -#define DIV 0xA1 /* DIVide with accumulator. */ -#define DAB 0xA2 /* Divide Accumulator by B. */ -#define DIV_AB 0xA4 /* DIV Absolute. */ -#define STX_IN 0xA5 /* STX Indirect. */ -#define DIV_Z 0xA6 /* DIV Zero Matrix. */ -#define INY 0xA8 /* INcrement Y register. */ -#define STB_ZX 0xA9 /* STB Zero Matrix, indexed with X. */ -#define TAX 0xAA /* Transfer Accumulator to X. */ -#define CPB_IY 0xAC /* CPB Indirect Indexed. */ -#define CPB_IX 0xAD /* CPB Indexed Indirect. */ -#define RTS 0xAE /* ReTurn from Subroutine. */ -#define RTL 0xB0 /* ReTurn from subroutine Long. */ -#define CMP 0xB1 /* CoMPare accumulator. */ -#define CAB 0xB2 /* Compare Accumulator, and B. */ -#define CMP_AB 0xB4 /* CMP Absolute. */ -#define CPX_IN 0xB5 /* CPX Indirect. */ -#define CMP_Z 0xB6 /* CMP Zero Matrix. */ -#define SEI 0xB8 /* SEt Interupt flag. */ -#define LDX 0xB9 /* LoaD X register. */ -#define TXA 0xBA /* Transfer X to Accumulator. */ -#define LDX_AB 0xBC /* LDX Absolute. */ -#define LDX_Z 0xBD /* LDX Zero Matrix. */ -#define JSR_IN 0xBE /* JSR Indirect. */ -#define RTI 0xC0 /* ReTurn from Interrupt. */ -#define LDA 0xC1 /* LoaD Accumulator. */ -#define LDA_AB 0xC4 /* LDA Absolute. */ -#define DEX 0xC5 /* DEcrement X register. */ -#define LDA_Z 0xC6 /* LDA Zero Matrix. */ -#define CLV 0xC8 /* CLear oVerflow flag. */ -#define LDX_ZY 0xC9 /* LDX Zero Matrix, indexed with Y. */ -#define TYX 0xCA /* Transfer Y to X. */ -#define STA 0xCC /* STA Absolute. */ -#define STA_Z 0xCD /* STore Accumulator. */ -#define JMP_IN 0xCE /* JMP Indirect. */ -#define TSX 0xD0 /* Transfer Stack pointer to X. */ -#define LDB 0xD1 /* LoaD B register. */ -#define LDB_AB 0xD4 /* LDB Absolute. */ -#define INX 0xD5 /* INcrement X register. */ -#define LDB_Z 0xD6 /* LDB Zero Matrix. */ -#define WAI 0xD8 /* WAit for Interrupt. */ -#define STX_ZY 0xD9 /* STX Zero Matrix, indexed with Y. */ -#define TXY 0xDA /* Transfer X to Y. */ -#define STB 0xDC /* STB Absolute. */ -#define STB_Z 0xDD /* STore B register. */ -#define TXS 0xE0 /* Transfer X to Stack pointer. */ -#define LDY 0xE1 /* LoaD Y register. */ -#define LDY_AB 0xE4 /* LDY Absolute. */ -#define DEC 0xE5 /* DECrement accumulator. */ -#define LDY_Z 0xE6 /* LDY Zero Matrix. */ -#define BRK 0xE8 /* BReaK. */ -#define LDY_ZX 0xE9 /* LDY Zero Matrix, indexed with X. */ -#define NOP 0xEA /* No OPeration. */ -#define STY 0xEC /* STY Absolute. */ -#define STY_Z 0xED /* STore Y register. */ -#define DEB 0xEE /* Decrement B register. */ -#define ASR 0xF1 /* Arithmetic Shift Right. */ -#define ARB 0xF2 /* Arithmetic shift Right accumulator by B. */ -#define ASR_AB 0xF4 /* ASR Absolute. */ -#define INC 0xF5 /* INCrement accumulator. */ -#define ASR_Z 0xF6 /* ASR Zero Matrix. */ -#define STY_ZX 0xF9 /* STY Zero Matrix, indexed with X. */ -#define STX 0xFC /* STX Absolute. */ -#define STX_Z 0xFD /* STore X register. */ -#define INB 0xFE /* Increment B register. */ - #define OPNUM 90 -#define C ((uint64_t)1 << 0) -#define Z ((uint64_t)1 << 1) -#define I ((uint64_t)1 << 2) -#define V ((uint64_t)1 << 6) -#define N ((uint64_t)1 << 7) +#define C (1 << 0) /* Carry flag. */ +#define Z (1 << 1) /* Zero flag. */ +#define I (1 << 2) /* Interrupt flag. */ +#define V (1 << 6) /* oVerflow flag. */ +#define N (1 << 7) /* Negative flag. */ -uint8_t *addr; /* Address Space. */ +extern uint8_t *addr; /* Address Space. */ union reg { uint8_t u8[8]; @@ -219,194 +36,4 @@ struct sux { uint8_t crt; /* Current running threads. */ }; -enum {IMM, ZM, ZMX, ZMY, IND, INDX, INDY, ABS, IMPL}; - -static const uint8_t optype[0x100] = { - [0x00] = IMPL, - [0x01] = IMM, - [0x02] = IMPL, - [0x04] = ABS, - [0x05] = IND, - [0x06] = ZM, - [0x08] = IMM, - [0x09] = IMM, - [0x0A] = IMM, - [0x0C] = ABS, - [0x0D] = ZM, - [0x0E] = ZM, - [0x10] = ABS, - [0x11] = IMM, - [0x12] = IMPL, - [0x14] = ABS, - [0x15] = IND, - [0x16] = ZM, - [0x18] = IMM, - [0x19] = IMM, - [0x1A] = IMM, - [0x1C] = ABS, - [0x1D] = ZM, - [0x1E] = ZM, - [0x20] = ABS, - [0x21] = IMM, - [0x22] = IMPL, - [0x24] = ABS, - [0x25] = IND, - [0x26] = ZM, - [0x28] = IMM, - [0x29] = IMM, - [0x2A] = IMM, - [0x2C] = ABS, - [0x2D] = ZM, - [0x2E] = ZM, - [0x30] = ABS, - [0x31] = IMM, - [0x32] = IMPL, - [0x34] = ABS, - [0x35] = IND, - [0x36] = ZM, - [0x38] = IMM, - [0x39] = ZMY, - [0x3A] = IMM, - [0x3C] = ABS, - [0x3D] = ZM, - [0x3E] = ZM, - [0x40] = ABS, - [0x41] = IMM, - [0x42] = IMPL, - [0x44] = ABS, - [0x45] = IND, - [0x46] = ZM, - [0x48] = IMM, - [0x49] = ZMY, - [0x4A] = IMM, - [0x4C] = ABS, - [0x4D] = ZM, - [0x4E] = ZM, - [0x50] = ABS, - [0x51] = IMM, - [0x52] = IMPL, - [0x54] = ABS, - [0x55] = IND, - [0x56] = ZM, - [0x58] = IMPL, - [0x59] = ZMY, - [0x5A] = IMM, - [0x5C] = INDY, - [0x5D] = INDX, - [0x5E] = ZM, - [0x60] = ABS, - [0x61] = IMM, - [0x62] = IMPL, - [0x64] = ABS, - [0x65] = IND, - [0x66] = ZM, - [0x68] = IMM, - [0x69] = ZMY, - [0x6A] = IMPL, - [0x6C] = INDY, - [0x6D] = INDX, - [0x6E] = ZM, - [0x70] = ABS, - [0x71] = IMM, - [0x72] = IMPL, - [0x74] = ABS, - [0x75] = IND, - [0x76] = ZM, - [0x78] = IMPL, - [0x79] = ZMX, - [0x7A] = IMPL, - [0x7C] = INDY, - [0x7D] = INDX, - [0x7E] = ZM, - [0x80] = ABS, - [0x81] = IMM, - [0x82] = IMPL, - [0x84] = ABS, - [0x85] = IND, - [0x86] = ZM, - [0x88] = IMPL, - [0x89] = ZMX, - [0x8A] = IMPL, - [0x8C] = INDY, - [0x8D] = INDX, - [0x8E] = ZM, - [0x90] = ABS, - [0x91] = IMM, - [0x92] = IMPL, - [0x94] = ABS, - [0x95] = IND, - [0x96] = ZM, - [0x98] = IMPL, - [0x99] = ZMX, - [0x9A] = IMPL, - [0x9C] = INDY, - [0x9D] = INDX, - [0x9E] = ZM, - [0xA0] = ABS, - [0xA1] = IMM, - [0xA2] = IMPL, - [0xA4] = ABS, - [0xA5] = IND, - [0xA6] = ZM, - [0xA8] = IMPL, - [0xA9] = ZMX, - [0xAA] = IMPL, - [0xAC] = INDY, - [0xAD] = INDX, - [0xAE] = IMPL, - [0xB0] = IMPL, - [0xB1] = IMM, - [0xB2] = IMPL, - [0xB4] = ABS, - [0xB5] = IND, - [0xB6] = ZM, - [0xB8] = IMPL, - [0xB9] = IMM, - [0xBA] = IMPL, - [0xBC] = ABS, - [0xBD] = ZM, - [0xBE] = IND, - [0xC0] = IMPL, - [0xC1] = IMM, - [0xC4] = ABS, - [0xC5] = IMPL, - [0xC6] = ZM, - [0xC8] = IMPL, - [0xC9] = ZMY, - [0xCA] = IMPL, - [0xCC] = ABS, - [0xCD] = ZM, - [0xCE] = IND, - [0xD0] = IMPL, - [0xD1] = IMM, - [0xD4] = ABS, - [0xD5] = IMPL, - [0xD6] = ZM, - [0xD8] = IMPL, - [0xD9] = ZMY, - [0xDA] = IMPL, - [0xDC] = ABS, - [0xDD] = ZM, - [0xE0] = IMM, - [0xE1] = IMM, - [0xE4] = ABS, - [0xE5] = IMPL, - [0xE6] = ZM, - [0xE8] = IMPL, - [0xE9] = ZMX, - [0xEA] = IMPL, - [0xEC] = ABS, - [0xED] = ZM, - [0xEE] = IMPL, - [0xF1] = IMM, - [0xF2] = IMPL, - [0xF4] = ABS, - [0xF5] = IMPL, - [0xF6] = ZM, - [0xF9] = ZMX, - [0xFC] = ABS, - [0xFD] = ZM, - [0xFE] = IMPL -}; - extern int asmmon(); diff --git a/programs/subasm-2.s b/programs/subasm-2.s index f77116b..26af017 100644 --- a/programs/subasm-2.s +++ b/programs/subasm-2.s @@ -3,8 +3,7 @@ ; ; by mr b0nk 500 - -.org $A000 +.org incl ; String Constants. prg_name: .byte "SuBAsm" @@ -20,15 +19,23 @@ dir: .byte "word" .byte "dword" .byte "qword" -tok: - .byte '.' - .byte '#' - .byte '$' - .byte '%' - .byte '(' - .byte ')' - .byte ',' + .byte "include" + +; Short form Commands. +sh_cmds: + .byte "vlahirs" +; Commands. +cmds: + .byte "viewmem" + .byte "list" + .byte "asm" + .byte "help" + .byte "inst" + .byte "run" + .byte "set" + +; Instruction Mnemonics. mne: .byte "AAB" .byte "ABA" @@ -121,31 +128,194 @@ mne: .byte "XAB" .byte "XOR" +; Command subroutine table. +cmd_srt: + .word viewmem + .word list + .word asm + .word help + .word inst + .word run + .word set + +; Hex character table. +hex_char: + .byte "0123456789ABCDEF" + + +.org $4400 +; Subroutine pointer. +sub_ptr: + .word 0 + +; Indecies. +idx0: + .word 0 +idx1: + .word 0 +idx2: + .word 0 + +; Program Counter. +prg_cnt: + .qword 0 + ; Start of program code. -.org $8600 +.org parser subasm: - ldb #0 - lda.w #tok - sta.q ptr2 - tba - jsl chk_tok - - jsl chk_mne -chk_tok: - phy #2 - txy - lda (ptr6), y - cmp (ptr2), y - ply #2 - cpx #7 - beq tok_false -tok_true: - inb -tok_false: - stb f -tok_end: - ldb #0 - rtl - -chk_mne: - ply #2 + ldb #0 ; Set the first pointer + lda.w #cmd_buf ; to the command buffer. + jsl set_ptr ; + tba ; Reset A. + tax ; Reset X. + jsl chk_shcmd ; Did we get a shortend command? + bne parse_cmd ; Yes, so skip everything else. + jsl chk_cmd ; No, but did we get a full command? + bne parse_cmd ; Yes, so skip everything else. + jsl lexer ; No, so start lexing this line. +subasm_end: + rtl ; End of subasm. + +parse_cmd: + inb ; Set the second pointer + lda.w #cmd_srt ; to the command subroutine table. + jsl set_ptr ; + deb ; Reset B. + tba ; Reset A. + lda f ; Get the command ID. + cmp #8 ; Is the command ID greater than the command count? + bcs subasm_end ; Yes, so we're done. + lsl #1 ; No, so multiply the command ID by two. + phy #2 ; Preserve the screen buffer position. + tay ; Set the index to the offset that we just calculated. + lda.w (ptr2), y ; Get the command subroutine, from the command subroutine table. + ply #2 ; Get back the screen buffer position. + ldb #2 ; Save it in the third pointer. + jsl set_ptr ; + ldb #0 ; Reset B. + jsr (ptr3) ; Run the command's subroutine. + jmp subasm_end ; We are done. + +chk_shcmd: + inb ; Set the second pointer + lda.w #sh_cmds ; to the shortend command table. + jsl set_ptr ; + deb ; Reset B. + tba ; Reset A. + phy #2 ; Preserve the screen buffer position. + txy ; Set our index to zero. + lda (ptr), y ; Is there nothing in the command buffer? + beq shcmd_fail ; Yes, so return that we failed. + cmp #' ' ; No, but is this character, a space? + beq shcmd_fail ; Yes, so return that we failed. +shcmd_loop: + ldb (ptr2), y ; Are we at the end of the table? + beq shcmd_fail ; Yes, so return that we failed. + cab ; No, so did the character match? + beq shcmd_fnd ; Yes, so check if there are any arguments. + iny ; No, so check the next command. + jmp shcmd_loop ; Keep looping. +shcmd_fnd: + sty f ; 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 shcmd_true ; Yes, so return that we succeded. + cmp #' ' ; No, but is this a space? + beq shcmd_true ; Yes, so return that we succeded. + jmp shcmd_fail ; No, so return that we failed. +shcmd_true: + lda #1 ; Return true. + jmp shcmd_end ; We are done. +shcmd_fail: + tba ; Return false. + tax ; Reset X. +shcmd_end: + ldb #0 ; Reset B. + ply #2 ; Get back the screen buffer position. + rtl ; End of chk_shcmd. + +print_hex: + pha #8 ; Preserve the hex value. + ldb #1 ; Set the second pointer + lda.w hex_char ; to the start of hex character table. + jsl set_ptr ; + ldb #0 ; Reset B. + pla #8 ; Get the hex value back. +pnthex_lp: + pha #8 ; Preserve the hex value. + and #$F ; Mask the lowest nibble. + phx #2 ; Preserve the digit count. + phy #2 ; Preserve the screen buffer position. + tay ; Get the index for the hex digit. + lda (ptr2), y ; Get the hex digit. + ply #2 ; Get back the screen buffer position. + jsl print_char ; Print the hex digit. + plx #2 ; Get the digit count back. + pla #8 ; Get the hex value back. +pnthex_lp1: + cpx #1 ; Is the digit count less than one? + bcc pnthex_lp2 ; Yes, so don't decrement the digit count. + dex ; No, but was the digit count zero, when decremented? + beq pnthex_end ; Yes, so we're done. + jmp pnthex_lp3 ; No, so get the next nibble. +pnthex_lp2: + ldb #1 ; Enable auto digit count. +pnthex_lp3: + lsr #4 ; No, but is the next nibble, a zero? + beq pnthex_lp4 ; Yes, so check if auto digit count is enabled. + jmp pnthex_lp ; No, so print the next digit. +pnthex_lp4: + cpb #1 ; Is auto digit count enabled? + beq pnthex_end ; Yes, so we're done. + jmp pnthex_lp ; No, so keep printing more digits. +pnthex_end: + ldb #0 ; Reset B. + rtl ; End of print_hex. + +print_space: + lda #' ' ; Set the character to a space. + phb #1 ; Preserve the spacing count. + jsl print_char ; Print the space. + plb #1 ; Get the spacing count back. + deb ; Have we printed all of the spacing? + beq pntsp_end ; Yes, so we're done. + jmp print_space ; No, so keep printing spaces. +pntsp_end: + rtl ; End of print_space. + +viewmem: + pha #8 ; Preserve the address. + lda #'\n' ; Print a newline. + jsl print_char ; + ldb #19 ; Print 19 spaces. + jsl print_space ; +vmem_lp: + pla #8 ; Get the address back. + nop ; +vmem_end: + rts ; End of viewmem. + +list: + nop ; +list_end: + rts ; End of list. +asm: + nop ; +asm_end: + rts ; End of asm. +help: + nop ; +help_end: + rts ; End of help. +inst: + nop ; +inst_end: + rts ; End of inst. +run: + nop ; +run_end: + rts ; End of run. +set: + nop ; +set_end: + rts ; End of set. diff --git a/programs/subeditor.s b/programs/subeditor.s index d16915d..bdd3a11 100644 --- a/programs/subeditor.s +++ b/programs/subeditor.s @@ -13,6 +13,9 @@ step = $C010 ; Enables clock stepping, when set. maxrow = 23 ; Screen's row count. maxcol = 79 ; Screen's column count. +; Include SuBAsm. +.include "subasm-2.s" + .org $A000 ; String Literals/Constants. tok: @@ -35,6 +38,8 @@ bits: .byte $02 .byte $01 +; This label is for any included files. +incl: ; Linewrap table. .org $1000 @@ -127,6 +132,7 @@ reset: lda.w #buffer ; Set the array to be cleared to the screen buffer. jsl clr_arr ; Clear the screen buffer. jmp start ; Goto the start of the main program. + clr_arr: phb #1 ; Preserve whatever was in B. ldb #0 ; Clear B. @@ -371,7 +377,9 @@ cmd_cpy_lp1: sta (ptr2), y ; Copy one byte from the screen buffer, to the command buffer. inx ; Increment the command buffer index. ply #2 ; Get back the screen index. - iny ; Increment the screen index. + cpx.w #$3FF ; Are we at the end of the command buffer? + bcs cmd_cpy_nd0 ; Yes, so we're done. + iny ; No, so increment the screen index. inb ; Increment the byte count. lsr #8 ; Shift in the next byte. stb g ; Save the byte count. @@ -383,13 +391,17 @@ cmd_cpy_lp1: cpb #7 ; Did we shift in eight bytes? beq cmd_cpy_lp ; Yes, so get eight more bytes. jmp cmd_cpy_lp1 ; No, so keep shifting in more bytes. +cmd_cpy_nd0: + ldb #0 ; Reset B. + phy #2 ; Save the screen index. + txy ; Get the command buffer index. + stb (ptr2), y ; Terminate the command buffer. + ply #2 ; Get back the screen index. cmd_cpy_nd: tab ; The B register is zero, so clear the Accumulator. rtl ; End of cmd_cpy. - - findst: lda #0 ; findst_lp: @@ -406,6 +418,7 @@ findst_done: cmp #0 ; rtl ; + fndend: phb #1 ; Save the contents of the B register. ldb #0 ; Make sure that set_ptr sets the first pointer. @@ -1194,7 +1207,7 @@ print_buf: jsl print_str ; lsr #$10 ; Clear the Accumulator. cmd_clr: - lda #10 ; + lda #'\n' ; jsl print_char ; jmp start ; @@ -1243,6 +1256,9 @@ set_ptr3: setptr_end: rtl ; End of set_ptr. +; Entry point for SuBAsm. +parser: + .org $FFC0 .qword reset a diff --git a/sux.c b/sux.c index 3c84425..b8c4ca7 100644 --- a/sux.c +++ b/sux.c @@ -18,6 +18,10 @@ uint64_t inst[THREADS]; uint64_t inss; #endif +#if debug +uint8_t subdbg; +#endif + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; @@ -26,6 +30,12 @@ pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER; uint8_t threads_done = 0; uint8_t step = 0; +uint8_t *addr; + +uint8_t kbd_rdy; + +WINDOW *scr; + struct suxthr { struct sux sx; uint8_t th; @@ -131,6 +141,9 @@ void *run(void *args) { case 2: value.u8[1] = addr[address.u64+1]; } + #if getclk + ++iclk; + #endif } #if debug && !bench #if keypoll @@ -584,14 +597,15 @@ int main(int argc, char **argv) { inss = 0; #endif int v = 0; - #if debug - subdbg = !strcmp(argv[1], "programs/subeditor.s"); - #endif + if (argc != 2) { if (asmmon("stdin") == 2) { return 0; } } else { + #if debug + subdbg = !strcmp(argv[1], "programs/subeditor.s"); + #endif if (asmmon(argv[1]) == 2) { return 0; } diff --git a/sux.h b/sux.h index b36c4b1..3554011 100644 --- a/sux.h +++ b/sux.h @@ -14,13 +14,14 @@ #define STEP_ADDR 0xC010 #define CURSES_BACKSPACE 0x7F -uint8_t kbd_rdy; +extern uint8_t kbd_rdy; + +extern WINDOW *scr; #if debug -uint8_t subdbg; +extern uint8_t subdbg; #endif -WINDOW *scr; #define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit) #define getflag(bit) (cpu->ps.u8[thread] & bit) @@ -171,6 +172,9 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco address.u8[1] = addr[cpu->pc[thread]+1];++tmp; } cpu->pc[thread]+=tmp; + #if getclk + iclk++; + #endif break; } @@ -224,7 +228,7 @@ inline void push(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread uint8_t byte[8]; } r; r.reg = 0; - uint8_t size = ((int8_t)value >= 0) ? value-1 : 0; + uint8_t size = (value > 0) ? value-1 : 0; uint8_t tmp = (size <= 7) ? size : 7; switch (opcode) { case PHA: r.reg = cpu->a[thread]; break; @@ -252,7 +256,7 @@ inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread uint8_t byte[8]; } r; r.reg = 0; - uint8_t size = ((int8_t)value >= 0) ? value-1 : 0; + uint8_t size = (value > 0) ? value-1 : 0; uint8_t tmp = (size <= 7) ? size : 7; uint8_t tmp2 = 0; /* Unroll Loop by implementing Duff's Device. */ @@ -267,11 +271,11 @@ inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread case 1: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } switch (opcode) { - case PLA: cpu->a[thread] = r.reg; break; - case PLB: cpu->b[thread] = r.reg; break; - case PLX: cpu->x[thread] = r.reg; break; - case PLY: cpu->y[thread] = r.reg; break; - case PLP: cpu->ps.u64 = r.reg; break; + case PLA: cpu->a[thread] = r.reg; break; + case PLB: cpu->b[thread] = r.reg; break; + case PLX: cpu->x[thread] = r.reg; break; + case PLY: cpu->y[thread] = r.reg; break; + case PLP: cpu->ps.u64 = r.reg; break; } } diff --git a/tables.h b/tables.h new file mode 100644 index 0000000..6a95887 --- /dev/null +++ b/tables.h @@ -0,0 +1,189 @@ +#include "enums.h" + +static const uint8_t optype[0x100] = { + [CPS ] = IMPL, + [ADC ] = IMM, + [AAB ] = IMPL, + [ADC_AB ] = ABS, + [LDA_IN ] = IND, + [ADC_Z ] = ZM, + [PHP ] = IMM, + [CPB ] = IMM, + [PHB ] = IMM, + [DEC_AB ] = ABS, + [DEC_Z ] = ZM, + [JMP_Z ] = ZM, + [JMP ] = ABS, + [SBC ] = IMM, + [SAB ] = IMPL, + [SBC_AB ] = ABS, + [STA_IN ] = IND, + [SBC_Z ] = ZM, + [ENT ] = IMM, + [CPY ] = IMM, + [PLB ] = IMM, + [INC_AB ] = ABS, + [INC_Z ] = ZM, + [JSR ] = ZM, + [JSL ] = ABS, + [AND ] = IMM, + [ABA ] = IMPL, + [AND_AB ] = ABS, + [CMP_IN ] = IND, + [AND_Z ] = ZM, + [PLP ] = IMM, + [CPX ] = IMM, + [PHY ] = IMM, + [CPB_AB ] = ABS, + [CPB_Z ] = ZM, + [BPO_Z ] = ZM, + [BPO ] = ABS, + [ORA ] = IMM, + [OAB ] = IMPL, + [ORA_AB ] = ABS, + [LDB_IN ] = IND, + [ORA_Z ] = ZM, + [STT ] = IMM, + [LDA_ZY ] = ZMY, + [PLY ] = IMM, + [CPX_AB ] = ABS, + [CPY_Z ] = ZM, + [BNG_Z ] = ZM, + [BNG ] = ABS, + [XOR ] = IMM, + [XAB ] = IMPL, + [XOR_AB ] = ABS, + [STB_IN ] = IND, + [XOR_Z ] = ZM, + [PHA ] = IMM, + [STA_ZY ] = ZMY, + [PHX ] = IMM, + [CPY_AB ] = ABS, + [CPX_Z ] = ZM, + [BCS_Z ] = ZM, + [BCS ] = ABS, + [LSL ] = IMM, + [LLB ] = IMPL, + [LSL_AB ] = ABS, + [CPB_IN ] = IND, + [LSL_Z ] = ZM, + [CLC ] = IMPL, + [LDB_ZY ] = ZMY, + [PLX ] = IMM, + [LDA_IY ] = INDY, + [LDA_IX ] = INDX, + [BCC_Z ] = ZM, + [BCC ] = ABS, + [LSR ] = IMM, + [LRB ] = IMPL, + [LSR_AB ] = ABS, + [LDY_IN ] = IND, + [LSR_Z ] = ZM, + [PLA ] = IMM, + [STB_ZY ] = ZMY, + [TAB ] = IMPL, + [STA_IY ] = INDY, + [STA_IX ] = INDX, + [BEQ_Z ] = ZM, + [BEQ ] = ABS, + [ROL ] = IMM, + [RLB ] = IMPL, + [ROL_AB ] = ABS, + [STY_IN ] = IND, + [ROL_Z ] = ZM, + [SEC ] = IMPL, + [LDA_ZX ] = ZMX, + [TBA ] = IMPL, + [CMP_IY ] = INDY, + [CMP_IX ] = INDX, + [BNE_Z ] = ZM, + [BNE ] = ABS, + [ROR ] = IMM, + [RRB ] = IMPL, + [ROR_AB ] = ABS, + [CPY_IN ] = IND, + [ROR_Z ] = ZM, + [DEY ] = IMPL, + [STA_ZX ] = ZMX, + [TAY ] = IMPL, + [LDB_IY ] = INDY, + [LDB_IX ] = INDX, + [BVS_Z ] = ZM, + [BVS ] = ABS, + [MUL ] = IMM, + [MAB ] = IMPL, + [MUL_AB ] = ABS, + [LDX_IN ] = IND, + [MUL_Z ] = ZM, + [CLI ] = IMPL, + [LDB_ZX ] = ZMX, + [TYA ] = IMPL, + [STB_IY ] = INDY, + [STB_IX ] = INDX, + [BVC_Z ] = ZM, + [BVC ] = ABS, + [DIV ] = IMM, + [DAB ] = IMPL, + [DIV_AB ] = ABS, + [STX_IN ] = IND, + [DIV_Z ] = ZM, + [INY ] = IMPL, + [STB_ZX ] = ZMX, + [TAX ] = IMPL, + [CPB_IY ] = INDY, + [CPB_IX ] = INDX, + [RTS ] = IMPL, + [RTL ] = IMPL, + [CMP ] = IMM, + [CAB ] = IMPL, + [CMP_AB ] = ABS, + [CPX_IN ] = IND, + [CMP_Z ] = ZM, + [SEI ] = IMPL, + [LDX ] = IMM, + [TXA ] = IMPL, + [LDX_AB ] = ABS, + [LDX_Z ] = ZM, + [JSR_IN ] = IND, + [RTI ] = IMPL, + [LDA ] = IMM, + [LDA_AB ] = ABS, + [DEX ] = IMPL, + [LDA_Z ] = ZM, + [CLV ] = IMPL, + [LDX_ZY ] = ZMY, + [TYX ] = IMPL, + [STA ] = ABS, + [STA_Z ] = ZM, + [JMP_IN ] = IND, + [TSX ] = IMPL, + [LDB ] = IMM, + [LDB_AB ] = ABS, + [INX ] = IMPL, + [LDB_Z ] = ZM, + [WAI ] = IMPL, + [STX_ZY ] = ZMY, + [TXY ] = IMPL, + [STB ] = ABS, + [STB_Z ] = ZM, + [TXS ] = IMM, + [LDY ] = IMM, + [LDY_AB ] = ABS, + [DEC ] = IMPL, + [LDY_Z ] = ZM, + [BRK ] = IMPL, + [LDY_ZX ] = ZMX, + [NOP ] = IMPL, + [STY ] = ABS, + [STY_Z ] = ZM, + [DEB ] = IMPL, + [ASR ] = IMM, + [ARB ] = IMPL, + [ASR_AB ] = ABS, + [INC ] = IMPL, + [ASR_Z ] = ZM, + [STY_ZX ] = ZMX, + [STX ] = ABS, + [STX_Z ] = ZM, + [INB ] = IMPL +}; diff --git a/test/add-sub.s b/test/add-sub.s new file mode 100644 index 0000000..694931d --- /dev/null +++ b/test/add-sub.s @@ -0,0 +1,27 @@ +; Test adding, and subtracting. +; +; Written by mr b0nk 500 + +; Main Program. +.org 0 +reset: + cps ; Clear the processor status register. + ldx.w #$FFFF ; Reset the stack pointer. + txs ; + lsr #16 ; Reset A. + tab ; Reset B. + tax ; Reset X. +up: + inc ; Increment the counter. + cmp #$FF ; Did the accumulator overflow? + bcs down ; Yes, so start decrementing. + jmp up ; No, so keep incrementing. +down: + dec ; Did the accumulator underflow? + beq up ; Yes, so start incrementing. + jmp down ; No, so keep decrementing. + +.org $FFC0 +.qword reset +a +d diff --git a/test/ind-addr.s b/test/ind-addr.s index 0c9365b..005c016 100644 --- a/test/ind-addr.s +++ b/test/ind-addr.s @@ -1,8 +1,14 @@ -.org $0 +.org 0 +rot: + .qword 0 + +.org $1000 reset: cps - lda #1 ldb #1 + lda.w #rotate_left + sta.q rot + tba main: jsr (rot) jmp main @@ -15,13 +21,9 @@ rotate_right: rrb rts -.org $1000 -rot: - .qword rotate_left -r -.org $0 -v -.org $1000 -v -done +.org $FFC0 +.qword reset + +a +d -- cgit v1.2.3-13-gbd6f