Removed DEI/DEO from uxn-tnl core

This commit is contained in:
neauoire 2023-08-08 09:23:11 -07:00
parent fda12df0f1
commit a1d2bfbbb0
6 changed files with 154 additions and 111 deletions

View File

@ -1,104 +0,0 @@
#include <stdio.h>
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define HALT(c) { return emu_halt(u, instr, (c), pc - 1); }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define PUSH8(x) { if(s->ptr == 0xff) HALT(2) s->dat[s->ptr++] = (x); }
#define PUSH16(x) { if((tsp = s->ptr) >= 0xfe) HALT(2) t = (x); POKE2(&s->dat[tsp], t); s->ptr = tsp + 2; }
#define PUSH(x) { if(m2) { PUSH16(x) } else { PUSH8(x) } }
#define POP8(o) { if(*sp == 0x00) HALT(1) o = s->dat[--*sp]; }
#define POP16(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; }
#define POP(o) { if(m2) { POP16(o) } else { POP8(o) } }
#define POKE(x, y) { if(m2) { t = (y); POKE2(u->ram + x, t) } else { u->ram[(x)] = (y); } }
#define PEEK(o, x) { if(m2) { o = PEEK2(u->ram + x); } else o = u->ram[(x)]; }
#define DEI(port) { }
#define DEO(port, value) { u->dev[(port)] = (value); if((deo_mask[(port) >> 4] >> ((port) & 0xf)) & 0x1) emu_deo(u, (port)); }
#define DEVR(dest, port) { if(m2) { dest = (emu_dei(u, (port)) << 8) + emu_dei(u, (port+1)); } else { dest = emu_dei(u, (port)); } }
#define DEVW(port, value) { if(m2) { DEO((port),(value >> 8)) DEO((port+1),(value)) } else { DEO((port),(value)) } }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 instr, opcode, m2, ksp, tsp, *sp;
Uint16 a, b, c, t;
Stack *s;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
instr = u->ram[pc++];
/* printf("%02x\n", instr); */
opcode = instr & 0x1f;
/* Short Mode */
m2 = instr & 0x20;
/* Return Mode */
s = instr & 0x40 ? &u->rst : &u->wst;
/* Keep Mode */
if(instr & 0x80) { ksp = s->ptr; sp = &ksp; }
else sp = &s->ptr;
/* Opcodes */
switch(opcode - (!opcode * (instr >> 5))) {
/* Immediate */
case -0x0: /* BRK */ return 1;
case -0x1: /* JCI */ POP8(b) if(!b) { pc += 2; break; } /* else fallthrough */
case -0x2: /* JMI */ pc += PEEK2(u->ram + pc) + 2; break;
case -0x3: /* JSI */ s = &u->rst; PUSH16(pc + 2) pc += PEEK2(u->ram + pc) + 2; break;
case -0x4: /* LIT */
case -0x6: /* LITr */ a = u->ram[pc++]; PUSH8(a) break;
case -0x5: /* LIT2 */
case -0x7: /* LIT2r */ PUSH16(PEEK2(u->ram + pc)) pc += 2; break;
/* ALU */
case 0x01: /* INC */ POP(a) PUSH(a + 1) break;
case 0x02: /* POP */ POP(a) break;
case 0x03: /* NIP */ POP(a) POP(b) PUSH(a) break;
case 0x04: /* SWP */ POP(a) POP(b) PUSH(a) PUSH(b) break;
case 0x05: /* ROT */ POP(a) POP(b) POP(c) PUSH(b) PUSH(a) PUSH(c) break;
case 0x06: /* DUP */ POP(a) PUSH(a) PUSH(a) break;
case 0x07: /* OVR */ POP(a) POP(b) PUSH(b) PUSH(a) PUSH(b) break;
case 0x08: /* EQU */ POP(a) POP(b) PUSH8(b == a) break;
case 0x09: /* NEQ */ POP(a) POP(b) PUSH8(b != a) break;
case 0x0a: /* GTH */ POP(a) POP(b) PUSH8(b > a) break;
case 0x0b: /* LTH */ POP(a) POP(b) PUSH8(b < a) break;
case 0x0c: /* JMP */ POP(a) JUMP(a) break;
case 0x0d: /* JCN */ POP(a) POP8(b) if(b) JUMP(a) break;
case 0x0e: /* JSR */ POP(a) s = (instr & 0x40) ? &u->wst : &u->rst; PUSH16(pc) JUMP(a) break;
case 0x0f: /* STH */ POP(a) s = (instr & 0x40) ? &u->wst : &u->rst; PUSH(a) break;
case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(b) break;
case 0x11: /* STZ */ POP8(a) POP(b) POKE(a, b) break;
case 0x12: /* LDR */ POP8(a) PEEK(b, pc + (Sint8)a) PUSH(b) break;
case 0x13: /* STR */ POP8(a) POP(b) POKE(pc + (Sint8)a, b) break;
case 0x14: /* LDA */ POP16(a) PEEK(b, a) PUSH(b) break;
case 0x15: /* STA */ POP16(a) POP(b) POKE(a, b) break;
case 0x16: /* DEI */ POP8(a) DEVR(b, a) PUSH(b) break;
case 0x17: /* DEO */ POP8(a) POP(b) DEVW(a, b) break;
case 0x18: /* ADD */ POP(a) POP(b) PUSH(b + a) break;
case 0x19: /* SUB */ POP(a) POP(b) PUSH(b - a) break;
case 0x1a: /* MUL */ POP(a) POP(b) PUSH((Uint32)b * a) break;
case 0x1b: /* DIV */ POP(a) POP(b) if(!a) HALT(3) PUSH(b / a) break;
case 0x1c: /* AND */ POP(a) POP(b) PUSH(b & a) break;
case 0x1d: /* ORA */ POP(a) POP(b) PUSH(b | a) break;
case 0x1e: /* EOR */ POP(a) POP(b) PUSH(b ^ a) break;
case 0x1f: /* SFT */ POP8(a) POP(b) PUSH(b >> (a & 0x0f) << ((a & 0xf0) >> 4)) break;
}
}
}
int
uxn_boot(Uxn *u, Uint8 *ram)
{
Uint32 i;
char *cptr = (char *)u;
for(i = 0; i < sizeof(*u); i++)
cptr[i] = 0;
u->ram = ram;
return 1;
}

98
etc/cores/uxn-abc.c Normal file
View File

@ -0,0 +1,98 @@
#include "uxn.h"
/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define HALT(c) { return emu_halt(u, ins, (c), pc - 1); }
#define FLIP { s = ins & 0x40 ? &u->wst : &u->rst; }
#define JUMP(x) { if(m2) pc = (x); else pc += (Sint8)(x); }
#define POKE(x, y) { if(m2) { POKE2(ram + x, y) } else { ram[(x)] = (y); } }
#define PEEK(o, x) { if(m2) { o = PEEK2(ram + x); } else o = ram[(x)]; }
#define PUSH1(y) { if(s->ptr == 0xff) HALT(2) s->dat[s->ptr++] = (y); }
#define PUSH2(y) { if((tsp = s->ptr) >= 0xfe) HALT(2) t = (y); POKE2(&s->dat[tsp], t); s->ptr = tsp + 2; }
#define PUSHx(y) { if(m2) { PUSH2(y) } else { PUSH1(y) } }
#define POP1(o) { if(*sp == 0x00) HALT(1) o = s->dat[--*sp]; }
#define POP2(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; }
#define POPx(o) { if(m2) { POP2(o) } else { POP1(o) } }
#define DEVW(p, y) { if(m2) { DEO(p, y >> 8) DEO((p + 1), y) } else { DEO(p, y) } }
#define DEVR(o, p) { if(m2) { o = ((DEI(p) << 8) + DEI(p + 1)); } else { o = DEI(p); } }
int
uxn_eval(Uxn *u, Uint16 pc)
{
Uint8 ins, opc, m2, ksp, tsp, *sp, *ram = u->ram;
Uint16 a, b, c, t;
Stack *s;
if(!pc || u->dev[0x0f]) return 0;
for(;;) {
ins = ram[pc++];
/* modes */
opc = ins & 0x1f;
m2 = ins & 0x20;
s = ins & 0x40 ? &u->rst : &u->wst;
if(ins & 0x80) { ksp = s->ptr; sp = &ksp; } else sp = &s->ptr;
/* Opcodes */
switch(opc - (!opc * (ins >> 5))) {
/* Immediate */
case -0x0: /* BRK */ return 1;
case -0x1: /* JCI */ POP1(b) if(!b) { pc += 2; break; } /* else fallthrough */
case -0x2: /* JMI */ pc += PEEK2(ram + pc) + 2; break;
case -0x3: /* JSI */ PUSH2(pc + 2) pc += PEEK2(ram + pc) + 2; break;
case -0x4: /* LIT */
case -0x6: /* LITr */ PUSH1(ram[pc++]) break;
case -0x5: /* LIT2 */
case -0x7: /* LIT2r */ PUSH2(PEEK2(ram + pc)) pc += 2; break;
/* ALU */
case 0x01: /* INC */ POPx(a) PUSHx(a + 1) break;
case 0x02: /* POP */ POPx(a) break;
case 0x03: /* NIP */ POPx(a) POPx(b) PUSHx(a) break;
case 0x04: /* SWP */ POPx(a) POPx(b) PUSHx(a) PUSHx(b) break;
case 0x05: /* ROT */ POPx(a) POPx(b) POPx(c) PUSHx(b) PUSHx(a) PUSHx(c) break;
case 0x06: /* DUP */ POPx(a) PUSHx(a) PUSHx(a) break;
case 0x07: /* OVR */ POPx(a) POPx(b) PUSHx(b) PUSHx(a) PUSHx(b) break;
case 0x08: /* EQU */ POPx(a) POPx(b) PUSH1(b == a) break;
case 0x09: /* NEQ */ POPx(a) POPx(b) PUSH1(b != a) break;
case 0x0a: /* GTH */ POPx(a) POPx(b) PUSH1(b > a) break;
case 0x0b: /* LTH */ POPx(a) POPx(b) PUSH1(b < a) break;
case 0x0c: /* JMP */ POPx(a) JUMP(a) break;
case 0x0d: /* JCN */ POPx(a) POP1(b) if(b) JUMP(a) break;
case 0x0e: /* JSR */ POPx(a) FLIP PUSH2(pc) JUMP(a) break;
case 0x0f: /* STH */ POPx(a) FLIP PUSHx(a) break;
case 0x10: /* LDZ */ POP1(a) PEEK(b, a) PUSHx(b) break;
case 0x11: /* STZ */ POP1(a) POPx(b) POKE(a, b) break;
case 0x12: /* LDR */ POP1(a) PEEK(b, pc + (Sint8)a) PUSHx(b) break;
case 0x13: /* STR */ POP1(a) POPx(b) POKE(pc + (Sint8)a, b) break;
case 0x14: /* LDA */ POP2(a) PEEK(b, a) PUSHx(b) break;
case 0x15: /* STA */ POP2(a) POPx(b) POKE(a, b) break;
case 0x16: /* DEI */ POP1(a) DEVR(b, a) PUSHx(b) break;
case 0x17: /* DEO */ POP1(a) POPx(b) DEVW(a, b) break;
case 0x18: /* ADD */ POPx(a) POPx(b) PUSHx(b + a) break;
case 0x19: /* SUB */ POPx(a) POPx(b) PUSHx(b - a) break;
case 0x1a: /* MUL */ POPx(a) POPx(b) PUSHx((Uint32)b * a) break;
case 0x1b: /* DIV */ POPx(a) POPx(b) if(!a) HALT(3) PUSHx(b / a) break;
case 0x1c: /* AND */ POPx(a) POPx(b) PUSHx(b & a) break;
case 0x1d: /* ORA */ POPx(a) POPx(b) PUSHx(b | a) break;
case 0x1e: /* EOR */ POPx(a) POPx(b) PUSHx(b ^ a) break;
case 0x1f: /* SFT */ POP1(a) POPx(b) PUSHx(b >> (a & 0xf) << (a >> 4)) break;
}
}
}
int
uxn_boot(Uxn *u, Uint8 *ram)
{
Uint32 i;
char *cptr = (char *)u;
for(i = 0; i < sizeof(*u); i++)
cptr[i] = 0;
u->ram = ram;
return 1;
}

View File

@ -30,8 +30,6 @@ WITH REGARD TO THIS SOFTWARE.
#define SET(x, y) { if(x > s->ptr) HALT(1) tmp = (x & k) + y + s->ptr; if(tmp > 254) HALT(2) s->ptr = tmp; } #define SET(x, y) { if(x > s->ptr) HALT(1) tmp = (x & k) + y + s->ptr; if(tmp > 254) HALT(2) s->ptr = tmp; }
#define PUT(o, v) { s->dat[(s->ptr - 1 - (o))] = (v); } #define PUT(o, v) { s->dat[(s->ptr - 1 - (o))] = (v); }
#define PUT2(o, v) { tmp = (v); POKE2(s->dat + (s->ptr - o - 2), tmp); } #define PUT2(o, v) { tmp = (v); POKE2(s->dat + (s->ptr - o - 2), tmp); }
#define DEO(a, b) { u->dev[(a)] = (b); if((deo_mask[(a) >> 4] >> ((a) & 0xf)) & 0x1) emu_deo(u, (a)); }
#define DEI(a, b) { PUT((a), ((dei_mask[(b) >> 4] >> ((b) & 0xf)) & 0x1) ? emu_dei(u, (b)) : u->dev[(b)]) }
int int
uxn_eval(Uxn *u, Uint16 pc) uxn_eval(Uxn *u, Uint16 pc)
@ -98,10 +96,10 @@ uxn_eval(Uxn *u, Uint16 pc)
case 0x34: t=T2; SET(2, 0) PUT2(0, PEEK2(ram + t)) break; case 0x34: t=T2; SET(2, 0) PUT2(0, PEEK2(ram + t)) break;
case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break; case 0x15: /* STA */ t=T2;n=L; SET(3,-3) ram[t] = n; break;
case 0x35: t=T2;n=N2; SET(4,-4) POKE2(ram + t, n) break; case 0x35: t=T2;n=N2; SET(4,-4) POKE2(ram + t, n) break;
case 0x16: /* DEI */ t=T; SET(1, 0) DEI(0, t) break; case 0x16: /* DEI */ t=T; SET(1, 0) PUT(0, DEI(t)) break;
case 0x36: t=T; SET(1, 1) DEI(1, t) DEI(0, t + 1) break; case 0x36: t=T; SET(1, 1) PUT(1, DEI(t)) PUT(0, DEI(t + 1)) break;
case 0x17: /* DEO */ t=T;n=N; SET(2,-2) DEO(t, n) break; case 0x17: /* DEO */ t=T;n=N; SET(2,-2) DEO(t, n) break;
case 0x37: t=T;n=N;l=L; SET(3,-3) DEO(t, l) DEO(t + 1, n) break; case 0x37: t=T;n=N;l=L; SET(3,-3) DEO(t, l) DEO((t + 1), n) break;
case 0x18: /* ADD */ t=T;n=N; SET(2,-1) PUT(0, n + t) break; case 0x18: /* ADD */ t=T;n=N; SET(2,-1) PUT(0, n + t) break;
case 0x38: t=T2;n=N2; SET(4,-2) PUT2(0, n + t) break; case 0x38: t=T2;n=N2; SET(4,-2) PUT2(0, n + t) break;
case 0x19: /* SUB */ t=T;n=N; SET(2,-1) PUT(0, n - t) break; case 0x19: /* SUB */ t=T;n=N; SET(2,-1) PUT(0, n - t) break;

51
etc/cores/uxn.h Normal file
View File

@ -0,0 +1,51 @@
/*
Copyright (c) 2021 Devine Lu Linvega
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define PAGE_PROGRAM 0x0100
/* clang-format off */
#define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
#define PEEK2(d) ((d)[0] << 8 | (d)[1])
#define DEO(p, value) { u->dev[p] = value; if((deo_mask[p >> 4] >> (p & 0xf)) & 0x1) emu_deo(u, p); }
#define DEI(p) ((dei_mask[(p) >> 4] >> ((p) & 0xf)) & 0x1 ? emu_dei(u, (p)) : u->dev[(p)])
/* clang-format on */
typedef unsigned char Uint8;
typedef signed char Sint8;
typedef unsigned short Uint16;
typedef signed short Sint16;
typedef unsigned int Uint32;
typedef struct {
Uint8 dat[255], ptr;
} Stack;
typedef struct Uxn {
Uint8 *ram, dev[256];
Stack wst, rst;
Uint8 (*dei)(struct Uxn *u, Uint8 addr);
void (*deo)(struct Uxn *u, Uint8 addr);
} Uxn;
/* required functions */
extern Uint8 emu_dei(Uxn *u, Uint8 addr);
extern void emu_deo(Uxn *u, Uint8 addr);
extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr);
extern Uint16 dei_mask[];
extern Uint16 deo_mask[];
/* built-ins */
int uxn_boot(Uxn *u, Uint8 *ram);
int uxn_eval(Uxn *u, Uint16 pc);

View File

@ -23,7 +23,7 @@ WITH REGARD TO THIS SOFTWARE.
#define POP2(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; } #define POP2(o) { if((tsp = *sp) <= 0x01) HALT(1) o = PEEK2(&s->dat[tsp - 2]); *sp = tsp - 2; }
#define POPx(o) { if(m2) { POP2(o) } else { POP1(o) } } #define POPx(o) { if(m2) { POP2(o) } else { POP1(o) } }
#define DEVW(p, y) { if(m2) { DEO(p, y >> 8) DEO((p + 1), y) } else { DEO(p, y) } } #define DEVW(p, y) { if(m2) { DEO(p, y >> 8) DEO((p + 1), y) } else { DEO(p, y) } }
#define DEVR(o, p) { if(m2) { o = ((DEI(p) << 8) + DEI(p + 1)); } else { o = DEI(p); } } #define DEVR(o, p) { if(m2) { o = DEI(p) << 8 | DEI(p + 1); } else { o = DEI(p); } }
int int
uxn_eval(Uxn *u, Uint16 pc) uxn_eval(Uxn *u, Uint16 pc)

View File

@ -15,7 +15,7 @@ WITH REGARD TO THIS SOFTWARE.
#define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); } #define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
#define PEEK2(d) ((d)[0] << 8 | (d)[1]) #define PEEK2(d) ((d)[0] << 8 | (d)[1])
#define DEO(p, value) { u->dev[p] = value; if((deo_mask[p >> 4] >> (p & 0xf)) & 0x1) emu_deo(u, p); } #define DEO(p, v) { u->dev[p] = v; if((deo_mask[p >> 4] >> (p & 0xf)) & 0x1) emu_deo(u, p); }
#define DEI(p) ((dei_mask[(p) >> 4] >> ((p) & 0xf)) & 0x1 ? emu_dei(u, (p)) : u->dev[(p)]) #define DEI(p) ((dei_mask[(p) >> 4] >> ((p) & 0xf)) & 0x1 ? emu_dei(u, (p)) : u->dev[(p)])
/* clang-format on */ /* clang-format on */