summaryrefslogtreecommitdiff
path: root/asmmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'asmmon.c')
-rw-r--r--asmmon.c554
1 files changed, 107 insertions, 447 deletions
diff --git a/asmmon.c b/asmmon.c
index 81e4b28..840deae 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -13,7 +13,8 @@ char lexeme[MAX_TOK];
char *string[MAX_TOK];
char *comment[MAX_TOK];
uint16_t incl[MAX_TOK];
-struct line tokline[MAX_TOK];
+line *lines;
+line *last_line;
struct line tln[MAX_TOK];
struct symbol *symbols[MAX_TOK];
struct fixup *fixups[MAX_TOK];
@@ -109,8 +110,9 @@ char *showbits(uint64_t value, uint8_t bitnum, 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;
+void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) {
+ line *s = find_line(start, dbg);
+ line *e = find_line(end, dbg);
uint8_t j = 0;
uint8_t flags = 0;
uint8_t isstr;
@@ -125,31 +127,24 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
char ch[6];
if (all) {
- end = lineidx;
+ s = lines;
+ e = last_line;
}
- for (; i < end; i++) {
- flags = 0;
- 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;
+
+ do {
+ token *t = s->tok;
+ uint8_t am = 0xFF;
+ uint8_t rs = 0xFF;
if (dbg) {
printf("list(): ");
}
if (ln) {
- printf("%u\t", l[i].linenum);
+ printf("%u\t", s->linenum);
} else if (addr) {
- printf("$%"PRIX64":\t", l[i].addr);
+ printf("$%"PRIX64":\t", s->addr);
}
- spaces = l[i].sspace;
- tabs = l[i].stab;
+ spaces = s->sspace;
+ tabs = s->stab;
while (spaces || tabs) {
if (spaces) {
putchar(' ');
@@ -160,136 +155,89 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
tabs--;
}
}
- if (flags & 0x01) {
- printf(".%s ", dir_t[l[i].dir]);
- if (isstr) {
- printf("\"%s\"", string[l[i].str]);
- }
- }
- if (flags & 0x02) {
- for (; j < 3; 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[l[i].rs]);
- } else if (flags & 0x02) {
- printf(" ");
- }
- if (flags & 0x7F) {
- switch (l[i].am) {
- case IMM:
- putchar('#');
+ for (; t && t->id != TOK_COMMENT; t = t->next) {
+ switch (t->id) {
+ case TOK_DIR : printf(".%s ", dir_t[t->type]); break;
+ case TOK_STRING: printf("\"%s\"", t->str) ; break;
+ case TOK_OPCODE:
+ for (; j < 3; j++) {
+ mne_lower[j] = tolower(mne[t->byte][j]);
+ }
+ mne_lower[j] = '\0';
+ j = 0;
+ printf("%s", mne_lower);
+ am = t->type;
+ t = t->next;
+ if (t->id == TOK_RS) {
+ rs = t->type;
+ printf("%s", rs_t[t->type]);
+ }
+ switch (am) {
+ case IMM : putchar('#'); break;
+ case IND :
+ case INDX:
+ case INDY: putchar('('); break;
+ }
break;
- case INDX:
- case INDY:
- case IND:
- putchar('(');
+ case TOK_SYM:
+ case TOK_LABEL:
+ printf("%s", symbols[t->word]->name);
+ if (t->id == TOK_LABEL) {
+ putchar(':');
+ } else if (t == s->tok && t->id == TOK_SYM) {
+ printf(" = ");
+ }
break;
- }
- }
- if (flags & 0x20) {
- printf("%s", symbols[l[i].sym]->name);
- if (l[i].islabel) {
- printf(": ");
- } else if (l[i].issym) {
- printf(" = ");
- }
- }
- if (flags & 0x10) {
- if (flags & 0x04) {
- bitnum = (l[i].rs << 3);
- } else {
- 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];
- }
- }
-
- j = 0;
-
- if (l[i].opbase == BASE_CHAR) {
- switch (l[i].op) {
- default : ch[j++] = l[i].op; break;
- case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
- case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
- case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
- case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
- case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
- case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
- }
- }
-
- ch[j] = '\0';
- j = 0;
-
- 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;
- case BASE_CHAR: printf("\'%s\'", ch); break;
- }
- bitnum = 0;
- opsize = 0;
- }
- if (iscm) {
- switch (l[i].cm) {
- case 0:
- putchar('+');
+ case TOK_HEX: printf("$%"PRIX64, t->qword); break;
+ case TOK_DEC: printf( "%"PRIu64, t->qword); break;
+ case TOK_BIN:
+ if (rs != 0xFF) {
+ bitnum = (rs << 3);
+ } else {
+ opsize += (t->qword <= 0x000000FF) + 0;
+ opsize += (t->qword > 0x000000FF) + 1;
+ opsize += (t->qword > 0x0000FFFF) + 2;
+ opsize += (t->qword > 0xFFFFFFFF) + 3;
+ if (opsize) {
+ bitnum = bitsize[opsize-1];
+ }
+ }
+ printf("%%%s", showbits(t->qword, bitnum, dbg));
+ bitnum = 0;
+ opsize = 0;
break;
- case 1:
- putchar ('-');
+ case TOK_CHAR:
+ j = 0;
+ switch (t->byte) {
+ default : ch[j++] = t->byte; break;
+ case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
+ case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
+ case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
+ case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
+ case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
+ case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
+ }
+ ch[j] = '\0';
+ j = 0;
+ printf("\'%s\'", ch);
+ break;
+ case TOK_EXPR:
+ switch (t->type) {
+ case EXPR_PLUS : putchar('+'); break;
+ case EXPR_MINUS: putchar('-'); break;
+ }
break;
}
- 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];
- }
-
- j = 0;
-
- if (l[i].aopbase == BASE_CHAR) {
- switch (l[i].aop) {
- default : ch[j++] = l[i].aop; break;
- case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
- case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
- case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
- case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
- case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
- case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
- }
- }
-
- ch[j] = '\0';
- j = 0;
-
- 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;
- case BASE_CHAR: printf("\'%s\'", ch); break;
- }
- bitnum = 0;
- opsize = 0;
}
- if (flags & 0x7F) {
+ if (am != 0xFF) {
if (fall) {
fall = 0;
}
- switch (l[i].am) {
+ switch (am) {
case INDX:
case ZMX:
printf(", x");
- if (l[i].am == ZMX) {
+ if (am == ZMX) {
break;
}
fall = 1;
@@ -308,8 +256,8 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
break;
}
}
- spaces = l[i].espace;
- tabs = l[i].etab;
+ spaces = s->espace;
+ tabs = s->etab;
while (spaces || tabs) {
if (spaces) {
putchar(' ');
@@ -320,302 +268,12 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
tabs--;
}
}
- if (iscom) {
- printf(";%s", comment[l[i].com]);
+ if (t->id == TOK_COMMENT) {
+ printf(";%s", t->str);
}
puts("");
- }
-}
-
-void assemble(struct line *line, bytecount *bc, uint8_t dbg) {
- bc->progsize = 0;
- bc->datasize = 0;
- uint64_t tmpaddr;
- uint64_t value;
- uint16_t flags = 0;
- uint16_t i = 0;
- uint16_t k = 0;
- uint16_t tmp;
- uint8_t c = 0;
- uint8_t prefix = 0;
- uint8_t opsize = 0;
- uint8_t skip = 0;
-
- uint64_t address;
- uint64_t op;
- uint64_t aop;
- uint16_t symid;
- uint16_t str;
- uint16_t com;
- uint8_t islabel;
- uint8_t opbase;
- uint8_t aopbase;
- uint8_t dir;
- uint8_t am;
- uint8_t cm;
- uint8_t rs;
- uint8_t ins;
-
- for (; i < lineidx; i++) {
- if (dbg) {
- printf("assemble(): i: $%X\n", i);
- }
- address = line[i].addr;
- tmpaddr = address;
- 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;
- flags |= (rs != 0x00FF) << 0x02;
- flags |= (am != 0x00FF) << 0x03;
- flags |= (opbase != 0x00FF) << 0x04;
- flags |= (aopbase != 0x00FF) << 0x05;
- flags |= (symid != 0xFFFF) << 0x06;
- flags |= (islabel ) << 0x07;
- flags |= (am != 0x00FF) << 0x08;
- flags |= (cm != 0x00FF) << 0x09;
- flags |= (str != 0xFFFF) << 0x0A;
- if (dbg) {
- printf("assemble(): ");
- putchar('%');
- printf("%u", str != 0xFFFF);
- printf("%u", cm != 0x00FF);
- printf("%u", am != 0x00FF);
- printf("%u", islabel );
- printf("%u", symid != 0xFFFF);
- printf("%u", aopbase != 0x00FF);
- printf("%u", opbase != 0x00FF);
- printf("%u", am != 0x00FF);
- printf("%u", rs != 0x00FF);
- printf("%u", ins != 0x00FF);
- printf("%u", dir != 0x00FF);
- putchar('\n');
-
- printf("assemble(): ");
- printf("flags: $%04X\n", flags);
- }
- if (!flags) {
- if (dbg) {
- printf("assemble(): ");
- puts("This line only contains a comment, so skip it.");
- }
- continue;
- }
- opsize = 0;
- skip = 0;
- if ((flags & 0x53) == 0x42 || (flags & 0x51) == 0x41) {
- value = symbols[symid]->val;
- } else {
- value = op;
- }
- if (flags & 0x220) {
- switch (cm) {
- case 0: value += aop; break;
- case 1: value -= aop; break;
- }
- }
- if (dbg) {
- printf("assemble(): value: $%"PRIX64"\n", value);
- }
- switch (dir) {
- case DIR_ORG:
- tmpaddr = value;
- if (dbg) {
- printf("assemble(): ");
- printf("The Program Counter's origin is now at, $%"PRIX64".\n", value);
- }
- skip = 1;
- break;
- case DIR_BYTE:
- if (flags & 0x400) {
- for (k = 0; string[str][k] != '\0'; k++) {
- switch (string[str][k]) {
- case '\\':
- switch (string[str][k+1]) {
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case '0': c = '\0'; break;
- }
- k++;
- break;
- default:
- c = string[str][k];
- break;
- }
- bc->datasize++;
- addr[tmpaddr++] = c;
- }
- addr[tmpaddr] = '\0';
- if (dbg) {
- printf("assemble(): ");
- printf("Placed string \"%s\"", string[str]);
- printf(", at address(es) $%"PRIX64"-$%"PRIX64".\n", address, tmpaddr);
- }
- } else {
- bc->datasize++;
- addr[tmpaddr++] = value & 0xFF;
- }
- break;
- case DIR_QWORD:
- addr[tmpaddr+7] = value >> 0x38;
- addr[tmpaddr+6] = value >> 0x30;
- addr[tmpaddr+5] = value >> 0x28;
- addr[tmpaddr+4] = value >> 0x20;
- tmp+=4;
- bc->datasize+=4;
- case DIR_DWORD:
- addr[tmpaddr+3] = value >> 0x18;
- addr[tmpaddr+2] = value >> 0x10;
- tmp+=2;
- bc->datasize+=2;
- case DIR_WORD:
- addr[tmpaddr+1] = value >> 0x08;
- addr[tmpaddr ] = value & 0xFF;
- tmp+=2;
- bc->datasize+=2;
- break;
- }
- tmpaddr += tmp;
- tmp = 0;
- if (skip | (flags & 0x80) | (flags == 0x108)) {
- if (dbg) {
- printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
- printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
- }
- continue;
- }
- if (flags & 0x04) {
- prefix = (rs << 4) | 3;
- } else {
- rs = 0;
- }
- if (flags & 0x102) {
- if (ins == 80) {
- if (flags & 0x10) {
- am = IMM;
- prefix |= 0x13;
- } else {
- am = IMPL;
- addr[tmpaddr++] = opcodes[ins][IMM];
- bc->progsize++;
- if (dbg) {
- printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
- printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[IMM]);
- printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][IMM]);
- }
- }
- }
- opsize = 0;
- if (am != IMM && am != IMPL) {
- opsize = (value <= 0x00000000000000FF) ? 1 : opsize;
- opsize = (value > 0x00000000000000FF) ? 2 : opsize;
- opsize = (value > 0x000000000000FFFF) ? 3 : opsize;
- opsize = (value > 0x0000000000FFFFFF) ? 4 : opsize;
- opsize = (value > 0x00000000FFFFFFFF) ? 5 : opsize;
- opsize = (value > 0x000000FFFFFFFFFF) ? 6 : opsize;
- opsize = (value > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
- opsize = (value > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
- if (opsize) {
- opsize--;
- prefix |= amp[opsize];
- }
- }
- if (prefix) {
- if (dbg) {
- printf("assemble(): ");
- puts("Prefix byte detected.");
- }
- addr[tmpaddr++] = prefix;
- bc->progsize++;
- if (dbg) {
- uint8_t addrsize = (prefix & 0x0C) >> 2;
- uint8_t regsize = (prefix & 0x30) >> 4;
-
- printf("assemble(): ");
- printf("The values of the prefix bits are");
- printf(", AM: %u, RS: %u\n", addrsize, regsize);
- }
- prefix = 0;
- }
- if (opcodes[ins][am] != 0xFF) {
- addr[tmpaddr++] = opcodes[ins][am];
- bc->progsize++;
- if (dbg) {
- printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
- printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[am]);
- printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][am]);
- }
- switch (am) {
- case IMM:
- switch (rs) {
- case 3:
- addr[tmpaddr+7] = value >> 0x38;
- addr[tmpaddr+6] = value >> 0x30;
- addr[tmpaddr+5] = value >> 0x28;
- addr[tmpaddr+4] = value >> 0x20;
- tmp+=4;
- case 2:
- addr[tmpaddr+3] = value >> 0x18;
- addr[tmpaddr+2] = value >> 0x10;
- tmp+=2;
- case 1:
- addr[tmpaddr+1] = value >> 0x08;
- tmp+=1;
- case 0:
- addr[tmpaddr ] = value & 0xFF;
- tmp+=1;
- }
- break;
- case ABS:
- case ZM:
- case ZMX:
- case ZMY:
- case IND:
- case INDX:
- case INDY:
- switch (opsize) {
- case 7: addr[tmpaddr+7] = value >> 0x38; tmp++;
- case 6: addr[tmpaddr+6] = value >> 0x30; tmp++;
- case 5: addr[tmpaddr+5] = value >> 0x28; tmp++;
- case 4: addr[tmpaddr+4] = value >> 0x20; tmp++;
- case 3: addr[tmpaddr+3] = value >> 0x18; tmp++;
- case 2: addr[tmpaddr+2] = value >> 0x10; tmp++;
- case 1: addr[tmpaddr+1] = value >> 0x08; tmp++;
- case 0: addr[tmpaddr ] = value & 0xFF; tmp++;
- }
- break;
- }
- tmpaddr += tmp;
- bc->progsize += tmp;
- tmp = 0;
- }
- }
- if (dbg) {
- printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
- printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
-
- printf("assemble(): The program size is now at");
- printf(", %"PRIu64" bytes in decimal", bc->progsize);
- printf(", and $%"PRIX64" bytes in hex.\n", bc->progsize);
-
- printf("assemble(): The data size is now at");
- printf(", %"PRIu64" bytes in decimal", bc->datasize);
- printf(", and $%"PRIX64" bytes in hex.\n", bc->datasize);
- }
- }
+ s = s->next;
+ } while (s != e && s);
}
int asmmon(const char *fn) {
@@ -700,6 +358,9 @@ int asmmon(const char *fn) {
if (fp2 != NULL) {
fclose(fp2);
}
+ if (lines) {
+ free_lines();
+ }
return 2;
case 0x02:
viewmem(address);
@@ -727,12 +388,12 @@ int asmmon(const char *fn) {
for (; isspace(tmp[i]); i++);
}
switch (tmp[i]) {
- case '$': base = BASE_HEX; i++; break;
- case '%': base = BASE_BIN; i++; break;
+ case '$': base = 16; i++; break;
+ case '%': base = 2; i++; break;
default:
j = i;
for (; isdigit(tmp[j]); j++, isflag++);
- base = (isflag) ? BASE_DEC : 0xFF;
+ base = (isflag) ? 10 : 0xFF;
isflag = 0;
j = 0;
break;
@@ -741,11 +402,7 @@ int asmmon(const char *fn) {
arg[j] = '\0';
j = 0;
if (base != 0xFF) {
- switch (base) {
- case BASE_HEX: value = strtol(arg, NULL, 16); break;
- case BASE_BIN: value = strtol(arg, NULL, 2); break;
- case BASE_DEC: value = strtol(arg, NULL, 10); break;
- }
+ value = strtol(arg, NULL, base);
base = 0xFF;
(isstart) ? (start = value) : (end = value);
if (isstart) {
@@ -765,15 +422,15 @@ int asmmon(const char *fn) {
}
i++;
}
- list(tokline, start, end, isstart, islinenum, isaddr, isdebug);
+ list(start, end, isstart, islinenum, isaddr, isdebug);
} else {
- list(tokline, 0, 0, 1, 0, 0, 0);
+ list(0, 0, 1, 0, 0, 0);
}
break;
case 0x08:
if (!inc_file) {
printf("Assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program.");
- assemble(tokline, &bc, dbg);
+ assemble(lines, &bc, dbg);
progsize = bc.progsize;
datasize = bc.datasize;
printf("Finished assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program.");
@@ -846,7 +503,7 @@ int asmmon(const char *fn) {
case 0xFF:
break;
default:
- address = lex(lex_line, tokline, address, dbg);
+ address = lex(lex_line, address, dbg);
break;
}
}
@@ -860,5 +517,8 @@ int asmmon(const char *fn) {
if (fp2 != NULL) {
fclose(fp2);
}
+ if (lines) {
+ free_lines();
+ }
return 0;
}