~rabbits/uxn11

256b7cafce242f64336ae7ac9a1983cb8a37f90b — Devine Lu Linvega a month ago 18ff855
Call opcodes are now relative
2 files changed, 31 insertions(+), 34 deletions(-)

M src/uxn.c
M src/uxnasm.c
M src/uxn.c => src/uxn.c +13 -10
@@ 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

M src/uxnasm.c => src/uxnasm.c +18 -24
@@ 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);
		}
	}