diff --git a/src/uxn.c b/src/uxn.c index 0af9995..1d1b12f 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -33,10 +33,11 @@ int uxn_eval(Uxn *u, Uint16 pc) { Uint8 kptr, *sp; - Uint16 a, b, c, j, k, bs, instr; + Uint16 a, b, c, j, k, bs, instr, opcode; Stack *src, *dst; if(!pc || u->dev[0x0f]) return 0; - while((instr = u->ram[pc++])) { + for(;;) { + instr = u->ram[pc++]; /* Return Mode */ if(instr & 0x40) { src = u->rst; dst = u->wst; } else { src = u->wst; dst = u->rst; } @@ -45,14 +46,17 @@ uxn_eval(Uxn *u, Uint16 pc) else sp = &src->ptr; /* Short Mode */ bs = instr & 0x20; - switch(instr & 0x1f) { - case 0x00: + opcode = instr & 0x1f; + switch(opcode - (!opcode * (instr >> 5))) { /* Literals/Calls */ - if(instr == 0x20) /* JMI */ { PEEK16(a, pc) pc = a; } - else if(instr == 0x40) /* JCI */ { sp = &u->wst->ptr; src = u->wst; POP8(b) if(b) { PEEK16(a, pc) pc = a; } else pc += 2; } - else if(instr == 0x60) /* JSI */ { PUSH16(u->rst, pc + 2) PEEK16(a, pc) pc = a; } - else if(bs) /* LIT2 */ { PEEK16(a, pc) PUSH16(src, a) pc += 2; } - else /* LITr */ { a = u->ram[pc++]; PUSH8(src, a) } break; + case -0x0: /* BRK */ return 1; + case -0x1: /* JMI */ PEEK16(a, pc) pc += a + 2; break; + case -0x2: /* JCI */ sp = &u->wst->ptr; src = u->wst; POP8(b) if(b) { PEEK16(a, pc) pc += a + 2; } else pc += 2; break; + case -0x3: /* JSI */ PUSH16(u->rst, pc + 2) PEEK16(a, pc) pc += a + 2; break; + case -0x4: /* LIT */ + case -0x6: /* LITr */ a = u->ram[pc++]; PUSH8(src, a) break; + case -0x5: /* LIT2 */ + case -0x7: /* LIT2r */ PEEK16(a, pc) PUSH16(src, a) pc += 2; break; /* ALU */ case 0x01: /* INC */ POP(a) PUSH(src, a + 1) break; case 0x02: /* POP */ POP(a) break; @@ -87,7 +91,6 @@ uxn_eval(Uxn *u, Uint16 pc) case 0x1f: /* SFT */ POP8(a) POP(b) PUSH(src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)) break; } } - return 1; } int diff --git a/src/uxnasm.c b/src/uxnasm.c index 48c1e7b..b43fa38 100644 --- a/src/uxnasm.c +++ b/src/uxnasm.c @@ -302,26 +302,26 @@ parse(char *w, FILE *f) makereference(p.scope, w, p.ptr); return writebyte(0xff); case ',': /* literal byte relative */ - makereference(p.scope, w, p.ptr); + makereference(p.scope, w, p.ptr + 1); return writelitbyte(0xff); case '-': /* raw byte absolute */ makereference(p.scope, w, p.ptr); return writebyte(0xff); case '.': /* literal byte zero-page */ - makereference(p.scope, w, p.ptr); + makereference(p.scope, w, p.ptr + 1); return writelitbyte(0xff); case ':': /* raw short absolute */ case '=': makereference(p.scope, w, p.ptr); return writeshort(0xffff, 0); case ';': /* literal short absolute */ - makereference(p.scope, w, p.ptr); + makereference(p.scope, w, p.ptr + 1); return writeshort(0xffff, 1); case '!': /* JMI */ - makereference(p.scope, w, p.ptr); + makereference(p.scope, w, p.ptr + 1); return writebyte(0x20) && writeshort(0xffff, 0); case '?': /* JCI */ - makereference(p.scope, w, p.ptr); + makereference(p.scope, w, p.ptr + 1); return writebyte(0x40) && writeshort(0xffff, 0); case '"': /* raw string */ i = 0; @@ -348,7 +348,7 @@ parse(char *w, FILE *f) return 0; return 1; } else { - makereference(p.scope, w - 1, p.ptr); + makereference(p.scope, w - 1, p.ptr + 1); return writebyte(0x60) && writeshort(0xffff, 0); } } @@ -360,10 +360,12 @@ resolve(void) { Label *l; int i; + Uint16 a; for(i = 0; i < p.rlen; i++) { Reference *r = &p.refs[i]; switch(r->rune) { case '_': + case ',': if(!(l = findlabel(r->name))) return error("Unknown relative reference", r->name); p.data[r->addr] = (Sint8)(l->addr - r->addr - 2); @@ -371,39 +373,30 @@ resolve(void) return error("Relative reference is too far", r->name); l->refs++; break; - case ',': - if(!(l = findlabel(r->name))) - return error("Unknown relative reference", r->name); - p.data[r->addr + 1] = (Sint8)(l->addr - r->addr - 3); - if((Sint8)p.data[r->addr + 1] != (l->addr - r->addr - 3)) - return error("Relative reference is too far", r->name); - l->refs++; - break; case '-': - if(!(l = findlabel(r->name))) - return error("Unknown absolute reference", r->name); - p.data[r->addr] = l->addr & 0xff; - l->refs++; - break; case '.': if(!(l = findlabel(r->name))) return error("Unknown zero-page reference", r->name); - p.data[r->addr + 1] = l->addr & 0xff; + p.data[r->addr] = l->addr & 0xff; l->refs++; break; case ':': case '=': + case ';': if(!(l = findlabel(r->name))) return error("Unknown absolute reference", r->name); p.data[r->addr] = l->addr >> 0x8; p.data[r->addr + 1] = l->addr & 0xff; l->refs++; break; + case '?': + case '!': default: if(!(l = findlabel(r->name))) return error("Unknown absolute reference", r->name); - p.data[r->addr + 1] = l->addr >> 0x8; - p.data[r->addr + 2] = l->addr & 0xff; + a = l->addr - r->addr - 2; + p.data[r->addr] = a >> 0x8; + p.data[r->addr + 1] = a & 0xff; l->refs++; break; } @@ -451,8 +444,9 @@ writesym(char *filename) fp = fopen(scat(scpy(filename, symdst, slen(filename) + 1), ".sym"), "w"); if(fp != NULL) { for(i = 0; i < p.llen; i++) { - fwrite(&p.labels[i].addr + 1, 1, 1, fp); - fwrite((Uint8*)&p.labels[i].addr, 1, 1, fp); + Uint8 hb = p.labels[i].addr >> 8, lb = p.labels[i].addr & 0xff; + fwrite(&hb, 1, 1, fp); + fwrite(&lb, 1, 1, fp); fwrite(p.labels[i].name, slen(p.labels[i].name) + 1, 1, fp); } }