From ed88644ded82008577804c590bec7188ef0da011 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Mon, 27 Apr 2020 00:22:27 -0400 Subject: Added support for including source files to the emulator's assembler. And removed three pointers, and the linewrap table from zero page, in SuBEditor. I moved the linewrap table to address $1000. And because of finally adding include support to the assembler, I can now start work on SuBAsm! --- asmmon.c | 245 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 166 insertions(+), 79 deletions(-) (limited to 'asmmon.c') diff --git a/asmmon.c b/asmmon.c index 16865eb..9df2bac 100644 --- a/asmmon.c +++ b/asmmon.c @@ -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; } -- cgit v1.2.3-13-gbd6f