Merged LIT and BRK into opcode zero, added INC opcode

This commit is contained in:
Andrew Alderwick 2021-08-17 22:48:48 +01:00
parent 5d4020ad31
commit 1b68169cee
5 changed files with 159 additions and 42 deletions

View File

@ -323,8 +323,7 @@ uxn_eval(Uxn *u, Uint16 vec)
return 0; return 0;
u->ram.ptr = vec; u->ram.ptr = vec;
if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
while(u->ram.ptr) { while((instr = u->ram.dat[u->ram.ptr++])) {
instr = u->ram.dat[u->ram.ptr++];
switch(instr) { switch(instr) {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wunused-value"

View File

@ -232,8 +232,7 @@ uxn_eval(Uxn *u, Uint16 vec)
return 0; return 0;
u->ram.ptr = vec; u->ram.ptr = vec;
if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
while(u->ram.ptr) { while((instr = u->ram.dat[u->ram.ptr++])) {
instr = u->ram.dat[u->ram.ptr++];
switch(instr) { switch(instr) {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wunused-value"

View File

@ -48,28 +48,14 @@ uxn_eval(Uxn *u, Uint16 vec)
return 0; return 0;
u->ram.ptr = vec; u->ram.ptr = vec;
if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
while(u->ram.ptr) { while((instr = u->ram.dat[u->ram.ptr++])) {
instr = u->ram.dat[u->ram.ptr++];
switch(instr) { switch(instr) {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wunused-value"
#pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-variable"
case 0x00: /* BRK */ case 0x00: /* LIT */
case 0x20: /* BRK2 */ case 0x80: /* LITk */
case 0x40: /* BRKr */ __asm__("evaluxn_00_LIT:");
case 0x60: /* BRK2r */
case 0x80: /* BRKk */
case 0xa0: /* BRK2k */
case 0xc0: /* BRKkr */
case 0xe0: /* BRK2kr */
__asm__("evaluxn_00_BRK:");
{
u->ram.ptr = 0;
}
break;
case 0x01: /* LIT */
case 0x81: /* LITk */
__asm__("evaluxn_01_LIT:");
{ {
u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++); u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
#ifndef NO_STACK_CHECKS #ifndef NO_STACK_CHECKS
@ -81,6 +67,19 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr += 1; u->wst.ptr += 1;
} }
break; break;
case 0x01: /* INC */
__asm__("evaluxn_01_INC:");
{
Uint8 a = u->wst.dat[u->wst.ptr - 1];
u->wst.dat[u->wst.ptr - 1] = a + 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 1, 0)) {
u->wst.error = 1;
goto error;
}
#endif
}
break;
case 0x02: /* POP */ case 0x02: /* POP */
__asm__("evaluxn_02_POP:"); __asm__("evaluxn_02_POP:");
{ {
@ -533,9 +532,9 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr -= 1; u->wst.ptr -= 1;
} }
break; break;
case 0x21: /* LIT2 */ case 0x20: /* LIT2 */
case 0xa1: /* LIT2k */ case 0xa0: /* LIT2k */
__asm__("evaluxn_21_LIT2:"); __asm__("evaluxn_20_LIT2:");
{ {
u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++); u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++); u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
@ -548,6 +547,20 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr += 2; u->wst.ptr += 2;
} }
break; break;
case 0x21: /* INC2 */
__asm__("evaluxn_21_INC2:");
{
Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
u->wst.dat[u->wst.ptr - 2] = (a + 1) >> 8;
u->wst.dat[u->wst.ptr - 1] = (a + 1) & 0xff;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 2, 0)) {
u->wst.error = 1;
goto error;
}
#endif
}
break;
case 0x22: /* POP2 */ case 0x22: /* POP2 */
__asm__("evaluxn_22_POP2:"); __asm__("evaluxn_22_POP2:");
{ {
@ -1035,9 +1048,9 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr -= 1; u->wst.ptr -= 1;
} }
break; break;
case 0x41: /* LITr */ case 0x40: /* LITr */
case 0xc1: /* LITkr */ case 0xc0: /* LITkr */
__asm__("evaluxn_41_LITr:"); __asm__("evaluxn_40_LITr:");
{ {
u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++); u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
#ifndef NO_STACK_CHECKS #ifndef NO_STACK_CHECKS
@ -1049,6 +1062,19 @@ uxn_eval(Uxn *u, Uint16 vec)
u->rst.ptr += 1; u->rst.ptr += 1;
} }
break; break;
case 0x41: /* INCr */
__asm__("evaluxn_41_INCr:");
{
Uint8 a = u->rst.dat[u->rst.ptr - 1];
u->rst.dat[u->rst.ptr - 1] = a + 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 1, 0)) {
u->rst.error = 1;
goto error;
}
#endif
}
break;
case 0x42: /* POPr */ case 0x42: /* POPr */
__asm__("evaluxn_42_POPr:"); __asm__("evaluxn_42_POPr:");
{ {
@ -1501,9 +1527,9 @@ uxn_eval(Uxn *u, Uint16 vec)
u->rst.ptr -= 1; u->rst.ptr -= 1;
} }
break; break;
case 0x61: /* LIT2r */ case 0x60: /* LIT2r */
case 0xe1: /* LIT2kr */ case 0xe0: /* LIT2kr */
__asm__("evaluxn_61_LIT2r:"); __asm__("evaluxn_60_LIT2r:");
{ {
u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++); u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++); u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
@ -1516,6 +1542,20 @@ uxn_eval(Uxn *u, Uint16 vec)
u->rst.ptr += 2; u->rst.ptr += 2;
} }
break; break;
case 0x61: /* INC2r */
__asm__("evaluxn_61_INC2r:");
{
Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
u->rst.dat[u->rst.ptr - 2] = (a + 1) >> 8;
u->rst.dat[u->rst.ptr - 1] = (a + 1) & 0xff;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 2, 0)) {
u->rst.error = 1;
goto error;
}
#endif
}
break;
case 0x62: /* POP2r */ case 0x62: /* POP2r */
__asm__("evaluxn_62_POP2r:"); __asm__("evaluxn_62_POP2r:");
{ {
@ -2003,6 +2043,24 @@ uxn_eval(Uxn *u, Uint16 vec)
u->rst.ptr -= 1; u->rst.ptr -= 1;
} }
break; break;
case 0x81: /* INCk */
__asm__("evaluxn_81_INCk:");
{
Uint8 a = u->wst.dat[u->wst.ptr - 1];
u->wst.dat[u->wst.ptr] = a + 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 1, 0)) {
u->wst.error = 1;
goto error;
}
if(__builtin_expect(u->wst.ptr > 254, 0)) {
u->wst.error = 2;
goto error;
}
#endif
u->wst.ptr += 1;
}
break;
case 0x82: /* POPk */ case 0x82: /* POPk */
__asm__("evaluxn_82_POPk:"); __asm__("evaluxn_82_POPk:");
{ {
@ -2526,6 +2584,25 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr += 1; u->wst.ptr += 1;
} }
break; break;
case 0xa1: /* INC2k */
__asm__("evaluxn_a1_INC2k:");
{
Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
u->wst.dat[u->wst.ptr] = (a + 1) >> 8;
u->wst.dat[u->wst.ptr + 1] = (a + 1) & 0xff;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 2, 0)) {
u->wst.error = 1;
goto error;
}
if(__builtin_expect(u->wst.ptr > 253, 0)) {
u->wst.error = 2;
goto error;
}
#endif
u->wst.ptr += 2;
}
break;
case 0xa2: /* POP2k */ case 0xa2: /* POP2k */
__asm__("evaluxn_a2_POP2k:"); __asm__("evaluxn_a2_POP2k:");
{ {
@ -3073,6 +3150,24 @@ uxn_eval(Uxn *u, Uint16 vec)
u->wst.ptr += 2; u->wst.ptr += 2;
} }
break; break;
case 0xc1: /* INCkr */
__asm__("evaluxn_c1_INCkr:");
{
Uint8 a = u->rst.dat[u->rst.ptr - 1];
u->rst.dat[u->rst.ptr] = a + 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 1, 0)) {
u->rst.error = 1;
goto error;
}
if(__builtin_expect(u->rst.ptr > 254, 0)) {
u->rst.error = 2;
goto error;
}
#endif
u->rst.ptr += 1;
}
break;
case 0xc2: /* POPkr */ case 0xc2: /* POPkr */
__asm__("evaluxn_c2_POPkr:"); __asm__("evaluxn_c2_POPkr:");
{ {
@ -3596,6 +3691,25 @@ uxn_eval(Uxn *u, Uint16 vec)
u->rst.ptr += 1; u->rst.ptr += 1;
} }
break; break;
case 0xe1: /* INC2kr */
__asm__("evaluxn_e1_INC2kr:");
{
Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
u->rst.dat[u->rst.ptr] = (a + 1) >> 8;
u->rst.dat[u->rst.ptr + 1] = (a + 1) & 0xff;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 2, 0)) {
u->rst.error = 1;
goto error;
}
if(__builtin_expect(u->rst.ptr > 253, 0)) {
u->rst.error = 2;
goto error;
}
#endif
u->rst.ptr += 2;
}
break;
case 0xe2: /* POP2kr */ case 0xe2: /* POP2kr */
__asm__("evaluxn_e2_POP2kr:"); __asm__("evaluxn_e2_POP2kr:");
{ {

View File

@ -33,8 +33,8 @@ Uint16 mempeek16(Uint8 *m, Uint16 a) { return (mempeek8(m, a) << 8) + mempeek8(m
static void devpoke16(Device *d, Uint8 a, Uint16 b) { devpoke8(d, a, b >> 8); devpoke8(d, a + 1, b); } static void devpoke16(Device *d, Uint8 a, Uint16 b) { devpoke8(d, a, b >> 8); devpoke8(d, a + 1, b); }
static Uint16 devpeek16(Device *d, Uint16 a) { return (devpeek8(d, a) << 8) + devpeek8(d, a + 1); } static Uint16 devpeek16(Device *d, Uint16 a) { return (devpeek8(d, a) << 8) + devpeek8(d, a + 1); }
/* Stack */ /* Stack */
static void op_brk(Uxn *u) { u->ram.ptr = 0; }
static void op_lit(Uxn *u) { push8(u->src, mempeek8(u->ram.dat, u->ram.ptr++)); } static void op_lit(Uxn *u) { push8(u->src, mempeek8(u->ram.dat, u->ram.ptr++)); }
static void op_inc(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, a + 1); }
static void op_pop(Uxn *u) { pop8(u->src); } static void op_pop(Uxn *u) { pop8(u->src); }
static void op_dup(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, a); push8(u->src, a); } static void op_dup(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, a); push8(u->src, a); }
static void op_nip(Uxn *u) { Uint8 a = pop8(u->src); pop8(u->src); push8(u->src, a); } static void op_nip(Uxn *u) { Uint8 a = pop8(u->src); pop8(u->src); push8(u->src, a); }
@ -70,6 +70,7 @@ static void op_eor(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->
static void op_sft(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b >> (a & 0x07) << ((a & 0x70) >> 4)); } static void op_sft(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b >> (a & 0x07) << ((a & 0x70) >> 4)); }
/* Stack */ /* Stack */
static void op_lit16(Uxn *u) { push16(u->src, mempeek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; } static void op_lit16(Uxn *u) { push16(u->src, mempeek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; }
static void op_inc16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, a + 1); }
static void op_pop16(Uxn *u) { pop16(u->src); } static void op_pop16(Uxn *u) { pop16(u->src); }
static void op_dup16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, a); push16(u->src, a); } static void op_dup16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, a); push16(u->src, a); }
static void op_nip16(Uxn *u) { Uint16 a = pop16(u->src); pop16(u->src); push16(u->src, a); } static void op_nip16(Uxn *u) { Uint16 a = pop16(u->src); pop16(u->src); push16(u->src, a); }
@ -105,12 +106,12 @@ static void op_eor16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push
static void op_sft16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); push16(u->src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)); } static void op_sft16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); push16(u->src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)); }
static void (*ops[])(Uxn *u) = { static void (*ops[])(Uxn *u) = {
op_brk, op_lit, op_pop, op_dup, op_nip, op_swp, op_ovr, op_rot, op_lit, op_inc, op_pop, op_dup, op_nip, op_swp, op_ovr, op_rot,
op_equ, op_neq, op_gth, op_lth, op_jmp, op_jnz, op_jsr, op_sth, op_equ, op_neq, op_gth, op_lth, op_jmp, op_jnz, op_jsr, op_sth,
op_pek, op_pok, op_ldr, op_str, op_lda, op_sta, op_dei, op_deo, op_pek, op_pok, op_ldr, op_str, op_lda, op_sta, op_dei, op_deo,
op_add, op_sub, op_mul, op_div, op_and, op_ora, op_eor, op_sft, op_add, op_sub, op_mul, op_div, op_and, op_ora, op_eor, op_sft,
/* 16-bit */ /* 16-bit */
op_brk, op_lit16, op_pop16, op_dup16, op_nip16, op_swp16, op_ovr16, op_rot16, op_lit16, op_inc16, op_pop16, op_dup16, op_nip16, op_swp16, op_ovr16, op_rot16,
op_equ16, op_neq16, op_gth16, op_lth16, op_jmp16, op_jnz16, op_jsr16, op_sth16, op_equ16, op_neq16, op_gth16, op_lth16, op_jmp16, op_jnz16, op_jsr16, op_sth16,
op_pek16, op_pok16, op_ldr16, op_str16, op_lda16, op_sta16, op_dei16, op_deo16, op_pek16, op_pok16, op_ldr16, op_str16, op_lda16, op_sta16, op_dei16, op_deo16,
op_add16, op_sub16, op_mul16, op_div16, op_and16, op_ora16, op_eor16, op_sft16 op_add16, op_sub16, op_mul16, op_div16, op_and16, op_ora16, op_eor16, op_sft16
@ -123,12 +124,12 @@ static void (*ops[])(Uxn *u) = {
int int
uxn_eval(Uxn *u, Uint16 vec) uxn_eval(Uxn *u, Uint16 vec)
{ {
Uint8 instr;
if(u->dev[0].dat[0xf]) if(u->dev[0].dat[0xf])
return 0; return 0;
u->ram.ptr = vec; u->ram.ptr = vec;
if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
while(u->ram.ptr) { while((instr = u->ram.dat[u->ram.ptr++])) {
Uint8 instr = u->ram.dat[u->ram.ptr++];
/* Return Mode */ /* Return Mode */
if(instr & MODE_RETURN) { if(instr & MODE_RETURN) {
u->src = &u->rst; u->src = &u->rst;

View File

@ -40,7 +40,7 @@ Program p;
/* clang-format off */ /* clang-format off */
static char ops[][4] = { static char ops[][4] = {
"BRK", "LIT", "POP", "DUP", "NIP", "SWP", "OVR", "ROT", "LIT", "INC", "POP", "DUP", "NIP", "SWP", "OVR", "ROT",
"EQU", "NEQ", "GTH", "LTH", "JMP", "JCN", "JSR", "STH", "EQU", "NEQ", "GTH", "LTH", "JMP", "JCN", "JSR", "STH",
"LDZ", "STZ", "LDR", "STR", "LDA", "STA", "DEI", "DEO", "LDZ", "STZ", "LDR", "STR", "LDA", "STA", "DEI", "DEO",
"ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT" "ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT"
@ -62,7 +62,7 @@ static char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); whi
static void static void
pushbyte(Uint8 b, int lit) pushbyte(Uint8 b, int lit)
{ {
if(lit) pushbyte(0x01, 0); if(lit) pushbyte(0x80, 0);
p.data[p.ptr++] = b; p.data[p.ptr++] = b;
p.length = p.ptr; p.length = p.ptr;
} }
@ -70,7 +70,7 @@ pushbyte(Uint8 b, int lit)
static void static void
pushshort(Uint16 s, int lit) pushshort(Uint16 s, int lit)
{ {
if(lit) pushbyte(0x21, 0); if(lit) pushbyte(0x20, 0);
pushbyte((s >> 8) & 0xff, 0); pushbyte((s >> 8) & 0xff, 0);
pushbyte(s & 0xff, 0); pushbyte(s & 0xff, 0);
} }
@ -123,6 +123,7 @@ findopcode(char *s)
return 0; /* failed to match */ return 0; /* failed to match */
m++; m++;
} }
if(!i) i |= (1 << 7); /* force LIT nonzero (keep is ignored) */
return i; return i;
} }
return 0; return 0;
@ -152,7 +153,7 @@ makemacro(char *name, FILE *f)
return error("Macro duplicate", name); return error("Macro duplicate", name);
if(sihx(name) && slen(name) % 2 == 0) if(sihx(name) && slen(name) % 2 == 0)
return error("Macro name is hex number", name); return error("Macro name is hex number", name);
if(findopcode(name) || !slen(name)) if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
return error("Macro name is invalid", name); return error("Macro name is invalid", name);
m = &p.macros[p.mlen++]; m = &p.macros[p.mlen++];
scpy(name, m->name, 64); scpy(name, m->name, 64);
@ -176,7 +177,7 @@ makelabel(char *name, Uint16 addr)
return error("Label duplicate", name); return error("Label duplicate", name);
if(sihx(name) && slen(name) % 2 == 0) if(sihx(name) && slen(name) % 2 == 0)
return error("Label name is hex number", name); return error("Label name is hex number", name);
if(findopcode(name) || !slen(name)) if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
return error("Label name is invalid", name); return error("Label name is invalid", name);
l = &p.labels[p.llen++]; l = &p.labels[p.llen++];
l->addr = addr; l->addr = addr;
@ -246,7 +247,10 @@ parsetoken(char *w)
} else if(w[0] == ';' && (l = findlabel(w + 1))) { /* absolute */ } else if(w[0] == ';' && (l = findlabel(w + 1))) { /* absolute */
pushshort(l->addr, 1); pushshort(l->addr, 1);
return ++l->refs; return ++l->refs;
} else if(findopcode(w) || scmp(w, "BRK", 4)) { /* opcode */ } else if(scmp(w, "BRK", 4)) { /* special BRK opcode */
pushbyte(0, 0);
return 1;
} else if(findopcode(w)) { /* opcode */
pushbyte(findopcode(w), 0); pushbyte(findopcode(w), 0);
return 1; return 1;
} else if(w[0] == '"') { /* string */ } else if(w[0] == '"') { /* string */