diff options
-rw-r--r-- | asmmon.c | 245 | ||||
-rw-r--r-- | asmmon.h | 250 | ||||
-rw-r--r-- | lexer.c | 269 | ||||
-rw-r--r-- | opcode.h | 249 | ||||
-rw-r--r-- | programs/subeditor.s | 342 | ||||
-rw-r--r-- | sux.c | 221 |
6 files changed, 889 insertions, 687 deletions
@@ -3,27 +3,29 @@ uint16_t linenum = 10; uint16_t lineidx = 0; uint16_t stridx = 0; uint16_t comidx = 0; +uint16_t inc_file = 0; /* Number of included files. */ uint8_t defined = 0; uint8_t isfixup = 0; + static char tstr[2048]; void viewmem(uint64_t address) { putchar('\n'); printf("\t\t\t"); - for (int ind = 0; ind < 0x10; ind++) { + for (uint8_t ind = 0; ind < 0x10; ind++) { printf("%02X", ind); if (ind < 0x0F) { putchar(' '); } } puts("\n"); - for (int hi = 0; hi < 0x10; hi++) { - printf("$%016"PRIX64":\t", (address & ~0xF)+(hi*0x10)); - for (int lo = 0; lo < 0x10; lo++) { - printf("%02X", addr[(address & ~0xF)+lo+(hi*0x10)]); + for (uint8_t hi = 0; hi < 0x10; hi++) { + printf("$%016"PRIX64":\t", (address & ~0xF)+(hi << 4)); + for (uint8_t lo = 0; lo < 0x10; lo++) { + printf("%02X", addr[(address & ~0xF)+lo+(hi << 4)]); if (lo < 0x0F) { putchar(' '); } @@ -99,7 +101,7 @@ char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg) { } -void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) { +void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) { uint16_t i = start; uint8_t j = 0; uint8_t flags = 0; @@ -117,27 +119,27 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u } for (; i < end; i++) { flags = 0; - flags |= (tokline[i].dir != 0x00FF) << 0; - flags |= (tokline[i].mne != 0x00FF) << 1; - flags |= (tokline[i].rs != 0x00FF) << 2; - flags |= (tokline[i].am != 0x00FF) << 3; - flags |= (tokline[i].opbase != 0x00FF) << 4; - flags |= (tokline[i].sym != 0xFFFF) << 5; - flags |= (tokline[i].rs != 0x00FF) << 6; - flags |= (tokline[i].am != 0x00FF) << 7; - iscm = tokline[i].cm != 0xFF; - isstr = tokline[i].str != 0xFFFF; - iscom = tokline[i].com != 0xFFFF; + flags |= (l[i].dir != 0x00FF) << 0; + flags |= (l[i].mne != 0x00FF) << 1; + flags |= (l[i].rs != 0x00FF) << 2; + flags |= (l[i].am != 0x00FF) << 3; + flags |= (l[i].opbase != 0x00FF) << 4; + flags |= (l[i].sym != 0xFFFF) << 5; + flags |= (l[i].rs != 0x00FF) << 6; + flags |= (l[i].am != 0x00FF) << 7; + iscm = l[i].cm != 0xFF; + isstr = l[i].str != 0xFFFF; + iscom = l[i].com != 0xFFFF; if (dbg) { printf("list(): "); } if (ln) { - printf("%u\t", tokline[i].linenum); + printf("%u\t", l[i].linenum); } else if (addr) { - printf("$%"PRIX64":\t", tokline[i].addr); + printf("$%"PRIX64":\t", l[i].addr); } - spaces = tokline[i].sspace; - tabs = tokline[i].stab; + spaces = l[i].sspace; + tabs = l[i].stab; while (spaces || tabs) { if (spaces) { putchar(' '); @@ -149,26 +151,26 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u } } if (flags & 0x01) { - printf(".%s ", dir_t[tokline[i].dir]); + printf(".%s ", dir_t[l[i].dir]); if (isstr) { - printf("\"%s\"", string[tokline[i].str]); + printf("\"%s\"", string[l[i].str]); } } if (flags & 0x02) { for (; j < 3; j++) { - mne_lower[j] = tolower(mne[tokline[i].mne][j]); + mne_lower[j] = tolower(mne[l[i].mne][j]); } mne_lower[j] = '\0'; j = 0; printf("%s", mne_lower); } if (flags & 0x04) { - printf("%s ", rs_t[tokline[i].rs]); + printf("%s ", rs_t[l[i].rs]); } else if (flags & 0x02) { printf(" "); } if (flags & 0x7F) { - switch (tokline[i].am) { + switch (l[i].am) { case IMM: putchar('#'); break; @@ -180,36 +182,36 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u } } if (flags & 0x20) { - printf("%s", symbols[tokline[i].sym]->name); - if (tokline[i].islabel) { + printf("%s", symbols[l[i].sym]->name); + if (l[i].islabel) { printf(": "); - } else if (tokline[i].issym) { + } else if (l[i].issym) { printf(" = "); } } if (flags & 0x10) { if (flags & 0x04) { - bitnum = (tokline[i].rs << 3); + bitnum = (l[i].rs << 3); } else { - opsize += (tokline[i].op <= 0x000000FF) + 0; - opsize += (tokline[i].op > 0x000000FF) + 1; - opsize += (tokline[i].op > 0x0000FFFF) + 2; - opsize += (tokline[i].op > 0xFFFFFFFF) + 3; + opsize += (l[i].op <= 0x000000FF) + 0; + opsize += (l[i].op > 0x000000FF) + 1; + opsize += (l[i].op > 0x0000FFFF) + 2; + opsize += (l[i].op > 0xFFFFFFFF) + 3; if (opsize) { bitnum = bitsize[opsize-1]; } } - switch (tokline[i].opbase) { - case BASE_HEX: printf("$%"PRIX64, tokline[i].op); break; - case BASE_DEC: printf("%"PRIu64, tokline[i].op); break; - case BASE_BIN: printf("%%%s", showbits(tokline[i].op, bitnum, dbg)); break; + switch (l[i].opbase) { + case BASE_HEX: printf("$%"PRIX64, l[i].op); break; + case BASE_DEC: printf("%"PRIu64, l[i].op); break; + case BASE_BIN: printf("%%%s", showbits(l[i].op, bitnum, dbg)); break; } bitnum = 0; opsize = 0; } if (iscm) { - switch (tokline[i].cm) { + switch (l[i].cm) { case 0: putchar('+'); break; @@ -217,17 +219,17 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u putchar ('-'); break; } - opsize += (tokline[i].aop <= 0x000000FF) + 0; - opsize += (tokline[i].aop > 0x000000FF) + 1; - opsize += (tokline[i].aop > 0x0000FFFF) + 2; - opsize += (tokline[i].aop > 0xFFFFFFFF) + 3; + opsize += (l[i].aop <= 0x000000FF) + 0; + opsize += (l[i].aop > 0x000000FF) + 1; + opsize += (l[i].aop > 0x0000FFFF) + 2; + opsize += (l[i].aop > 0xFFFFFFFF) + 3; if (opsize) { bitnum = bitsize[opsize-1]; } - switch (tokline[i].aopbase) { - case BASE_HEX: printf("$%"PRIX64, tokline[i].aop); break; - case BASE_DEC: printf("%"PRIu64, tokline[i].aop); break; - case BASE_BIN: printf("%%%s", showbits(tokline[i].aop, bitnum, dbg)); break; + switch (l[i].aopbase) { + case BASE_HEX: printf("$%"PRIX64, l[i].aop); break; + case BASE_DEC: printf("%"PRIu64, l[i].aop); break; + case BASE_BIN: printf("%%%s", showbits(l[i].aop, bitnum, dbg)); break; } bitnum = 0; opsize = 0; @@ -236,11 +238,11 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u if (fall) { fall = 0; } - switch (tokline[i].am) { + switch (l[i].am) { case INDX: case ZMX: printf(", x"); - if (tokline[i].am == ZMX) { + if (l[i].am == ZMX) { break; } fall = 1; @@ -259,8 +261,8 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u break; } } - spaces = tokline[i].espace; - tabs = tokline[i].etab; + spaces = l[i].espace; + tabs = l[i].etab; while (spaces || tabs) { if (spaces) { putchar(' '); @@ -272,13 +274,13 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u } } if (iscom) { - printf(";%s", comment[tokline[i].com]); + printf(";%s", comment[l[i].com]); } puts(""); } } -uint64_t assemble(uint8_t dbg) { +uint64_t assemble(struct line *line, uint8_t dbg) { uint64_t bytecount = 0; uint64_t tmpaddr; uint64_t value; @@ -292,6 +294,8 @@ uint64_t assemble(uint8_t dbg) { uint8_t skip = 0; uint64_t address; + uint64_t op; + uint64_t aop; uint16_t symid; uint16_t str; uint16_t com; @@ -308,19 +312,21 @@ uint64_t assemble(uint8_t dbg) { if (dbg) { printf("assemble(): i: $%X\n", i); } - address = tokline[i].addr; + address = line[i].addr; tmpaddr = address; - symid = tokline[i].sym; - str = tokline[i].str; - com = tokline[i].com; - islabel = tokline[i].islabel; - opbase = tokline[i].opbase; - aopbase = tokline[i].aopbase; - dir = tokline[i].dir; - am = tokline[i].am; - cm = tokline[i].cm; - rs = tokline[i].rs; - ins = tokline[i].mne; + op = line[i].op; + aop = line[i].aop; + symid = line[i].sym; + str = line[i].str; + com = line[i].com; + islabel = line[i].islabel; + opbase = line[i].opbase; + aopbase = line[i].aopbase; + dir = line[i].dir; + am = line[i].am; + cm = line[i].cm; + rs = line[i].rs; + ins = line[i].mne; flags = 0; flags |= (dir != 0x00FF) << 0x00; flags |= (ins != 0x00FF) << 0x01; @@ -364,15 +370,15 @@ uint64_t assemble(uint8_t dbg) { if ((flags & 0x53) == 0x42) { value = symbols[symid]->val; } else { - value = tokline[i].op; + value = op; } if ((flags & 0x51) == 0x41) { value = symbols[symid]->val; } if (flags & 0x220) { switch (cm) { - case 0: value += tokline[i].aop; break; - case 1: value -= tokline[i].aop; break; + case 0: value += aop; break; + case 1: value -= aop; break; } } if (dbg) { @@ -430,7 +436,10 @@ uint64_t assemble(uint8_t dbg) { addr[tmpaddr+1] = value >> 0x08; addr[tmpaddr ] = value & 0xFF; tmp+=2; - + break; + case DIR_INCLUDE: + incl[inc_file++] = line[i].incl; + break; } tmpaddr += tmp; tmp = 0; @@ -567,9 +576,23 @@ uint64_t assemble(uint8_t dbg) { int asmmon(const char *fn) { FILE *fp; + FILE *fp2; + char *path = malloc(0x400); if (strcasecmp(fn, "stdin")) { + uint16_t i = 0; + uint8_t dir = 0; + for (; fn[i] != '\0'; i++) dir = (fn[i] == '/') ? i : dir; + if (dir) { + memcpy(path, fn, dir); + path[dir] = '\0'; + } else { + path[0] = '.'; + path[1] = '\0'; + + } fp = fopen(fn, "r"); if (fp == NULL) { + free(path); return 2; } } @@ -578,6 +601,9 @@ int asmmon(const char *fn) { uint64_t address = 0; uint64_t bytecount = 0; uint8_t dbg = 0; + uint8_t isinclude = 0; + uint16_t tmp_lineidx = 0; + uint8_t inc_count = 0; init_symbol(); while (!done) { char *cmd; @@ -586,10 +612,19 @@ int asmmon(const char *fn) { char lex_line[0x1000]; uint16_t size = 0; uint8_t cmds = 0; - uint8_t dummy = 0; /* Is single character command. */ uint8_t isshcmd = 0; - fgets(lex_line, sizeof(lex_line), (!strcasecmp(fn, "stdin")) ? stdin : fp); + if (!isinclude) { + fgets(lex_line, sizeof(lex_line), (!strcasecmp(fn, "stdin")) ? stdin : fp); + } else { + if (fp2 != NULL) { + if (fgets(lex_line, sizeof(lex_line), fp2) == NULL && feof(fp2)) { + lex_line[0] = 'a' ; + lex_line[1] = '\n'; + lex_line[2] = '\0'; + } + } + } size = strlen(lex_line)+1; cmd = malloc(size); memcpy(cmd, lex_line, size); @@ -612,6 +647,11 @@ int asmmon(const char *fn) { } switch (cmds) { case 0x01: + free(path); + fclose(fp); + if (fp2 != NULL) { + fclose(fp2); + } return 2; case 0x02: viewmem(address); @@ -677,16 +717,55 @@ int asmmon(const char *fn) { } i++; } - list(start, end, isstart, islinenum, isaddr, isdebug); + if (!isinclude) { + list(tokline, start, end, isstart, islinenum, isaddr, isdebug); + } else { + list(tln, start, end, isstart, islinenum, isaddr, isdebug); + } } else { - list(0, 0, 1, 0, 0, 0); + if (!isinclude) { + list(tokline, 0, 0, 1, 0, 0, 0); + } else { + list(tln, 0, 0, 1, 0, 0, 0); + } } break; case 0x08: - puts("Assembling program."); - bytecount = assemble(dbg); - puts("Finished assembling program."); - printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", bytecount, bytecount); + if (!isinclude) { + puts("Assembling program."); + bytecount = assemble(tokline, dbg); + } else { + bytecount += assemble(tln, dbg); + } + 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; + } + lineidx = 0; + linenum = 10; + inc_file--; + inc_count++; + if (inc_file && fp2 != NULL) { + fclose(fp2); + } + fp2 = fopen(fn2, "r"); + if (fp2 == NULL) { + free(path); + fclose(fp); + return 2; + } + } else if (!inc_file && tmp_lineidx) { + lineidx = tmp_lineidx; + } + if (!isinclude) { + puts("Finished assembling program."); + printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", bytecount, bytecount); + } break; case 0x10: usage(); @@ -729,11 +808,19 @@ int asmmon(const char *fn) { case 0xFF: break; default: - address = lex(lex_line, address, dbg); + if (!isinclude) { + address = lex(lex_line, tokline, address, dbg); + } else { + address = lex(lex_line, tln, address, dbg); + } break; } } } - reslv_fixups(0); + free(path); + fclose(fp); + if (fp2 != NULL) { + fclose(fp2); + } return 0; } @@ -2,11 +2,42 @@ #include <ctype.h> #include <string.h> -#define debug 1 - char lexeme[0x1000]; uint8_t lex_type; +enum { + DIR_ORG, + DIR_BYTE, + DIR_WORD, + DIR_DWORD, + DIR_QWORD, + DIR_INCLUDE +}; + +enum { + TOK_DIR, + TOK_LABEL, + TOK_SYM, + TOK_PLUS, + TOK_MINUS, + TOK_STRING, + TOK_CHAR, + TOK_IMM, + TOK_OPCODE, + TOK_RS, + TOK_COMMENT, + TOK_HEX, + TOK_DEC, + TOK_BIN, + TOK_INCLUDE +}; + +enum { + BASE_HEX, + BASE_DEC, + BASE_BIN +}; + static const uint8_t opcodes[OPNUM][9] = { /* IMM ZM ZMX ZMY IND INDX INDY ABS IMPL*/ [ 0] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}, @@ -101,12 +132,13 @@ static const uint8_t opcodes[OPNUM][9] = { [89] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE} }; -static const char *dir_t[5] = { +static const char *dir_t[6] = { [0] = "org", [1] = "byte", [2] = "word", [3] = "dword", - [4] = "qword" + [4] = "qword", + [5] = "include" }; static const char *rs_t[4] = { @@ -116,7 +148,7 @@ static const char *rs_t[4] = { [3] = ".q" }; -static const char *lex_tok[14] = { +static const char *lex_tok[15] = { [0x0] = "TOK_DIR", [0x1] = "TOK_LABEL", [0x2] = "TOK_SYM", @@ -130,7 +162,206 @@ static const char *lex_tok[14] = { [0xA] = "TOK_COMMENT", [0xB] = "TOK_HEX", [0xC] = "TOK_DEC", - [0xD] = "TOK_BIN" + [0xD] = "TOK_BIN", + [0xE] = "TOK_INCLUDE" +}; + +static const char *adrmode[9] = { + [IMM ] = "IMM", + [ZM ] = "ZM", + [ZMX ] = "ZMX", + [ZMY ] = "ZMY", + [IND ] = "IND", + [INDX] = "INDX", + [INDY] = "INDY", + [ABS ] = "ABS", + [IMPL] = "IMPL" +}; + +static const char *mne[OPNUM] = { + [ 0] = "CPS", + [ 1] = "ADC", + [ 2] = "AAB", + [ 3] = "PHP", + [ 4] = "CPB", + [ 5] = "PHB", + [ 6] = "DEC", + [ 7] = "JMP", + [ 8] = "SBC", + [ 9] = "SAB", + [10] = "ENT", + [11] = "CPY", + [12] = "PLB", + [13] = "INC", + [14] = "JSR", + [15] = "JSL", + [16] = "AND", + [17] = "ABA", + [18] = "PLP", + [19] = "CPX", + [20] = "PHY", + [21] = "BPO", + [22] = "ORA", + [23] = "OAB", + [24] = "STT", + [25] = "PLY", + [26] = "BNG", + [27] = "XOR", + [28] = "XAB", + [29] = "PHA", + [30] = "PHX", + [31] = "BCS", + [32] = "LSL", + [33] = "LLB", + [34] = "CLC", + [35] = "PLX", + [36] = "BCC", + [37] = "LSR", + [38] = "LRB", + [39] = "PLA", + [40] = "TAB", + [41] = "BEQ", + [42] = "ROL", + [43] = "RLB", + [44] = "SEC", + [45] = "TBA", + [46] = "BNE", + [47] = "ROR", + [48] = "RRB", + [49] = "DEY", + [50] = "TAY", + [51] = "BVS", + [52] = "MUL", + [53] = "MAB", + [54] = "CLI", + [55] = "TYA", + [56] = "BVC", + [57] = "DIV", + [58] = "DAB", + [59] = "INY", + [60] = "TAX", + [61] = "RTS", + [62] = "RTL", + [63] = "CMP", + [64] = "CAB", + [65] = "SEI", + [66] = "LDX", + [67] = "TXA", + [68] = "RTI", + [69] = "LDA", + [70] = "DEX", + [71] = "CLV", + [72] = "TYX", + [73] = "STA", + [74] = "TSX", + [75] = "LDB", + [76] = "INX", + [77] = "WAI", + [78] = "TXY", + [79] = "STB", + [80] = "TXS", + [81] = "LDY", + [82] = "BRK", + [83] = "NOP", + [84] = "STY", + [85] = "DEB", + [86] = "ASR", + [87] = "ARB", + [88] = "STX", + [89] = "INB" +}; + +static const char *instdesc[OPNUM] = { + [ 0] = "Clears the Processor Status register.", + [ 1] = "ADd accumulator, with operand, Carry if needed.", + [ 2] = "Add Accumulator, with B, carry if needed.", + [ 3] = "PusH the number of bytes specified, from the Processor status register to the stack.", + [ 4] = "ComPare the B register, with operand.", + [ 5] = "PusH the number of bytes specified, from the B register to the stack.", + [ 6] = "DECrement accumulator, or memory.", + [ 7] = "JuMP to the address specified.", + [ 8] = "SuBtract accumulator, with operand, Carry if needed", + [ 9] = "Subtract Accumulator, with B, carry if needed.", + [10] = "ENd a Thread.", + [11] = "ComPare the Y register, with operand.", + [12] = "PuLl the number of bytes specified, from the stack, to the B register.", + [13] = "INCrement accumulator, or memory.", + [14] = "Jump to a SubRoutine.", + [15] = "Jump to a Subroutine, Long address.", + [16] = "Bitwise AND accumulator, with operand.", + [17] = "Bitwise AND Accumulator, with B.", + [18] = "PuLl the number of bytes specified, from the stack, to the Processor status register.", + [19] = "ComPare the X register, with operand.", + [20] = "PusH the number of bytes specified, from the Y register to the stack.", + [21] = "Branch if POsitive.", + [22] = "Bitwise OR Accumulator, with operand.", + [23] = "Bitwise OR Accumulator, with B.", + [24] = "STart a Thread.", + [25] = "PuLl the number of bytes specified, from the stack, to the Y register.", + [26] = "Branch if NeGative.", + [27] = "Bitwise XOR Accumulator, with operand.", + [28] = "Bitwise XOR Accumulator, with B.", + [29] = "PusH the number of bytes specified, from the Accumulator to the stack.", + [30] = "PusH the number of bytes specified, from the X register to the stack.", + [31] = "Branch if the Carry flag is Set.", + [32] = "Logical Shift Left accumulator, with operand.", + [33] = "Logical Shift Left accumulator, with B.", + [34] = "CLear the Carry flag.", + [35] = "PuLl the number of bytes specified, from the stack, to the X register.", + [36] = "Branch if the Carry flag has been Cleared.", + [37] = "Logical Shift Right accumulator, with operand.", + [38] = "Logical Shift Right accumulator, with B.", + [39] = "PuLl the number of bytes specified, from the stack, to the Accumulator.", + [40] = "Transfer the value from the Accumulator, to the B register.", + [41] = "Branch if EQual (the zero flag has been set).", + [42] = "ROtate Left accumulator, with operand.", + [43] = "Rotate Left accumulator, with B.", + [44] = "SEt the Carry flag.", + [45] = "Transfer the value from the Y register, to the Accumulator.", + [46] = "Branch if Not Equal (the zero flag has been cleared)", + [47] = "ROtate Right accumulator, with operand.", + [48] = "Rotate Right accumulator, with B.", + [49] = "DEcrement the Y register.", + [50] = "Transfer the value from the Accumulator, to the Y register.", + [51] = "Branch if the oVerflow flag is Set.", + [52] = "MULtiply accumulator, with operand.", + [53] = "Multiply Accumulator, with B.", + [54] = "CLear the Interrupt flag.", + [55] = "Transfer the value from the Y register, to the Accumulator.", + [56] = "Branch if the oVerflow flag has been Cleared.", + [57] = "DIVide accumulator, with operand, and put the remainder into the B register.", + [58] = "Divide Accumulator, with B, and put the remainder into the X register.", + [59] = "INcrement the Y register.", + [60] = "Transfer the value from the Accumulator, to the X register.", + [61] = "ReTurn from a Subroutine.", + [62] = "ReTurn from subroutine, Long address.", + [63] = "CoMPare acumulator, with operand.", + [64] = "Compare Accumulator, with B.", + [65] = "SEt the Interrupt flag.", + [66] = "LoaD the value from the operand, to the X register.", + [67] = "Transfer the value from the X register, to the Accumulator.", + [68] = "ReTurn from an Interrupt.", + [69] = "LoaD the value from the operand, to the Accumulator.", + [70] = "DEcrement the X register.", + [71] = "CLear the oVerflow flag.", + [72] = "Transfer the value from the Y register, to the X register.", + [73] = "STore the value from the Accumulator, in memory.", + [74] = "Transfer the value from the Stack pointer, to the X register.", + [75] = "LoaD the value from the operand, to the B register.", + [76] = "INcrement the X register.", + [77] = "WAIt for an interrupt", + [78] = "Transfer the value from the X register, to the Y register.", + [79] = "STore the value from the B register, in memory.", + [80] = "Transfer the value from the X register, to the Stack pointer.", + [81] = "LoaD the value from the operand, to the Y register.", + [82] = "BReaKpoint", + [83] = "NO oPeration", + [84] = "STore the value from the Y register, in memory.", + [85] = "DEcrement the B register.", + [86] = "Arithmetic Shift Right accumulator, with operand.", + [87] = "Arithmetic shift Right accumulator, with B.", + [88] = "STore the value from the X register, in memory.", + [89] = "INcrement the B register." }; static const uint8_t bitsize[4] = { @@ -168,6 +399,7 @@ struct line { uint16_t sym; uint16_t com; uint16_t str; + uint16_t incl; uint16_t linenum; uint64_t op; uint64_t aop; @@ -181,8 +413,10 @@ 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; @@ -209,5 +443,5 @@ extern uint8_t set_symval(const char *name, uint16_t id, uint64_t val, uint8_t u extern char *get_symname(uint16_t id, uint8_t dbg); extern uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg); extern uint16_t get_comment(const char *cmnt, uint8_t dbg); -extern uint16_t reslv_fixups(uint8_t dbg); -extern uint64_t lex(char *str, uint64_t address, uint8_t dbg); +extern uint16_t reslv_fixups(struct line *l, uint8_t dbg); +extern uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg); @@ -43,7 +43,7 @@ uint16_t mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, ui } } } - symbols[i] = malloc(sizeof(*symbols) + strlen(name)); + symbols[i] = malloc(sizeof(**symbols) + strlen(name)); symbols[i]->def = def; symbols[i]->val = val; strcpy(symbols[i]->name, name); @@ -119,7 +119,7 @@ char *get_symname(uint16_t id, uint8_t dbg) { uint16_t fixup_cnt = 0; uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg) { - uint16_t i = mksymbol(name, 0, 0, 0, 0, dbg); + uint16_t i = mksymbol(name, 0, 0, 0, ln, dbg); if (dbg) { printf("get_symid(): Symbol ID: $%X, i: $%X.\n", symbols[i]->id, i); } @@ -129,7 +129,7 @@ uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg) { if (dbg) { printf("get_symid(): oof, symbol %s, does not exist, yet.\n", name); } - fixups[fixup_cnt] = malloc(sizeof(*fixups)); + fixups[fixup_cnt] = malloc(sizeof(**fixups)); fixups[fixup_cnt]->adr = val; fixups[fixup_cnt]->ln = ln; fixups[fixup_cnt]->s = symbols[i]; @@ -204,14 +204,14 @@ uint16_t get_string(const char *str, uint8_t dbg) { return i; } -uint16_t reslv_fixups(uint8_t dbg) { +uint16_t reslv_fixups(struct line *l, uint8_t dbg) { uint16_t i = 0, j = 0; for (; fixups[j]; j++) { if (fixups[j]->s->def) { if (dbg) { printf("reslv_fixups(): Symbol ID: $%X, Symbol Name: %s.\n", fixups[j]->s->id, fixups[j]->s->name); } - tokline[fixups[j]->ln].sym = fixups[j]->s->id; + l[fixups[j]->ln].sym = fixups[j]->s->id; } else { if (dbg) { printf("reslv_fixups(): oof, undefined reference to '%s', at $%016"PRIX64".\n", fixups[j]->s->name, fixups[j]->adr); @@ -223,25 +223,25 @@ uint16_t reslv_fixups(uint8_t dbg) { } -uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { +uint64_t update_addr(struct line *ln, uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { uint64_t value = 0; uint16_t i = 0; uint16_t j = 0; uint16_t flags = 0; uint8_t opsize = 0; - uint16_t symid = tokline[l].sym; - uint16_t str = tokline[l].str; - uint16_t com = tokline[l].com; - uint8_t islabel = tokline[l].islabel; - uint8_t issym = tokline[l].issym; - uint8_t opbase = tokline[l].opbase; - uint8_t aopbase = tokline[l].aopbase; - uint8_t dir = tokline[l].dir; - uint8_t am = tokline[l].am; - uint8_t cm = tokline[l].cm; - uint8_t rs = tokline[l].rs; - uint8_t mne = tokline[l].mne; + uint16_t symid = ln[l].sym; + uint16_t str = ln[l].str; + uint16_t com = ln[l].com; + uint8_t islabel = ln[l].islabel; + uint8_t issym = ln[l].issym; + uint8_t opbase = ln[l].opbase; + uint8_t aopbase = ln[l].aopbase; + uint8_t dir = ln[l].dir; + uint8_t am = ln[l].am; + uint8_t cm = ln[l].cm; + uint8_t rs = ln[l].rs; + uint8_t mne = ln[l].mne; flags |= (dir != 0x00FF) << 0x00; flags |= (mne != 0x00FF) << 0x01; @@ -277,12 +277,12 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { value = use_symbol("", symid, address, 1, dbg); } } else { - value = tokline[l].op; + value = ln[l].op; } if (flags & 0x220) { switch (cm) { - case 0: value += tokline[l].aop; break; - case 1: value -= tokline[l].aop; break; + case 0: value += ln[l].aop; break; + case 1: value -= ln[l].aop; break; } } if (dbg) { @@ -324,7 +324,7 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { return address; } if ((flags & 0x15B) == 0x02 || (opcodes[mne][IMPL] != 0xFF && am == 0xFF && opbase == 0xFF && symid == 0xFFFF)) { - tokline[l].am = IMPL; + ln[l].am = IMPL; am = IMPL; if (dbg) { printf("update_addr(): "); @@ -366,7 +366,7 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { case 3: if (!(flags & 0x100)) { am = ZM; - tokline[l].am = am; + ln[l].am = am; if (dbg) { printf("update_addr(): "); puts("Addressing Mode has been set to Zero Matrix."); @@ -379,7 +379,7 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { case 7: if (!(flags & 0x100)) { am = ABS; - tokline[l].am = am; + ln[l].am = am; if (dbg) { printf("update_addr(): "); puts("Addressing Mode has been set to Absolute."); @@ -402,21 +402,21 @@ uint64_t update_addr(uint64_t address, uint8_t fixup, uint16_t l, uint8_t dbg) { return address; } -uint16_t find_line(uint16_t ln, uint8_t dbg) { +uint16_t find_line(struct line *l, uint16_t ln, uint8_t dbg) { uint16_t i = 0; - for (; i < lineidx && tokline[i].linenum != ln; i++); - if (tokline[i].linenum == ln) { + for (; i < lineidx && l[i].linenum != ln; i++); + if (l[i].linenum == ln) { if (dbg) { printf("find_line(): Found line number %u, at line index %X.\n", ln, i); } } if (dbg) { - printf("find_line(): linenum: %u, i: %X\n", tokline[i].linenum, i); + printf("find_line(): linenum: %u, i: %X\n", l[i].linenum, i); } return i; } -uint64_t lex(char *str, uint64_t address, uint8_t dbg) { +uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) { char sym[0x100]; uint16_t i = 0; uint16_t j = 0; @@ -451,25 +451,25 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { ln = linenum; } for (; isspace(str[i]); i++); - line = find_line(ln, dbg); + line = find_line(l, ln, dbg); if (line != lineidx) { - address = tokline[line].addr; - } - tokline[line].dir = 0xFF; - tokline[line].mne = 0xFF; - tokline[line].rs = 0xFF; - tokline[line].am = 0xFF; - tokline[line].cm = 0xFF; - tokline[line].opbase = 0xFF; - tokline[line].aopbase = 0xFF; - tokline[line].islabel = 0; - tokline[line].issym = 0; - tokline[line].str = 0xFFFF; - tokline[line].com = 0xFFFF; - tokline[line].sym = 0xFFFF; - tokline[line].op = 0; - tokline[line].aop = 0; - tokline[line].addr = address; + address = l[line].addr; + } + l[line].dir = 0xFF; + l[line].mne = 0xFF; + l[line].rs = 0xFF; + l[line].am = 0xFF; + l[line].cm = 0xFF; + l[line].opbase = 0xFF; + l[line].aopbase = 0xFF; + l[line].islabel = 0; + l[line].issym = 0; + l[line].str = 0xFFFF; + l[line].com = 0xFFFF; + l[line].sym = 0xFFFF; + l[line].op = 0; + l[line].aop = 0; + l[line].addr = address; while (str[i] != '\0' && str[i] != '\n') { space = 0; tab = 0; @@ -483,10 +483,10 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { printf("lex(): tab: %u, space: %u\n", tab, space); } if (isstart) { - tokline[line].stab = tab; - tokline[line].sspace = space; + l[line].stab = tab; + l[line].sspace = space; if (dbg) { - printf("lex(): starting tabs: %u, starting spaces: %u\n", tokline[line].stab, tokline[line].sspace); + printf("lex(): starting tabs: %u, starting spaces: %u\n", l[line].stab, l[line].sspace); } } if (isspace(str[i])) { @@ -502,7 +502,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } lexeme[j] = '\0'; if (!isop) { - for (k = 0; k < 5; k++) { + for (k = 0; k < 6; k++) { if (tolower(lexeme[0]) == dir_t[k][0]) { if (!strcasecmp(lexeme, dir_t[k])) { lex_type = TOK_DIR; @@ -510,7 +510,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } } } - tokline[line].dir = k; + l[line].dir = k; } else { lex_type = TOK_RS; switch (tolower(lexeme[j-1])) { @@ -528,7 +528,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { break; } address++; - tokline[line].rs = rs; + l[line].rs = rs; isop = 0; } break; @@ -539,31 +539,34 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } strid = get_string(lexeme, dbg); if (strid == 0xFFFF) { - if (line != lineidx && tokline[line].str != 0xFFFF) { - strid = tokline[line].str; + if (line != lineidx && l[line].str != 0xFFFF) { + strid = l[line].str; } else { strid = stridx; } string[strid] = malloc(j+1); memcpy(string[strid], lexeme, j+1); - tokline[line].str = strid; + l[line].str = strid; if (dbg) { printf("lex(): str[0x%04X]: %s\n", strid, string[strid]); } stridx += (line == lineidx); } else { - tokline[line].str = strid; + l[line].str = strid; if (dbg) { printf("lex(): str[0x%04X]: %s\n", strid, string[strid]); } } + if (l[line].dir == DIR_INCLUDE) { + l[line].incl = strid; + } lex_type = TOK_STRING; break; case '#': lexeme[j] = '#'; lexeme[j+1] = '\0'; lexeme[j+2] = '\0'; - tokline[line].am = IMM; + l[line].am = IMM; lex_type = TOK_IMM; break; case '$': @@ -574,27 +577,27 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j] = '\0'; switch (lex_type) { case TOK_SYM: - tokline[line].op = strtoull(lexeme, NULL, 16); - mksymbol(sym, tokline[line].op, 1, 0, 0, dbg); - tokline[line].sym = get_symid(sym, address, line, dbg); - isfixup += (tokline[line].sym == 0xFFFF); + l[line].op = strtoull(lexeme, NULL, 16); + mksymbol(sym, l[line].op, 1, 0, 0, dbg); + l[line].sym = get_symid(sym, address, line, dbg); + isfixup += (l[line].sym == 0xFFFF); if (dbg) { printf("lex(): isfixup: %u\n", isfixup); } - tokline[line].opbase = BASE_HEX; + l[line].opbase = BASE_HEX; break; case TOK_PLUS: case TOK_MINUS: - tokline[line].aop = strtoull(lexeme, NULL, 16); - tokline[line].aopbase = BASE_HEX; + l[line].aop = strtoull(lexeme, NULL, 16); + l[line].aopbase = BASE_HEX; break; default: - if (tokline[line].cm != 0xFF) { - tokline[line].aop = strtoull(lexeme, NULL, 16); - tokline[line].aopbase = BASE_HEX; + if (l[line].cm != 0xFF) { + l[line].aop = strtoull(lexeme, NULL, 16); + l[line].aopbase = BASE_HEX; } else { - tokline[line].op = strtoull(lexeme, NULL, 16); - tokline[line].opbase = BASE_HEX; + l[line].op = strtoull(lexeme, NULL, 16); + l[line].opbase = BASE_HEX; } break; @@ -609,27 +612,27 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j] = '\0'; switch (lex_type) { case TOK_SYM: - tokline[line].op = strtoull(lexeme, NULL, 2); - mksymbol(sym, tokline[line].op, 1, 0, 0, dbg); - tokline[line].sym = get_symid(sym, address, line, dbg); - isfixup += (tokline[line].sym == 0xFFFF); + l[line].op = strtoull(lexeme, NULL, 2); + mksymbol(sym, l[line].op, 1, 0, 0, dbg); + l[line].sym = get_symid(sym, address, line, dbg); + isfixup += (l[line].sym == 0xFFFF); if (dbg) { printf("lex(): isfixup: %u\n", isfixup); } - tokline[line].opbase = BASE_BIN; + l[line].opbase = BASE_BIN; break; case TOK_PLUS: case TOK_MINUS: - tokline[line].aop = strtoull(lexeme, NULL, 2); - tokline[line].aopbase = BASE_BIN; + l[line].aop = strtoull(lexeme, NULL, 2); + l[line].aopbase = BASE_BIN; break; default: - if (tokline[lineidx].cm != 0xFF) { - tokline[line].aop = strtoull(lexeme, NULL, 2); - tokline[line].aopbase = BASE_BIN; + if (l[lineidx].cm != 0xFF) { + l[line].aop = strtoull(lexeme, NULL, 2); + l[line].aopbase = BASE_BIN; } else { - tokline[line].op = strtoull(lexeme, NULL, 2); - tokline[line].opbase = BASE_BIN; + l[line].op = strtoull(lexeme, NULL, 2); + l[line].opbase = BASE_BIN; } break; @@ -639,20 +642,20 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { case '+': lexeme[j] = '+'; lexeme[j+1] = '\0'; - tokline[line].cm = 0; + l[line].cm = 0; lex_type = TOK_PLUS; break; case '-': lexeme[j] = '-'; lexeme[j+1] = '\0'; - tokline[line].cm = 1; + l[line].cm = 1; lex_type = TOK_MINUS; break; case '(': lexeme[j] = '('; lexeme[j+1] = '\0'; lexeme[j+2] = '\0'; - tokline[line].am = IND; + l[line].am = IND; break; case ')': i++; @@ -661,9 +664,9 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { while (isspace(str[i])) { lexeme[j++] = str[i++]; } - if (tokline[line].am == IND && tolower(str[i]) == 'y') { + if (l[line].am == IND && tolower(str[i]) == 'y') { lexeme[j++] = 'y'; - tokline[line].am = INDY; + l[line].am = INDY; } lexeme[j] = '\0'; } else { @@ -677,18 +680,18 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { while (isspace(str[i])) { lexeme[j++] = str[i++]; } - if (tokline[line].am == IND && tolower(str[i]) == 'x') { - tokline[line].am = INDX; + if (l[line].am == IND && tolower(str[i]) == 'x') { + l[line].am = INDX; lexeme[j++] = 'x'; i++; } else { switch (tolower(str[i])) { case 'x': - tokline[line].am = ZMX; + l[line].am = ZMX; lexeme[j++] = 'x'; break; case 'y': - tokline[line].am = ZMY; + l[line].am = ZMY; lexeme[j++] = 'y'; break; } @@ -700,13 +703,13 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j] = ':'; lexeme[j+1] = '\0'; lex_type = TOK_LABEL; - tokline[line].islabel = 1; + l[line].islabel = 1; mksymbol(sym, address, 1, 0, 0, dbg); if (isfixup) { - isfixup = reslv_fixups(dbg); + isfixup = reslv_fixups(l, dbg); } - tokline[line].sym = get_symid(sym, address, line, dbg); - isfixup += (tokline[line].sym == 0xFFFF); + l[line].sym = get_symid(sym, address, line, dbg); + isfixup += (l[line].sym == 0xFFFF); if (dbg) { printf("lex(): isfixup: %u\n", isfixup); } @@ -715,7 +718,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { i++; lexeme[j] = '='; lexeme[j+1] = 0; - tokline[line].issym = 1; + l[line].issym = 1; lex_type = TOK_SYM; break; case ';': @@ -726,20 +729,20 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j] = '\0'; comid = get_comment(lexeme, dbg); if (comid == 0xFFFF) { - if (line != lineidx && tokline[line].com != 0xFFFF) { - comid = tokline[line].com; + if (line != lineidx && l[line].com != 0xFFFF) { + comid = l[line].com; } else { comid = comidx; } comment[comid] = malloc(j+1); memcpy(comment[comid], lexeme, j+1); - tokline[line].com = comid; + l[line].com = comid; if (dbg) { printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]); } comidx += (line == lineidx); } else { - tokline[line].com = comid; + l[line].com = comid; if (dbg) { printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]); } @@ -780,7 +783,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { if (!strcasecmp(lexeme, mne[k])) { lex_type = TOK_OPCODE; isop = 1; - tokline[line].mne = k; + l[line].mne = k; address++; break; } @@ -823,30 +826,30 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { if (num) { switch (lex_type) { case TOK_SYM: - tokline[line].op = strtoull(lexeme, NULL, 10); - mksymbol(sym, tokline[line].op, 1, 0, 0, dbg); + l[line].op = strtoull(lexeme, NULL, 10); + mksymbol(sym, l[line].op, 1, 0, 0, dbg); if (isfixup) { - isfixup = reslv_fixups(dbg); + isfixup = reslv_fixups(l, dbg); } - tokline[line].sym = get_symid(sym, address, line, dbg); - isfixup += tokline[line].sym == 0xFFFF; + l[line].sym = get_symid(sym, address, line, dbg); + isfixup += l[line].sym == 0xFFFF; if (dbg) { printf("lex(): isfixup: %u\n", isfixup); } - tokline[line].opbase = BASE_DEC; + l[line].opbase = BASE_DEC; break; case TOK_PLUS: case TOK_MINUS: - tokline[line].aop = strtoull(lexeme, NULL, 10); - tokline[line].aopbase = BASE_DEC; + l[line].aop = strtoull(lexeme, NULL, 10); + l[line].aopbase = BASE_DEC; break; default: - if (tokline[lineidx].cm != 0xFF) { - tokline[line].aop = strtoull(lexeme, NULL, 10); - tokline[line].aopbase = BASE_DEC; + if (l[lineidx].cm != 0xFF) { + l[line].aop = strtoull(lexeme, NULL, 10); + l[line].aopbase = BASE_DEC; } else { - tokline[line].op = strtoull(lexeme, NULL, 10); - tokline[line].opbase = BASE_DEC; + l[line].op = strtoull(lexeme, NULL, 10); + l[line].opbase = BASE_DEC; } break; @@ -861,8 +864,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { printf("lex(): spaces: %u\n", spaces); } if (str[i+spaces] != ':' && str[i+spaces] != '=') { - tokline[line].sym = get_symid(lexeme, address, line, dbg); - isfixup += tokline[line].sym == 0xFFFF; + l[line].sym = get_symid(lexeme, address, line, dbg); + isfixup += l[line].sym == 0xFFFF; if (dbg) { printf("lex(): isfixup: %u\n", isfixup); } @@ -906,10 +909,10 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } if (lex_type == TOK_COMMENT) { if (!isstart) { - tokline[line].etab = tab; - tokline[line].espace = space; + l[line].etab = tab; + l[line].espace = space; if (dbg) { - printf("lex(): ending tabs: %u, ending spaces: %u\n", tokline[line].etab, tokline[line].espace); + printf("lex(): ending tabs: %u, ending spaces: %u\n", l[line].etab, l[line].espace); } } } @@ -919,7 +922,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } } if (i) { - address = update_addr(address, isfixup, line, dbg); + address = update_addr(l, address, isfixup, line, dbg); if (dbg) { printf("lex(): Next address: $%"PRIX64"\n", address); printf( @@ -936,26 +939,26 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { ", op: $%016"PRIX64 ", aop: $%016"PRIX64 ", ln: %u\n" - , tokline[line].addr - , tokline[line].dir - , tokline[line].mne - , tokline[line].rs - , tokline[line].am - , tokline[line].cm - , tokline[line].opbase - , tokline[line].com - , tokline[line].sym - , tokline[line].op - , tokline[line].aop + , l[line].addr + , l[line].dir + , l[line].mne + , l[line].rs + , l[line].am + , l[line].cm + , l[line].opbase + , l[line].com + , l[line].sym + , l[line].op + , l[line].aop , line); } if (ln > linenum || islinenum) { - tokline[line].linenum = ln; + l[line].linenum = ln; if (ln > linenum) { linenum+=(10+(ln & 10)); } } else if (!islinenum) { - tokline[line].linenum = linenum; + l[line].linenum = linenum; linenum += 10; } lineidx += (line == lineidx); @@ -4,7 +4,12 @@ #include <stdlib.h> #include <unistd.h> -#define OPNAME(opcode) [opcode] = #opcode /* Get name of Opcode, for disassembly. */ +#define bench 0 +#define debug 0 +#define IO 1 +#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. */ @@ -211,60 +216,6 @@ struct sux { }; enum {IMM, ZM, ZMX, ZMY, IND, INDX, INDY, ABS, IMPL}; -enum { - DIR_ORG, - DIR_BYTE, - DIR_WORD, - DIR_DWORD, - DIR_QWORD -}; - -enum { - TOK_DIR, - TOK_LABEL, - TOK_SYM, - TOK_PLUS, - TOK_MINUS, - TOK_STRING, - TOK_CHAR, - TOK_IMM, - TOK_OPCODE, - TOK_RS, - TOK_COMMENT, - TOK_HEX, - TOK_DEC, - TOK_BIN -}; - -enum { - BASE_HEX, - BASE_DEC, - BASE_BIN -}; - - -static const uint8_t adrsize[8] = { - [0] = 0, - [1] = 2, - [2] = 5, - [3] = 3, - [4] = 1, - [5] = 4, - [6] = 6, - [7] = 7 -}; - -static const char *adrmode[9] = { - [IMM ] = "IMM", - [ZM ] = "ZM", - [ZMX ] = "ZMX", - [ZMY ] = "ZMY", - [IND ] = "IND", - [INDX] = "INDX", - [INDY] = "INDY", - [ABS ] = "ABS", - [IMPL] = "IMPL" -}; static const uint8_t optype[0x100] = { [0x00] = IMPL, @@ -454,192 +405,7 @@ static const uint8_t optype[0x100] = { [0xFE] = IMPL }; -static const char *mne[OPNUM] = { - [ 0] = "CPS", - [ 1] = "ADC", - [ 2] = "AAB", - [ 3] = "PHP", - [ 4] = "CPB", - [ 5] = "PHB", - [ 6] = "DEC", - [ 7] = "JMP", - [ 8] = "SBC", - [ 9] = "SAB", - [10] = "ENT", - [11] = "CPY", - [12] = "PLB", - [13] = "INC", - [14] = "JSR", - [15] = "JSL", - [16] = "AND", - [17] = "ABA", - [18] = "PLP", - [19] = "CPX", - [20] = "PHY", - [21] = "BPO", - [22] = "ORA", - [23] = "OAB", - [24] = "STT", - [25] = "PLY", - [26] = "BNG", - [27] = "XOR", - [28] = "XAB", - [29] = "PHA", - [30] = "PHX", - [31] = "BCS", - [32] = "LSL", - [33] = "LLB", - [34] = "CLC", - [35] = "PLX", - [36] = "BCC", - [37] = "LSR", - [38] = "LRB", - [39] = "PLA", - [40] = "TAB", - [41] = "BEQ", - [42] = "ROL", - [43] = "RLB", - [44] = "SEC", - [45] = "TBA", - [46] = "BNE", - [47] = "ROR", - [48] = "RRB", - [49] = "DEY", - [50] = "TAY", - [51] = "BVS", - [52] = "MUL", - [53] = "MAB", - [54] = "CLI", - [55] = "TYA", - [56] = "BVC", - [57] = "DIV", - [58] = "DAB", - [59] = "INY", - [60] = "TAX", - [61] = "RTS", - [62] = "RTL", - [63] = "CMP", - [64] = "CAB", - [65] = "SEI", - [66] = "LDX", - [67] = "TXA", - [68] = "RTI", - [69] = "LDA", - [70] = "DEX", - [71] = "CLV", - [72] = "TYX", - [73] = "STA", - [74] = "TSX", - [75] = "LDB", - [76] = "INX", - [77] = "WAI", - [78] = "TXY", - [79] = "STB", - [80] = "TXS", - [81] = "LDY", - [82] = "BRK", - [83] = "NOP", - [84] = "STY", - [85] = "DEB", - [86] = "ASR", - [87] = "ARB", - [88] = "STX", - [89] = "INB" -}; - -static const char *instdesc[OPNUM] = { - [ 0] = "Clears the Processor Status register.", - [ 1] = "ADd accumulator, with operand, Carry if needed.", - [ 2] = "Add Accumulator, with B, carry if needed.", - [ 3] = "PusH the number of bytes specified, from the Processor status register to the stack.", - [ 4] = "ComPare the B register, with operand.", - [ 5] = "PusH the number of bytes specified, from the B register to the stack.", - [ 6] = "DECrement accumulator, or memory.", - [ 7] = "JuMP to the address specified.", - [ 8] = "SuBtract accumulator, with operand, Carry if needed", - [ 9] = "Subtract Accumulator, with B, carry if needed.", - [10] = "ENd a Thread.", - [11] = "ComPare the Y register, with operand.", - [12] = "PuLl the number of bytes specified, from the stack, to the B register.", - [13] = "INCrement accumulator, or memory.", - [14] = "Jump to a SubRoutine.", - [15] = "Jump to a Subroutine, Long address.", - [16] = "Bitwise AND accumulator, with operand.", - [17] = "Bitwise AND Accumulator, with B.", - [18] = "PuLl the number of bytes specified, from the stack, to the Processor status register.", - [19] = "ComPare the X register, with operand.", - [20] = "PusH the number of bytes specified, from the Y register to the stack.", - [21] = "Branch if POsitive.", - [22] = "Bitwise OR Accumulator, with operand.", - [23] = "Bitwise OR Accumulator, with B.", - [24] = "STart a Thread.", - [25] = "PuLl the number of bytes specified, from the stack, to the Y register.", - [26] = "Branch if NeGative.", - [27] = "Bitwise XOR Accumulator, with operand.", - [28] = "Bitwise XOR Accumulator, with B.", - [29] = "PusH the number of bytes specified, from the Accumulator to the stack.", - [30] = "PusH the number of bytes specified, from the X register to the stack.", - [31] = "Branch if the Carry flag is Set.", - [32] = "Logical Shift Left accumulator, with operand.", - [33] = "Logical Shift Left accumulator, with B.", - [34] = "CLear the Carry flag.", - [35] = "PuLl the number of bytes specified, from the stack, to the X register.", - [36] = "Branch if the Carry flag has been Cleared.", - [37] = "Logical Shift Right accumulator, with operand.", - [38] = "Logical Shift Right accumulator, with B.", - [39] = "PuLl the number of bytes specified, from the stack, to the Accumulator.", - [40] = "Transfer the value from the Accumulator, to the B register.", - [41] = "Branch if EQual (the zero flag has been set).", - [42] = "ROtate Left accumulator, with operand.", - [43] = "Rotate Left accumulator, with B.", - [44] = "SEt the Carry flag.", - [45] = "Transfer the value from the Y register, to the Accumulator.", - [46] = "Branch if Not Equal (the zero flag has been cleared)", - [47] = "ROtate Right accumulator, with operand.", - [48] = "Rotate Right accumulator, with B.", - [49] = "DEcrement the Y register.", - [50] = "Transfer the value from the Accumulator, to the Y register.", - [51] = "Branch if the oVerflow flag is Set.", - [52] = "MULtiply accumulator, with operand.", - [53] = "Multiply Accumulator, with B.", - [54] = "CLear the Interrupt flag.", - [55] = "Transfer the value from the Y register, to the Accumulator.", - [56] = "Branch if the oVerflow flag has been Cleared.", - [57] = "DIVide accumulator, with operand, and put the remainder into the B register.", - [58] = "Divide Accumulator, with B, and put the remainder into the X register.", - [59] = "INcrement the Y register.", - [60] = "Transfer the value from the Accumulator, to the X register.", - [61] = "ReTurn from a Subroutine.", - [62] = "ReTurn from subroutine, Long address.", - [63] = "CoMPare acumulator, with operand.", - [64] = "Compare Accumulator, with B.", - [65] = "SEt the Interrupt flag.", - [66] = "LoaD the value from the operand, to the X register.", - [67] = "Transfer the value from the X register, to the Accumulator.", - [68] = "ReTurn from an Interrupt.", - [69] = "LoaD the value from the operand, to the Accumulator.", - [70] = "DEcrement the X register.", - [71] = "CLear the oVerflow flag.", - [72] = "Transfer the value from the Y register, to the X register.", - [73] = "STore the value from the Accumulator, in memory.", - [74] = "Transfer the value from the Stack pointer, to the X register.", - [75] = "LoaD the value from the operand, to the B register.", - [76] = "INcrement the X register.", - [77] = "WAIt for an interrupt", - [78] = "Transfer the value from the X register, to the Y register.", - [79] = "STore the value from the B register, in memory.", - [80] = "Transfer the value from the X register, to the Stack pointer.", - [81] = "LoaD the value from the operand, to the Y register.", - [82] = "BReaKpoint", - [83] = "NO oPeration", - [84] = "STore the value from the Y register, in memory.", - [85] = "DEcrement the B register.", - [86] = "Arithmetic Shift Right accumulator, with operand.", - [87] = "Arithmetic shift Right accumulator, with B.", - [88] = "STore the value from the X register, in memory.", - [89] = "INcrement the B register." -}; - +#if debug static const char *opname[0x100] = { [0x00] = "CPS", [0x01] = "ADC #", @@ -827,5 +593,6 @@ static const char *opname[0x100] = { [0xFD] = "STX zm", [0xFE] = "INB" }; +#endif extern int asmmon(); diff --git a/programs/subeditor.s b/programs/subeditor.s index 8eec46a..1842b5a 100644 --- a/programs/subeditor.s +++ b/programs/subeditor.s @@ -35,6 +35,13 @@ bits: .byte $02 .byte $01 + +; Linewrap table. +.org $1000 +bitabl: + .qword 0 + .qword 0 + ; Input buffer. .org $2000 buffer: @@ -43,7 +50,7 @@ buffer: cmd_buf: -; Initalize some variables. +; Screen variables. .org 0 scr_row: .byte 0 @@ -57,7 +64,10 @@ scr_ptr: .word 0 scr_ptr2: .word 0 -; Registers. +scr_ptr3: + .word 0 + +; Pseudo registers. a: .byte 0 b: @@ -70,17 +80,17 @@ e: .byte 0 f: .byte 0 -; This register is always zero. +g: + .byte 0 +; This pseudo register is always zero. zero: .qword 0 -; End of registers. +; End of pseudo registers. + end: - .byte 0 + .word 0 bitmask: .byte 0 -bitabl: - .qword 0 - .qword 0 scr_str: .byte 0 scr_end: @@ -95,16 +105,6 @@ ptr2: .qword 0 ptr3: .qword 0 -ptr4: - .qword 0 -ptr5: - .qword 0 -ptr6: - .qword 0 -scr_ptr3: - .word 0 -g: - .byte 0 ; Main program .org $8000 @@ -117,84 +117,63 @@ reset: tyx ; Reset the X register. lda #maxrow ; Set the end of the screen to the screen's max row count. sta scr_end ; - lda.w #buffer ; Place the address for the screen buffer - sta.q ptr5 ; into one of the pointers. - lda.w #cmd_buf ; Place the address for the command buffer - sta.q ptr6 ; into one of the pointers. tya ; Reset the Accumulator. sta scr_str ; Set the start of the screen back to zero. sta.q bitabl ; Reset the first half of the linewrap table. sta.q bitabl+8 ; Reset the second half of the linewrap table. inc end ; - jsl clr_buf ; Clear the screen buffer. + lda.w #$1FFF ; Set the clear count to $1FFF. + sta.w scr_ptr ; + 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_buf: +clr_arr: phb #1 ; Preserve whatever was in B. ldb #0 ; Clear B. - lda.w #buffer+8 ; - sta.q ptr4 ; + jsl 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. + jsl set_ptr ; + deb ; Set B back to zero. tba ; -clr_buf_st: - cpy.w #$1FFF ; Did we clear all of the screen buffer? - bcs clr_buf_end ; Yes, so we're done. - sta.q (ptr5), y ; No, so clear eight bytes. - sta.q (ptr4), y ; Clear eight more bytes. - tya ; Copy the buffer index. +clr_arr_st: + cpy.w scr_ptr ; Did we clear all of the array? + bcs clr_arr_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 (ptr5), y ; Do this one more time, to clear 32 bytes. - sta.q (ptr4), y ; + sta.q (ptr), y ; Do this one more time, to clear 32 bytes. + sta.q (ptr2), y ; tya ; adc #$10 ; tay ; tba ; - jmp clr_buf_st ; Keep looping. -clr_buf_end: + jmp clr_arr_st ; Keep looping. +clr_arr_end: ldy.w zero ; Set the index back to zero. plb #1 ; Get whatever was in the B register, back. - rtl ; End of clr_buf. + rtl ; End of clr_arr. start: lda #0 ; TODO: Update this for the Super VIA. - sta status ; Clear the controll register of the I/O adapter. + sta status ; Clear the control register of the I/O adapter. tax ; Reset X. phy #2 ; Save the cursor index for later. tay ; Reset the cursor index. - jsl clr_cbuf ; Clear the command buffer. + lda.w #$3FF ; Set the clear count to $3FF. + sta.w scr_ptr ; + lda.w #cmd_buf ; Set the array to be cleared to the command buffer. + jsl clr_arr ; Clear the command buffer. ply #2 ; Get back the cursor index. lda.w #string ; Print the startup message. jsl print_str ; - lda.w zero ; Reset the Accumulator. + lsr #$10 ; Reset the Accumulator. sta end ; jmp read ; Start reading the keyboard. -clr_cbuf: - phb #1 ; Start of callee preservation. - ldb #0 ; Reset the B register. - lda.w #cmd_buf+8; Place the address of the command buffer, plus eight - sta.q ptr4 ; into the fourth pointer. - tba ; Set the Accumulator back to zero. -clr_cbuf_st: - cpy.w #$3FF ; Did we clear all of the command buffer? - bcs clr_cbuf_nd ; Yes, so we're done. - sta.q (ptr6), y ; No, so clear eight bytes. - sta.q (ptr4), y ; Clear eight more bytes. - tya ; Copy the buffer index. - adc #$10 ; Increment the index by 16. - tay ; Update the index. - tba ; Reset the Accumulator. - sta.q (ptr6), y ; Do this one more time, to clear 32 bytes. - sta.q (ptr4), y ; - tya ; - adc #$10 ; - tay ; - tba ; - jmp clr_cbuf_st ; Keep looping. -clr_cbuf_nd: - plb #1 ; End of callee preservation. - rtl ; End of clr_cbuf. - read: lda #0 ; Reset the Accumulator. sta end ; Disable the dummy flag. @@ -206,12 +185,19 @@ read: jmp read ; No, so keep looping. print_str: - sta.q ptr ; Place the string pointer into the main pointer. + sta.w end ; Save the parameter. +print_str2: + lda.w end ; Get the parameter. ldb #0 ; Clear the B register. + jsl set_ptr ; Set the first pointer to the parameter. tba ; Clear the Accumulator. inb ; Enable replace mode. stb b ; pntstr_lp: + lda.w ptr ; Get the first pointer. + cmp.w end ; Did the pointer change? + bne print_str2 ; Yes, so set it back. + lsr #$10 ; No, reset the accumulator. phy #2 ; Save the cursor index. txy ; Copy the string index into Y. lda (ptr), y ; Are we at the end of the string? @@ -236,34 +222,61 @@ getbt0: adc scr_str ; Add the screen offset to it. tax ; Use it as the wrap index. getbt1: + pha #1 ; Save the parameter. + ldb #1 ; Make sure that set_ptr sets the second pointer. + lda.w #bitabl ; Set the second pointer to the linewrap table. + jsl set_ptr ; + lsr #$10 ; Clear the Accumulator. + pla #1 ; Get the return byte back. jsl bitpos ; Get the bit, and byte position. - ldb bitabl, x ; Get one byte of the wrap table. + phy #2 ; Save the screen index. + txy ; Get the byte position. + ldb (ptr2), y ; Get one byte of the wrap table. + ply #2 ; Get the screen index back. aba ; Mask out the bit of the current line number. cmp #1 ; Set the carry flag, if true. jmp bitout ; We are done. clrbit: + pha #1 ; Save the parameter. + ldb #1 ; Make sure that set_ptr sets the second pointer. + lda.w #bitabl ; Set the second pointer to the linewrap table. + jsl set_ptr ; + lsr #$10 ; Clear the Accumulator. + pla #1 ; Get the return byte back. jsl bitpos ; Get the bit, and byte position. xor #$FF ; Invert the bitmask. - ldb bitabl, x ; Get one byte of the wrap table. + phy #2 ; Save the screen index. + txy ; Get the byte position. + ldb (ptr2), y ; Get one byte of the wrap table. aba ; Clear the bit of the current line number. bitsav: - sta bitabl, x ; Update the wrap table. + sta (ptr2), y ; Update the wrap table. + ply #2 ; Get the screen index back. bitout: ldx bitmask ; Return the bitmask. rtl ; We are done. setbit: + pha #1 ; Save the parameter. + ldb #1 ; Make sure that set_ptr sets the second pointer. + lda.w #bitabl ; Set the second pointer to the linewrap table. + jsl set_ptr ; + lsr #$10 ; Clear the Accumulator. + pla #1 ; Get the return byte back. jsl bitpos ; Get the bit, and byte position. - ldb bitabl, x ; Get one byte of the wrap table. + phy #2 ; Save the screen index. + txy ; Get the byte position. + ldb (ptr2), y ; Get one byte of the wrap table. oab ; Set the bit of the current line number. jmp bitsav ; Save the bit. bitpos: pha #1 ; Save the parameter. - lda.w #bits ; Place the address of the bitmask table, - sta.q ptr3 ; in the third pointer. - lda.w zero ; Clear the Accumulator. + ldb #0 ; Make sure that set_ptr sets the first pointer. + lda.w #bits ; Set the first pointer to the bitmask table. + jsl set_ptr ; + lsr #$10 ; Clear the Accumulator. pla #1 ; Get the parameter back. stx bitmask ; Make the line number the bitmask. txa ; Copy it to the Accumulator. @@ -271,7 +284,7 @@ bitpos: phy #2 ; Save the cursor index. tay ; Use the bit position as the index. tax ; Copy it into X. - lda (ptr3), y ; Get the bitmask. + lda (ptr), y ; Get the bitmask. ply #2 ; Get back the cursor index. pha #1 ; Save the bitmask. lda bitmask ; Get the line number. @@ -288,7 +301,8 @@ getchar: pha #1 ; Save the character. phy #2 ; Save the cursor index. cmp #10 ; Was the character that was typed, a newline? - beq cmd_cpy ; Yes, so start copying the line to the command buffer. + bne getchar_pnt ; No, so just print the character. + jsl cmd_cpy ; Yes, so start copying the line to the command buffer. getchar_pnt: ply #2 ; Get back the cursor index. pla #1 ; Get back the character. @@ -311,10 +325,26 @@ reset_row1: reset_row2: stb scr_row ; Set the row position. jmp getchar_pt1 ; Print the character. +getchar_ln: + lda #0 ; Return zero. + jmp getchar_end ; We are done. +getchar_chr: + lda #1 ; Return one. +getchar_end: + rtl ; End of get char. + + cmd_cpy: lda scr_row ; Get the row position. sta scr_trow ; Save it for later. jsl findend ; Find the end of the line. + ldb scr_str ; Has the screen been scrolled? + beq cmd_cpy3 ; No, so don't subtract the screen's starting point from the line number. +cmd_cpy2: + sec ; Yes, so make sure that we don't subtract by the starting point, plus one. + sbc scr_str ; Offset the row position, back by the screen's starting point. + clc ; Clear the carry flag, so that nothing odd occurs. +cmd_cpy3: sta scr_row ; Set the row position to the end of the line. sta e ; Save it into the temporary row posiition. jsl findst ; Find the start of the line. @@ -324,13 +354,21 @@ cmd_cpy: mul #maxcol+1 ; Multiply it with the width of the screen, plus one. tay ; Place it into the index. ldx.w #0 ; Reset the X register. + ldb #0 ; Make sure that set_ptr sets the first pointer. + lda.w #buffer ; Set the first pointer to the start of the screen buffer. + jsl set_ptr ; + inb ; Make sure that set_ptr sets the second pointer. + lda.w #cmd_buf ; Set the second pointer to the start of the command buffer. + jsl set_ptr ; + deb ; Set B back to zero. + tba ; Set the accumulator to zero. cmd_cpy_lp: ldb #0 ; Reset the B register. - lda.q (ptr5), y ; Get eight bytes from the current line. + lda.q (ptr), y ; Get eight bytes from the current line. cmd_cpy_lp1: phy #2 ; Save the screen index. txy ; Get the command buffer index. - sta (ptr6), y ; Copy one byte from the screen buffer, to the command buffer. + 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. @@ -347,14 +385,10 @@ cmd_cpy_lp1: jmp cmd_cpy_lp1 ; No, so keep shifting in more bytes. cmd_cpy_nd: tab ; The B register is zero, so clear the Accumulator. - jmp getchar_pnt ; Go back to printing the character. -getchar_ln: - lda #0 ; Return zero. - jmp getchar_end ; We are done. -getchar_chr: - lda #1 ; Return one. -getchar_end: - rtl ; End of get char. + rtl ; End of cmd_cpy. + + + findst: lda #0 ; @@ -373,9 +407,15 @@ findst_done: rtl ; fndend: + phb #1 ; Save the contents of the B register. + ldb #0 ; Make sure that set_ptr sets the first pointer. + lda.w #buffer ; Set the first pointer to the start of the screen buffer. + jsl set_ptr ; + tba ; Set the Accumulator to zero. + plb #1 ; Restore the contents of the B register. phy #2 ; fndend_lp: - lda (ptr5), y ; Are we at the end of the string? + lda (ptr), y ; Are we at the end of the string? beq fndend_done ; Yes, so we're done. iny ; No, so increment the cursor index. jmp fndend_lp ; Keep looping. @@ -400,26 +440,31 @@ parse: jmp result ; print_char: - sta a ; - cmp #$1B ; - beq esc ; - cmp #10 ; - beq nl ; Did the user type a newline? - cmp #$C ; - beq clr_scr ; - cmp #19 ; - beq en_step ; - cmp #18 ; - beq dis_step ; - cmp #8 ; - beq bs ; Did the user type a backspace? - cmp #$7F ; - beq bs ; Did the user type a backspace? - sta a ; + sta a ; Save the typed character for now. + ldb #2 ; Make sure that set_ptr sets the third pointer. + lda.w #buffer ; Set the third pointer to the start of the screen buffer. + jsl set_ptr ; + ldb #0 ; Set B to zero. + tba ; Set the Accumulator to zero. + lda a ; Get back the character. + cmp #$1B ; Did the user type an escape character? + beq esc ; Yes, so go check the escape code. + cmp #10 ; No, but did the user type a newline? + beq nl ; Yes, so handle the newline. + cmp #$C ; No, but did the user type Ctrl+L? + beq clr_scr ; Yes, so clear the screen. + cmp #19 ; No, but did the user type Ctrl+S? + beq en_step ; Yes, so enable clock/instruction stepping. + cmp #18 ; No, but did the user type Ctrl+R? + beq dis_step ; Yes, so disable clock/instruction stepping. + cmp #8 ; No, but did the user type a backspace? + beq bs ; Yes, so handle the backspace. + cmp #$7F ; No, but did they type Delete? + beq bs ; Yes, so treat it as a backspace. printc: - lda #0 ; + lda #0 ; No, so start trying to print a character. sta d ; - lda (ptr5), y ; Are we at the end of the string? + lda (ptr3), y ; Are we at the end of the string? beq printc_save ; Yes, so just print the character. lda b ; No, but was the flag set? bne printc_save ; Yes, so don't shift the line. @@ -456,7 +501,7 @@ prntc_movln: ldb #1 ; stb d ; lda a ; - sta (ptr5), y ; store typed character into the input buffer. + sta (ptr3), y ; store typed character into the input buffer. lda scr_row ; sta scr_trow ; jmp prntc_updt ; @@ -465,7 +510,7 @@ printc_save: bne prntc_updt ; printc_sav1: lda a ; - sta (ptr5), y ; store typed character into the input buffer. + sta (ptr3), y ; store typed character into the input buffer. printc_inc: inc scr_col ; Increment the cursor's x coordinate. iny ; @@ -517,9 +562,9 @@ printc_end: nl: lda #0 ; - ldb (ptr5), y ; + ldb (ptr3), y ; bne nl1 ; - sta (ptr5), y ; Store said terminator into the input buffer. + sta (ptr3), y ; Store said terminator into the input buffer. nl1: sta scr_col ; lda scr_row ; @@ -544,9 +589,15 @@ clr_scr: sta.q bitabl ; sta.q bitabl+8 ; tay ; - jsl clr_buf ; + lda.w #$1FFF ; Set the clear count to $1FFF. + sta.w scr_ptr ; + lda.w #buffer ; Set the array to be cleared to the command buffer. + jsl clr_arr ; Clear the screen buffer. tay ; - jsl clr_cbuf ; + lda.w #$3FF ; Set the clear count to $3FF. + sta.w scr_ptr ; + lda.w #buffer ; Set the array to be cleared to the command buffer. + jsl clr_arr ; Clear the screen buffer. sta scr_col ; sta scr_row ; jsl update_pos ; @@ -589,7 +640,7 @@ back0: back1: dey ; Decrement the buffer's offset. lda #0 ; Place a null terminator - sta (ptr5), y ; into the buffer. + sta (ptr3), y ; into the buffer. tyx ; Copy the current cursor index to X. iny ; Increment cursor index. ldb #0 ; @@ -646,7 +697,6 @@ backwrp: tax ; Transfer that into X. backwrp2: dec scr_row ; Move up by one row. -; jsl clrbit ; Clear the wrap bit for this row. ldb #maxcol+1 ; Move the cursor to the absolute right of the screen. stb scr_col ; jsl update_pos ; Update the cursor's position. @@ -659,7 +709,7 @@ shftln: jmp shftln_lp0 ; No, so shift, and increment. shftln_neg: ldy.w zero ; Set the source poition to 0. - stb (ptr5), y ; Clear the character that is in the source. + stb (ptr3), y ; Clear the character that is in the source. jmp shftln_end ; We are done. shftln_lp0: sty.w scr_ptr2 ; Save the source position for later. @@ -669,26 +719,26 @@ shftln_lp0: bcs shftln_end ; No, so we're done. shftln_lp01: ldy.w scr_ptr2 ; Get the source position. - lda (ptr5), y ; Get the character from the source position. + lda (ptr3), y ; Get the character from the source position. phy #2 ; Save the source position for later. txy ; Set our position to the destination. - sta (ptr5), y ; Place the character from the source position, to the destination position. + sta (ptr3), y ; Place the character from the source position, to the destination position. ply #2 ; Set our position back to the source. - stb (ptr5), y ; Clear the character that is in the source. + stb (ptr3), y ; Clear the character that is in the source. bng shftln_neg ; The source underflowed, so set it back to zero, dey ; Decrement the source position. dex ; Decrement the destination position. jmp shftln_lp0 ; Keep looping. shftln_lp1: stx.w scr_ptr2 ; Save the destination position for later. - lda (ptr5), y ; Is the character at the source position, a null terminator? + lda (ptr3), y ; Is the character at the source position, a null terminator? beq shftln_end1 ; Yes, so we're done. phy #2 ; No, so save the source position for later. txy ; Set our position to the destination. - sta (ptr5), y ; Place the character from the source position, to the destination position. + sta (ptr3), y ; Place the character from the source position, to the destination position. inx ; Increment the destination position. ply #2 ; Set our position back to the source. - stb (ptr5), y ; Clear the character that is in the source. + stb (ptr3), y ; Clear the character that is in the source. iny ; Increment the source position. jmp shftln_lp1 ; Keep looping. shftln_wrap: @@ -700,18 +750,18 @@ shftln_wrp1: jsl clrbit ; Clear the wrap bit of the ending line. jmp shftln_end2 ; We are done. shftln_end: - lda (ptr5), y ; Is this character a null terminator? + lda (ptr3), y ; Is this character a null terminator? bne shftln_nd0 ; No, so just find the end of the line. lda #$20 ; Yes, so convert it to a space for now. - sta (ptr5), y ; + sta (ptr3), y ; shftln_nd0: jsl findend ; Find the ending line. sta d ; Save ending line for later. - lda (ptr5), y ; Is this character a space? + lda (ptr3), y ; Is this character a space? cmp #$20 ; bne shftln_nd1 ; No, so skip the conversion. lda #0 ; Yes, so convert it back to zero. - sta (ptr5), y ; + sta (ptr3), y ; shftln_nd1: lda d ; Get the ending line. cmp scr_row ; Is the ending line greater than the starting line? @@ -1068,12 +1118,12 @@ rdrw_row: sta scr_col ; jsl update_pos ; rdrow_st: - lda (ptr5), y ; + lda (ptr3), y ; beq rdrow_inc ; sta scr ; rdrow_inc: inc scr_col ; - lda (ptr5), y ; + lda (ptr3), y ; beq rdrow_skip ; rdrow_inc1: iny ; @@ -1103,18 +1153,22 @@ rset_x: jmp print_buf ; Print the input buffer. dabbed: - ldb #0 ; - lda.w #tok ; - sta.q ptr2 ;i - tba ; + ldb #0 ; Make sure that set_ptr is setting the first pointer. + lda.w #cmd_buf ; Set the first pointer to the start of the command buffer. + jsl set_ptr ; + inb ; Make set_ptr set the second pointer. + lda.w #tok ; Set the second pointer to the start of the token string. + jsl set_ptr ; + deb ; Set B back to zero. + tba ; Also set the accumulator back to zero. dab_st: phy #2 ; txy ; - lda (ptr6), y ; Get a character from the input buffer. - beq dab_pend ; Are we done with printing the buffer? - cmp (ptr2), y ; - beq chk_str ; - jmp dab_pend ; + lda (ptr), y ; Are we at the end of the string? + beq dab_pend ; Yes, so return false. + cmp (ptr2), y ; No, but is this character the same as the character in the token string? + beq chk_str ; Yes, so increment the character count. + jmp dab_pend ; No, so return false. chk_str: ply #2 ; inx ; @@ -1124,7 +1178,6 @@ chk_str: pnt_msg: lda.w #msg ; ldx #0 ; - stx.q ptr ; jsl print_str ; jmp dab_peqnd ; dab_pend: @@ -1140,7 +1193,7 @@ dab_end: print_buf: lda.w #cmd_buf ; jsl print_str ; - lda.w zero ; + lsr #$10 ; Clear the Accumulator. cmd_clr: lda #10 ; jsl print_char ; @@ -1175,6 +1228,21 @@ rdrwln_done: sta f ; rtl ; +set_ptr: + cpb #1 ; Are we setting the second pointer? + beq set_ptr2 ; Yes, so start setting it. + cpb #2 ; No, but are we setting the third pointer? + beq set_ptr3 ; Yes, so start setting it. +set_ptr1: + sta.q ptr ; No, so set the first pointer. + jmp setptr_end ; We are done. +set_ptr2: + sta.q ptr2 ; Set the second pointer. + jmp setptr_end ; We are done. +set_ptr3: + sta.q ptr3 ; Set the third pointer. +setptr_end: + rtl ; End of set_ptr. .org $FFC0 .qword reset @@ -3,11 +3,7 @@ #include <ctype.h> #include <string.h> #include <pthread.h> -#define bench 0 -#define debug 0 -#define IO 1 -#define getclk 0 -#define keypoll 0 + #if bench #include <sys/time.h> #else @@ -31,8 +27,19 @@ uint64_t tclk; /* Total Clock cycles. */ #endif const uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */ + +#if !IO uint64_t inst[THREADS]; +#endif + +#if debug +uint8_t subdbg = 0; +#endif + +#if bench uint64_t inss; +#endif + uint8_t threads_done = 0; uint8_t kbd_rdy = 0; uint8_t step = 0; @@ -41,6 +48,7 @@ uint8_t step = 0; #if !bench WINDOW *scr; #endif + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; @@ -69,7 +77,9 @@ void *run(void *args) { #if getclk uint64_t iclk = 0; #endif + #if !IO uint64_t ins = 0; + #endif uint8_t sign = 0; uint8_t tmp; uint8_t tmp2; @@ -84,11 +94,12 @@ void *run(void *args) { gettimeofday(&str[thread], 0); #endif #if debug && !bench - uint8_t scr_row = 0xFF, scr_col = 0xFF; - uint8_t updt = 0; uint64_t tmpaddr = 0; - addr[STEP_ADDR] = 1; - step = 1; + uint16_t scr_col = 0; + if (!subdbg) { + addr[STEP_ADDR] = 1; + step = 1; + } #if keypoll pthread_mutex_lock(&mutex); #endif @@ -350,61 +361,77 @@ void *run(void *args) { break; } - if (updt) { - mvwprintw(scr, 27, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]); - mvwprintw(scr, 28, 0, "scr_ptr3: $%04X", (addr[0x5C] << 8) | addr[0x5B]); - mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x28], addr[0x29]); - mvwprintw(scr, 32, 0, "bitabl: %02X %02X %02X %02X %02X %02X %02X %02X " - "%02x %02x %02x %02x %02x %02x %02x %02x\r" - , addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D], addr[0x1E], addr[0x1F] - , addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25], addr[0x26], addr[0x27]); + if (address == TX_ADDR || address == RX_ADDR) { + wmove(scr, 27, 0); + wprintw(scr, "TX_ADDR: $%02X, RX_ADDR: $%02X", addr[TX_ADDR], addr[RX_ADDR]); } - uint8_t ln = 33; - uint16_t line_idx = 0; - uint16_t tmpad = 0x2000; - int row, col; - uint8_t iscursor = 0; - mvwprintw(scr, ln++, 0, "buffer:\r"); - if (updt) { - scr_row = addr[0]; - scr_col = addr[1]; - wmove(scr, ln++, 0); - for (uint8_t i = 0; i < 10; i++) { - line_idx = (i << 6) + (i << 4); - for (uint8_t j = 0; j < 0x50; j++) { - wprintw(scr, "%02X", addr[tmpad+j+line_idx]); - if ((addr[0]+addr[0x28]) == i && addr[1] == j) { - iscursor=1; - getyx(scr,row, col); - wmove(scr, ln++, 0); - wclrtoeol(scr); - wmove(scr, row+1, col-2); - wprintw(scr, "/\\\r"); - wmove(scr, row, col); - } - } - wprintw(scr, ", i: %02X\r", i); - if (!iscursor) { - wmove(scr, ln, 0); - wclrtoeol(scr); - } - iscursor = 0; + if (subdbg) { + uint8_t ln = 33; + uint16_t line_idx = 0; + uint16_t tmpad = 0x2000; + int row, col; + uint8_t iscursor = 0; + uint64_t ptr; + uint8_t adr; + wmove(scr, 30, 0); + adr = 0x1F; + ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 | + (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38; + wprintw(scr, "ptr1: $%04"PRIX64, ptr); + adr = 0x27; + ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 | + (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38; + wprintw(scr, ", ptr2: $%04"PRIX64, ptr); + adr = 0x2F; + ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 | + (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38; + wprintw(scr, ", ptr3: $%04"PRIX64, ptr); + if (address == CTRL_ADDR || addr[STEP_ADDR]) { + mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x1C], addr[0x1D]); + mvwprintw(scr, 32, 0, "bitabl: %02X%02X%02X%02X%02X%02X%02X%02X" + "%02X%02X%02X%02X%02X%02X%02X%02X" + , addr[0x1000], addr[0x1001], addr[0x1002], addr[0x1003], addr[0x1004], addr[0x1005], addr[0x1006], addr[0x1007] + , addr[0x1008], addr[0x1009], addr[0x100A], addr[0x100B], addr[0x100C], addr[0x100D], addr[0x100E], addr[0x100F]); + mvwprintw(scr, ln++, 0, "buffer:\r"); wmove(scr, ln++, 0); + for (uint8_t i = 0; i < 10; i++) { + line_idx = (i << 6) + (i << 4); + for (uint8_t j = 0; j < 0x50; j++) { + wprintw(scr, "%02X", addr[tmpad+j+line_idx]); + if ((addr[0]+addr[0x1C]) == i && addr[1] == j) { + iscursor=1; + getyx(scr,row, col); + wmove(scr, ln++, 0); + wclrtoeol(scr); + wmove(scr, row+1, col-2); + wprintw(scr, "/\\\r"); + wmove(scr, row, col); + } + } + wprintw(scr, ", i: %02X", i); + if (!iscursor) { + wmove(scr, ln, 0); + wclrtoeol(scr); + } + iscursor = 0; + wmove(scr, ln++, 0); + } } - updt = 0; + /*if (address == 0x4000 || tmpaddr == 0x4000 || addr[STEP_ADDR]) { + ln = 46; + tmpad = 0x4000; + line_idx = 0; + mvwprintw(scr, ln++, 0, "cmd_buf:"); + for (uint8_t i = 0; i < 5; i++) { + wmove(scr, ln++, 0); + line_idx = (i << 4)+(i << 6); + for (uint8_t j = 0; j < 0x50; j++) { + wprintw(scr, "%02X", addr[tmpad+j+line_idx]); + } + wprintw(scr, ", i: %02X", i); + } + }*/ } - /*ln = 45; - tmpad = 0x4000; - line_idx = 0; - mvwprintw(scr, ln++, 0, "cmd_buf:\r"); - for (uint8_t i = 0; i < 5; i++) { - wmove(scr, ln++, 0); - line_idx = (i << 4)+(i << 6); - for (uint8_t j = 0; j < 0x50; j++) { - wprintw(scr, "%02X", addr[tmpad+j+line_idx]); - } - wprintw(scr, ", i: %02X\r", i); - }*/ #if keypoll pthread_mutex_unlock(&mutex); #endif @@ -668,8 +695,19 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif + #if debug + if (!subdbg) { + scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0; + wmove(scr, 28, scr_col); + } + #endif if (esc) { - switch(addr[TX_ADDR]) { + #if debug + if (!subdbg && addr[RX_ADDR] == '\n') { + wclrtoeol(scr); + } + #endif + switch (addr[TX_ADDR]) { case 'A': if (y > 0) y--; @@ -716,9 +754,8 @@ void *run(void *args) { #if !debug wmove(scr, y, x); #else - updt = 1; mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y); - mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]); + /*mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);*/ #endif idx = 3; bcd[0] = 0; @@ -731,7 +768,6 @@ void *run(void *args) { #if !debug wscrl(scr, -1); #else - updt = (!addr[0x16]); #endif esc = 0; break; @@ -739,7 +775,6 @@ void *run(void *args) { #if !debug wscrl(scr, 1); #else - updt = (!addr[0x16]); #endif esc = 0; break; @@ -779,7 +814,13 @@ void *run(void *args) { #if !debug wdelch(scr); #else - updt = 1; + if (!subdbg) { + scr_col++; + wmove(scr, 28, scr_col--); + wdelch(scr); + wmove(scr, 28, scr_col); + wdelch(scr); + } #endif break; case '\033': @@ -789,8 +830,6 @@ void *run(void *args) { #if !debug wmove(scr, y, x); waddch(scr, addr[address]); - #else - updt = (!addr[0x16]); #endif x = 0; y+=1; @@ -800,7 +839,13 @@ void *run(void *args) { wmove(scr, y, x); waddch(scr, addr[address]); #else - updt = (!addr[0x16]); + if (!subdbg && scr_col < 160) { + if (addr[address] != ' ') { + wprintw(scr, "%02X", addr[address]); + } else { + wprintw(scr, " "); + } + } #endif x+=1; break; @@ -1218,11 +1263,10 @@ void *run(void *args) { default: break; } + #if !IO ins++; - #if !bench - #if debug - updt = (!addr[0x16]); #endif + #if !bench if (step) { pthread_mutex_lock(&main_mutex); pthread_cond_signal(&main_cond); @@ -1244,7 +1288,7 @@ void *run(void *args) { #if getclk wprintw(scr, ", Clock cycles: %"PRIu64, iclk); #endif - if (!step) { + if (!step && !subdbg) { wrefresh(scr); } #if keypoll @@ -1272,9 +1316,13 @@ int main(int argc, char **argv) { struct suxthr thr[THREADS]; char *tmp = malloc(2048); addr = malloc(0x04000000); + #if bench 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; @@ -1328,7 +1376,9 @@ int main(int argc, char **argv) { | (uint64_t)addr[vec+7+offset] << 56; thr[i].th = i; + #if !IO inst[i] = 0; + #endif result = pthread_create(&therads[i], NULL, run, &thr[i]); assert(!result); } @@ -1342,6 +1392,11 @@ int main(int argc, char **argv) { int x, y; if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) { if ((c != EOF && c !=-1)) { + #if !keypoll + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + #endif pthread_mutex_lock(&main_mutex); curs_set(0); pthread_cond_wait(&main_cond, &main_mutex); @@ -1350,9 +1405,7 @@ int main(int argc, char **argv) { c = 0; step_key = 0; addr[CTRL_ADDR] = 0; - #if !debug wrefresh(scr); - #endif } } #if keypoll @@ -1361,10 +1414,10 @@ int main(int argc, char **argv) { getyx(scr, y, x); c = wgetch(scr); if (c == 19) { - step = 1; if (kbd_rdy) { c = wgetch(scr); } + step = 1; } if (kbd_rdy) { switch (c) { @@ -1377,27 +1430,17 @@ int main(int argc, char **argv) { addr[CTRL_ADDR] = 1; #if debug && !bench wmove(scr, getmaxy(scr)-1, 0); - wprintw(scr, "c: %i, x: %i, y: %i", c, x, y); + wclrtoeol(scr); + wprintw(scr, "c: %i", c); wmove(scr, y, x); - wrefresh(scr); #endif } - #if !keypoll - pthread_mutex_lock(&mutex); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - #endif break; } } else { if (step) { step = !(c == 18); step_key = (c == 19); - #if !keypoll - pthread_mutex_lock(&mutex); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - #endif } } addr[STEP_ADDR] = step; |