Skip to content

Commit

Permalink
a16: add support for labels and the "word" pseudo-op
Browse files Browse the repository at this point in the history
  • Loading branch information
swetland committed Apr 5, 2012
1 parent 72884f8 commit aafa43d
Showing 1 changed file with 94 additions and 6 deletions.
100 changes: 94 additions & 6 deletions a16.c
Expand Up @@ -38,12 +38,79 @@ void die(const char *fmt, ...) {
exit(1); exit(1);
} }


struct fixup {
struct fixup *next;
struct label *label;
u16 pc;
};

struct label {
struct label *next;
u16 pc;
u16 defined;
char name[1];
};

struct label *labels = 0;
struct fixup *fixups = 0;

struct label *mklabel(const char *name, u16 pc, u16 def) {
struct label *l;
for (l = labels; l; l = l->next) {
if (!strcasecmp(name, l->name)) {
if (def) {
if (l->defined)
die("cannot redefine label: %s", name);
l->defined = def;
l->pc = pc;
}
return l;
}
}
l = malloc(sizeof(*l) + strlen(name));
l->defined = def;
l->pc = pc;
strcpy(l->name, name);
l->next = labels;
labels = l;
return l;
}

void use_label(const char *name, u16 pc) {
struct label *l = mklabel(name, 0, 0);
if (l->defined) {
image[pc] = l->pc;
} else {
struct fixup *f = malloc(sizeof(*f));
f->next = fixups;
f->pc = pc;
f->label = l;
fixups = f;
}
}

void set_label(const char *name, u16 pc) {
mklabel(name, pc, 1);
}

void resolve_fixups(void) {
struct fixup *f;
for (f = fixups; f; f = f->next) {
if (f->label->defined) {
image[f->pc] = f->label->pc;
} else {
die("undefined reference to '%s' at 0x%04x", f->label->name, f->pc);
}
}
}

enum tokens { enum tokens {
tA, tB, tC, tX, tY, tZ, tI, tJ, tA, tB, tC, tX, tY, tZ, tI, tJ,
tXXX, tSET, tADD, tSUB, tMUL, tDIV, tMOD, tSHL, tXXX, tSET, tADD, tSUB, tMUL, tDIV, tMOD, tSHL,
tSHR, tAND, tBOR, tXOR, tIFE, tIFN, tIFG, tIFB, tSHR, tAND, tBOR, tXOR, tIFE, tIFN, tIFG, tIFB,
tJSR, tJSR,
tPOP, tPEEK, tPUSH, tSP, tPC, tO, tPOP, tPEEK, tPUSH, tSP, tPC, tO,
tWORD,
tCOMMA, tOBRACK, tCBRACK, tCOLON, tCOMMA, tOBRACK, tCBRACK, tCOLON,
tSTRING, tNUMBER, tEOF, tSTRING, tNUMBER, tEOF,
}; };
Expand All @@ -53,14 +120,15 @@ static const char *tnames[] = {
"SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB", "SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB",
"JSR", "JSR",
"POP", "PEEK", "PUSH", "SP", "PC", "O", "POP", "PEEK", "PUSH", "SP", "PC", "O",
"WORD",
",", "[", "]", ":", ",", "[", "]", ":",
"<STRING>", "<NUMBER>", "<EOF>", "<STRING>", "<NUMBER>", "<EOF>",
}; };
static const char *rnames[] = { static const char *rnames[] = {
"A", "B", "C", "X", "Y", "Z", "I", "J", "A", "B", "C", "X", "Y", "Z", "I", "J",
}; };


#define LASTKEYWORD tO #define LASTKEYWORD tWORD


int _next(void) { int _next(void) {
char c; char c;
Expand Down Expand Up @@ -115,6 +183,18 @@ void expect(int t) {
die("expecting %s, found %s", tnames[t], tnames[token]); die("expecting %s, found %s", tnames[t], tnames[token]);
} }


void assemble_imm_or_label(void) {
next();
if (token == tNUMBER) {
image[PC++] = tnumber;
} else if (token == tSTRING) {
image[PC] = 0;
use_label(tstring, PC++);
} else {
die("expected number or label");
}
}

int assemble_operand(void) { int assemble_operand(void) {
int n; int n;
next(); next();
Expand All @@ -131,6 +211,10 @@ int assemble_operand(void) {
case tNUMBER: case tNUMBER:
image[PC++] = tnumber; image[PC++] = tnumber;
return 0x1f; return 0x1f;
case tSTRING:
image[PC] = 0;
use_label(tstring, PC++);
return 0x1f;
default: default:
if (token != tOBRACK) if (token != tOBRACK)
die("expected ["); die("expected [");
Expand All @@ -144,15 +228,14 @@ int assemble_operand(void) {
if (token == tCBRACK) { if (token == tCBRACK) {
return n | 0x08; return n | 0x08;
} else if (token == tCOMMA) { } else if (token == tCOMMA) {
expect(tNUMBER); // handle labels assemble_imm_or_label();
image[PC++] = tnumber;
expect(tCBRACK); expect(tCBRACK);
return n | 0x10; return n | 0x10;
} else { } else {
die("invalid operand"); die("invalid operand");
} }
//case tSTRING: case tSTRING:
// handle labels use_label(tstring, PC);
case tNUMBER: case tNUMBER:
image[PC++] = tnumber; image[PC++] = tnumber;
next(); next();
Expand Down Expand Up @@ -191,7 +274,10 @@ void assemble(const char *fn) {
goto done; goto done;
case tCOLON: case tCOLON:
expect(tSTRING); expect(tSTRING);
//setlabel(tstring, PC); set_label(tstring, PC);
continue;
case tWORD:
assemble_imm_or_label();
continue; continue;
case tSET: case tADD: case tSUB: case tMUL: case tSET: case tADD: case tSUB: case tMUL:
case tDIV: case tMOD: case tSHL: case tSHR: case tDIV: case tMOD: case tSHL: case tSHR:
Expand Down Expand Up @@ -239,6 +325,8 @@ int main(int argc, char **argv) {
assemble(argv[0]); assemble(argv[0]);
} }


linebuffer[0] = 0;
resolve_fixups();
emit(outfn); emit(outfn);
return 0; return 0;
} }
Expand Down

0 comments on commit aafa43d

Please sign in to comment.