Call opcodes are now relative
This commit is contained in:
parent
18ff8550c7
commit
256b7cafce
23
src/uxn.c
23
src/uxn.c
|
@ -33,10 +33,11 @@ int
|
||||||
uxn_eval(Uxn *u, Uint16 pc)
|
uxn_eval(Uxn *u, Uint16 pc)
|
||||||
{
|
{
|
||||||
Uint8 kptr, *sp;
|
Uint8 kptr, *sp;
|
||||||
Uint16 a, b, c, j, k, bs, instr;
|
Uint16 a, b, c, j, k, bs, instr, opcode;
|
||||||
Stack *src, *dst;
|
Stack *src, *dst;
|
||||||
if(!pc || u->dev[0x0f]) return 0;
|
if(!pc || u->dev[0x0f]) return 0;
|
||||||
while((instr = u->ram[pc++])) {
|
for(;;) {
|
||||||
|
instr = u->ram[pc++];
|
||||||
/* Return Mode */
|
/* Return Mode */
|
||||||
if(instr & 0x40) { src = u->rst; dst = u->wst; }
|
if(instr & 0x40) { src = u->rst; dst = u->wst; }
|
||||||
else { src = u->wst; dst = u->rst; }
|
else { src = u->wst; dst = u->rst; }
|
||||||
|
@ -45,14 +46,17 @@ uxn_eval(Uxn *u, Uint16 pc)
|
||||||
else sp = &src->ptr;
|
else sp = &src->ptr;
|
||||||
/* Short Mode */
|
/* Short Mode */
|
||||||
bs = instr & 0x20;
|
bs = instr & 0x20;
|
||||||
switch(instr & 0x1f) {
|
opcode = instr & 0x1f;
|
||||||
case 0x00:
|
switch(opcode - (!opcode * (instr >> 5))) {
|
||||||
/* Literals/Calls */
|
/* Literals/Calls */
|
||||||
if(instr == 0x20) /* JMI */ { PEEK16(a, pc) pc = a; }
|
case -0x0: /* BRK */ return 1;
|
||||||
else if(instr == 0x40) /* JCI */ { sp = &u->wst->ptr; src = u->wst; POP8(b) if(b) { PEEK16(a, pc) pc = a; } else pc += 2; }
|
case -0x1: /* JMI */ PEEK16(a, pc) pc += a + 2; break;
|
||||||
else if(instr == 0x60) /* JSI */ { PUSH16(u->rst, pc + 2) PEEK16(a, pc) pc = a; }
|
case -0x2: /* JCI */ sp = &u->wst->ptr; src = u->wst; POP8(b) if(b) { PEEK16(a, pc) pc += a + 2; } else pc += 2; break;
|
||||||
else if(bs) /* LIT2 */ { PEEK16(a, pc) PUSH16(src, a) pc += 2; }
|
case -0x3: /* JSI */ PUSH16(u->rst, pc + 2) PEEK16(a, pc) pc += a + 2; break;
|
||||||
else /* LITr */ { a = u->ram[pc++]; PUSH8(src, a) } 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 */
|
/* ALU */
|
||||||
case 0x01: /* INC */ POP(a) PUSH(src, a + 1) break;
|
case 0x01: /* INC */ POP(a) PUSH(src, a + 1) break;
|
||||||
case 0x02: /* POP */ POP(a) 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;
|
case 0x1f: /* SFT */ POP8(a) POP(b) PUSH(src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
42
src/uxnasm.c
42
src/uxnasm.c
|
@ -302,26 +302,26 @@ parse(char *w, FILE *f)
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr);
|
||||||
return writebyte(0xff);
|
return writebyte(0xff);
|
||||||
case ',': /* literal byte relative */
|
case ',': /* literal byte relative */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr + 1);
|
||||||
return writelitbyte(0xff);
|
return writelitbyte(0xff);
|
||||||
case '-': /* raw byte absolute */
|
case '-': /* raw byte absolute */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr);
|
||||||
return writebyte(0xff);
|
return writebyte(0xff);
|
||||||
case '.': /* literal byte zero-page */
|
case '.': /* literal byte zero-page */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr + 1);
|
||||||
return writelitbyte(0xff);
|
return writelitbyte(0xff);
|
||||||
case ':': /* raw short absolute */
|
case ':': /* raw short absolute */
|
||||||
case '=':
|
case '=':
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr);
|
||||||
return writeshort(0xffff, 0);
|
return writeshort(0xffff, 0);
|
||||||
case ';': /* literal short absolute */
|
case ';': /* literal short absolute */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr + 1);
|
||||||
return writeshort(0xffff, 1);
|
return writeshort(0xffff, 1);
|
||||||
case '!': /* JMI */
|
case '!': /* JMI */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr + 1);
|
||||||
return writebyte(0x20) && writeshort(0xffff, 0);
|
return writebyte(0x20) && writeshort(0xffff, 0);
|
||||||
case '?': /* JCI */
|
case '?': /* JCI */
|
||||||
makereference(p.scope, w, p.ptr);
|
makereference(p.scope, w, p.ptr + 1);
|
||||||
return writebyte(0x40) && writeshort(0xffff, 0);
|
return writebyte(0x40) && writeshort(0xffff, 0);
|
||||||
case '"': /* raw string */
|
case '"': /* raw string */
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -348,7 +348,7 @@ parse(char *w, FILE *f)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
makereference(p.scope, w - 1, p.ptr);
|
makereference(p.scope, w - 1, p.ptr + 1);
|
||||||
return writebyte(0x60) && writeshort(0xffff, 0);
|
return writebyte(0x60) && writeshort(0xffff, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,10 +360,12 @@ resolve(void)
|
||||||
{
|
{
|
||||||
Label *l;
|
Label *l;
|
||||||
int i;
|
int i;
|
||||||
|
Uint16 a;
|
||||||
for(i = 0; i < p.rlen; i++) {
|
for(i = 0; i < p.rlen; i++) {
|
||||||
Reference *r = &p.refs[i];
|
Reference *r = &p.refs[i];
|
||||||
switch(r->rune) {
|
switch(r->rune) {
|
||||||
case '_':
|
case '_':
|
||||||
|
case ',':
|
||||||
if(!(l = findlabel(r->name)))
|
if(!(l = findlabel(r->name)))
|
||||||
return error("Unknown relative reference", r->name);
|
return error("Unknown relative reference", r->name);
|
||||||
p.data[r->addr] = (Sint8)(l->addr - r->addr - 2);
|
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);
|
return error("Relative reference is too far", r->name);
|
||||||
l->refs++;
|
l->refs++;
|
||||||
break;
|
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 '-':
|
case '-':
|
||||||
if(!(l = findlabel(r->name)))
|
|
||||||
return error("Unknown absolute reference", r->name);
|
|
||||||
p.data[r->addr] = l->addr & 0xff;
|
|
||||||
l->refs++;
|
|
||||||
break;
|
|
||||||
case '.':
|
case '.':
|
||||||
if(!(l = findlabel(r->name)))
|
if(!(l = findlabel(r->name)))
|
||||||
return error("Unknown zero-page reference", 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++;
|
l->refs++;
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
case '=':
|
case '=':
|
||||||
|
case ';':
|
||||||
if(!(l = findlabel(r->name)))
|
if(!(l = findlabel(r->name)))
|
||||||
return error("Unknown absolute reference", r->name);
|
return error("Unknown absolute reference", r->name);
|
||||||
p.data[r->addr] = l->addr >> 0x8;
|
p.data[r->addr] = l->addr >> 0x8;
|
||||||
p.data[r->addr + 1] = l->addr & 0xff;
|
p.data[r->addr + 1] = l->addr & 0xff;
|
||||||
l->refs++;
|
l->refs++;
|
||||||
break;
|
break;
|
||||||
|
case '?':
|
||||||
|
case '!':
|
||||||
default:
|
default:
|
||||||
if(!(l = findlabel(r->name)))
|
if(!(l = findlabel(r->name)))
|
||||||
return error("Unknown absolute reference", r->name);
|
return error("Unknown absolute reference", r->name);
|
||||||
p.data[r->addr + 1] = l->addr >> 0x8;
|
a = l->addr - r->addr - 2;
|
||||||
p.data[r->addr + 2] = l->addr & 0xff;
|
p.data[r->addr] = a >> 0x8;
|
||||||
|
p.data[r->addr + 1] = a & 0xff;
|
||||||
l->refs++;
|
l->refs++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -451,8 +444,9 @@ writesym(char *filename)
|
||||||
fp = fopen(scat(scpy(filename, symdst, slen(filename) + 1), ".sym"), "w");
|
fp = fopen(scat(scpy(filename, symdst, slen(filename) + 1), ".sym"), "w");
|
||||||
if(fp != NULL) {
|
if(fp != NULL) {
|
||||||
for(i = 0; i < p.llen; i++) {
|
for(i = 0; i < p.llen; i++) {
|
||||||
fwrite(&p.labels[i].addr + 1, 1, 1, fp);
|
Uint8 hb = p.labels[i].addr >> 8, lb = p.labels[i].addr & 0xff;
|
||||||
fwrite((Uint8*)&p.labels[i].addr, 1, 1, fp);
|
fwrite(&hb, 1, 1, fp);
|
||||||
|
fwrite(&lb, 1, 1, fp);
|
||||||
fwrite(p.labels[i].name, slen(p.labels[i].name) + 1, 1, fp);
|
fwrite(p.labels[i].name, slen(p.labels[i].name) + 1, 1, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue