summaryrefslogtreecommitdiff
path: root/asmmon.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-04-27 00:22:27 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-04-27 14:00:00 -0400
commited88644ded82008577804c590bec7188ef0da011 (patch)
tree9bb534b0019c61a4c300493b382135ff3793103b /asmmon.c
parente093aba79dd1ed88cb490b7cd69c81f0b14bea11 (diff)
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!
Diffstat (limited to 'asmmon.c')
-rw-r--r--asmmon.c245
1 files changed, 166 insertions, 79 deletions
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;
}