diff --git a/assembler.c b/assembler.c index f2f2104..bc363de 100644 --- a/assembler.c +++ b/assembler.c @@ -35,8 +35,8 @@ Program p; char ops[][4] = { "BRK", "NOP", "LIT", "---", "IOR", "IOW", "LDR", "STR", - "JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---", - "POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL", + "JMP", "JSR", "---", "RTS", "AND", "ORA", "ROL", "ROR", + "POP", "DUP", "SWP", "OVR", "ROT", "WSR", "RSW", "---", "ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" }; diff --git a/build.sh b/build.sh index 400d835..7dc1761 100755 --- a/build.sh +++ b/build.sh @@ -24,5 +24,5 @@ rm -f ./bin/emulator cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator # run -./bin/assembler examples/sprite.usm bin/boot.rom +./bin/assembler examples/controller.usm bin/boot.rom ./bin/emulator bin/boot.rom diff --git a/emulator.c b/emulator.c index 72f3a1a..000c98d 100644 --- a/emulator.c +++ b/emulator.c @@ -330,11 +330,6 @@ main(int argc, char **argv) devmouse = portuxn(&u, "mouse", defaultrw, defaultrw); start(&u); - - echos(&u.wst, 0x40, "stack"); - echom(&u.ram, 0x40, "ram"); - echof(&u); - quit(); return 0; } diff --git a/examples/controller.usm b/examples/controller.usm index 1e07106..055058d 100644 --- a/examples/controller.usm +++ b/examples/controller.usm @@ -23,18 +23,27 @@ BRK |c000 @FRAME - #00 IOR #10 NEQ ,next0 ROT JMP? POP2 - ~y #0001 SUB2 =y + #05 =dev/r ( set dev/read to mouse ) + + #04 IOR #01 NEQ ,next0 ROT JMP? POP2 + #00 IOR2 =x #02 IOR2 =y + @next0 - #00 IOR #20 NEQ ,next1 ROT JMP? POP2 + #03 =dev/r ( set dev/read to controller ) + + #00 IOR #10 NEQ ,next1 ROT JMP? POP2 + ~y #0001 SUB2 =y + @next1 + + #00 IOR #20 NEQ ,next2 ROT JMP? POP2 ~y #0001 ADD2 =y - @next1 - #00 IOR #40 NEQ ,next2 ROT JMP? POP2 + @next2 + #00 IOR #40 NEQ ,next3 ROT JMP? POP2 ~x #0001 SUB2 =x - @next2 + @next3 #00 IOR #80 NEQ ,end ROT JMP? POP2 ~x #0001 ADD2 =x diff --git a/examples/test.usm b/examples/test.usm index f0ce8f0..d5c5c66 100644 --- a/examples/test.usm +++ b/examples/test.usm @@ -3,21 +3,19 @@ :dev/r fff8 ( std read port ) :dev/w fff9 ( std write port ) -:test 0010 - ;x 1 ;y 2 |0100 @RESET - #12 =x - #1234 =y - ~x - ~y - - #ef =test + #12 #34 WSR2 + RSW2 + ,test JSR BRK +@test + RTS + |c000 @FRAME BRK |d000 @ERROR BRK diff --git a/uxn.c b/uxn.c index 8404e8b..5ad7ae1 100644 --- a/uxn.c +++ b/uxn.c @@ -18,6 +18,7 @@ WITH REGARD TO THIS SOFTWARE. /* clang-format off */ void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); } int getflag(Uint8 *a, char flag) { return *a & flag; } +void warn(char *s, Uint8 b) { printf("Warning: %s(%d)\n", s, b);} void mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; } Uint8 mempeek8(Memory *m, Uint16 a) { return m->dat[a]; } void mempoke16(Memory *m, Uint16 a, Uint16 b) { mempoke8(m, a, b >> 8); mempoke8(m, a + 1, b); } @@ -39,17 +40,20 @@ void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); } /* Logic */ void op_jmp(Uxn *u) { u->ram.ptr = pop16(&u->wst); } -void op_jsr(Uxn *u) { push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); } -void op_rts(Uxn *u) { u->ram.ptr = pop16(&u->rst); } +void op_jsr(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); } +void op_rts(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } u->ram.ptr = pop16(&u->rst); } +void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); } +void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); } +void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); } +void op_ror(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b >> a); } /* Stack */ void op_pop(Uxn *u) { pop8(&u->wst); } void op_dup(Uxn *u) { push8(&u->wst, peek8(&u->wst, 0)); } void op_swp(Uxn *u) { Uint8 b = pop8(&u->wst), a = pop8(&u->wst); push8(&u->wst, b); push8(&u->wst, a); } void op_ovr(Uxn *u) { push8(&u->wst, peek8(&u->wst, 1)); } void op_rot(Uxn *u) { Uint8 c = pop8(&u->wst), b = pop8(&u->wst), a = pop8(&u->wst); push8(&u->wst, b); push8(&u->wst, c); push8(&u->wst, a); } -void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); } -void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); } -void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); } +void op_wsr(Uxn *u) { Uint8 a = pop8(&u->wst); push8(&u->rst, a); u->balance++; } +void op_rsw(Uxn *u) { Uint8 a = pop8(&u->rst); push8(&u->wst, a); u->balance--; } /* Arithmetic */ void op_add(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b + (Sint8)a : b + a); } void op_sub(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b - (Sint8)a : b - a); } @@ -66,15 +70,18 @@ void op_ior16(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8( void op_iow16(Uxn *u) { Uint8 a = pop8(&u->wst); Uint8 b = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) { dev->write(dev, &u->ram, b); dev->write(dev, &u->ram, a); } } void op_ldr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->wst, mempeek16(&u->ram, a)); } void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); } +void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b & a); } +void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); } +void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); } +void op_ror16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b >> a); } /* Stack(16-bits) */ void op_pop16(Uxn *u) { pop16(&u->wst); } void op_dup16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 0)); } void op_swp16(Uxn *u) { Uint16 b = pop16(&u->wst), a = pop16(&u->wst); push16(&u->wst, b); push16(&u->wst, a); } void op_ovr16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 1)); } void op_rot16(Uxn *u) { Uint16 c = pop16(&u->wst), b = pop16(&u->wst), a = pop16(&u->wst); push16(&u->wst, b); push16(&u->wst, c); push16(&u->wst, a); } -void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b & a); } -void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); } -void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); } +void op_wsr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->rst, a); u->balance += 2; } +void op_rsw16(Uxn *u) { Uint16 a = pop16(&u->rst); push16(&u->wst, a); u->balance -= 2; } /* Arithmetic(16-bits) */ void op_add16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b + (Sint16)a : b + a); } void op_sub16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b - (Sint16)a : b - a); } @@ -87,25 +94,25 @@ void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u- void (*ops[])(Uxn *u) = { op_brk, op_nop, op_lit, op_lix, op_ior, op_iow, op_ldr, op_str, - op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, - op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, + op_jmp, op_jsr, op_nop, op_rts, op_and, op_ora, op_rol, op_ror, + op_pop, op_dup, op_swp, op_ovr, op_rot, op_wsr, op_rsw, op_nop, op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, /* 16-bit */ op_brk, op_nop16, op_lit16, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, - op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, - op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16, + op_jmp, op_jsr, op_nop, op_rts, op_and16, op_ora16, op_rol16, op_ror16, + op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_wsr16, op_rsw16, op_nop, op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16 }; Uint8 opr[][2] = { {0,0}, {0,0}, {0,0}, {0,0}, {1,1}, {1,0}, {2,1}, {3,0}, - {2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, - {1,0}, {1,2}, {2,2}, {2,3}, {3,3}, {2,1}, {2,1}, {2,1}, + {2,0}, {2,0}, {0,0}, {0,0}, {2,1}, {2,1}, {2,1}, {2,1}, + {1,0}, {1,2}, {2,2}, {2,3}, {3,3}, {1,0}, {0,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, /* 16-bit */ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */ - {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */ + {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {0,0}, /* TODO */ {4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2} }; diff --git a/uxn.h b/uxn.h index 74d7e34..ca03027 100644 --- a/uxn.h +++ b/uxn.h @@ -38,7 +38,7 @@ typedef struct Device { } Device; typedef struct { - Uint8 literal, status, devices; + Uint8 literal, status, balance, devices; Uint16 counter, devr, devw, vreset, vframe, verror; St8 wst, rst; Memory ram;