| ... | ... |
@@ -35,8 +35,8 @@ Program p; |
| 35 | 35 |
|
| 36 | 36 |
char ops[][4] = {
|
| 37 | 37 |
"BRK", "NOP", "LIT", "---", "IOR", "IOW", "LDR", "STR", |
| 38 |
- "JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---", |
|
| 39 |
- "POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL", |
|
| 38 |
+ "JMP", "JSR", "---", "RTS", "AND", "ORA", "ROL", "ROR", |
|
| 39 |
+ "POP", "DUP", "SWP", "OVR", "ROT", "WSR", "RSW", "---", |
|
| 40 | 40 |
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" |
| 41 | 41 |
}; |
| 42 | 42 |
|
| ... | ... |
@@ -24,5 +24,5 @@ rm -f ./bin/emulator |
| 24 | 24 |
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 |
| 25 | 25 |
|
| 26 | 26 |
# run |
| 27 |
-./bin/assembler examples/sprite.usm bin/boot.rom |
|
| 27 |
+./bin/assembler examples/controller.usm bin/boot.rom |
|
| 28 | 28 |
./bin/emulator bin/boot.rom |
| ... | ... |
@@ -23,18 +23,27 @@ BRK |
| 23 | 23 |
|
| 24 | 24 |
|c000 @FRAME |
| 25 | 25 |
|
| 26 |
- #00 IOR #10 NEQ ,next0 ROT JMP? POP2 |
|
| 27 |
- ~y #0001 SUB2 =y |
|
| 26 |
+ #05 =dev/r ( set dev/read to mouse ) |
|
| 27 |
+ |
|
| 28 |
+ #04 IOR #01 NEQ ,next0 ROT JMP? POP2 |
|
| 29 |
+ #00 IOR2 =x #02 IOR2 =y |
|
| 30 |
+ |
|
| 28 | 31 |
@next0 |
| 29 | 32 |
|
| 30 |
- #00 IOR #20 NEQ ,next1 ROT JMP? POP2 |
|
| 31 |
- ~y #0001 ADD2 =y |
|
| 33 |
+ #03 =dev/r ( set dev/read to controller ) |
|
| 32 | 34 |
|
| 35 |
+ #00 IOR #10 NEQ ,next1 ROT JMP? POP2 |
|
| 36 |
+ ~y #0001 SUB2 =y |
|
| 33 | 37 |
@next1 |
| 34 |
- #00 IOR #40 NEQ ,next2 ROT JMP? POP2 |
|
| 35 |
- ~x #0001 SUB2 =x |
|
| 38 |
+ |
|
| 39 |
+ #00 IOR #20 NEQ ,next2 ROT JMP? POP2 |
|
| 40 |
+ ~y #0001 ADD2 =y |
|
| 36 | 41 |
|
| 37 | 42 |
@next2 |
| 43 |
+ #00 IOR #40 NEQ ,next3 ROT JMP? POP2 |
|
| 44 |
+ ~x #0001 SUB2 =x |
|
| 45 |
+ |
|
| 46 |
+ @next3 |
|
| 38 | 47 |
#00 IOR #80 NEQ ,end ROT JMP? POP2 |
| 39 | 48 |
~x #0001 ADD2 =x |
| 40 | 49 |
|
| ... | ... |
@@ -3,21 +3,19 @@ |
| 3 | 3 |
:dev/r fff8 ( std read port ) |
| 4 | 4 |
:dev/w fff9 ( std write port ) |
| 5 | 5 |
|
| 6 |
-:test 0010 |
|
| 7 |
- |
|
| 8 | 6 |
;x 1 ;y 2 |
| 9 | 7 |
|
| 10 | 8 |
|0100 @RESET |
| 11 | 9 |
|
| 12 |
- #12 =x |
|
| 13 |
- #1234 =y |
|
| 14 |
- ~x |
|
| 15 |
- ~y |
|
| 16 |
- |
|
| 17 |
- #ef =test |
|
| 10 |
+ #12 #34 WSR2 |
|
| 11 |
+ RSW2 |
|
| 12 |
+ ,test JSR |
|
| 18 | 13 |
|
| 19 | 14 |
BRK |
| 20 | 15 |
|
| 16 |
+@test |
|
| 17 |
+ RTS |
|
| 18 |
+ |
|
| 21 | 19 |
|c000 @FRAME BRK |
| 22 | 20 |
|d000 @ERROR BRK |
| 23 | 21 |
|
| ... | ... |
@@ -18,6 +18,7 @@ WITH REGARD TO THIS SOFTWARE. |
| 18 | 18 |
/* clang-format off */ |
| 19 | 19 |
void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); }
|
| 20 | 20 |
int getflag(Uint8 *a, char flag) { return *a & flag; }
|
| 21 |
+void warn(char *s, Uint8 b) { printf("Warning: %s(%d)\n", s, b);}
|
|
| 21 | 22 |
void mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; }
|
| 22 | 23 |
Uint8 mempeek8(Memory *m, Uint16 a) { return m->dat[a]; }
|
| 23 | 24 |
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
|
| 39 | 40 |
void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); }
|
| 40 | 41 |
/* Logic */ |
| 41 | 42 |
void op_jmp(Uxn *u) { u->ram.ptr = pop16(&u->wst); }
|
| 42 |
-void op_jsr(Uxn *u) { push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst); }
|
|
| 43 |
-void op_rts(Uxn *u) { u->ram.ptr = pop16(&u->rst); }
|
|
| 43 |
+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); }
|
|
| 44 |
+void op_rts(Uxn *u) { if(u->balance > 0){ warn("Stack unbalance", u->balance); } u->ram.ptr = pop16(&u->rst); }
|
|
| 45 |
+void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); }
|
|
| 46 |
+void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
|
|
| 47 |
+void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); }
|
|
| 48 |
+void op_ror(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b >> a); }
|
|
| 44 | 49 |
/* Stack */ |
| 45 | 50 |
void op_pop(Uxn *u) { pop8(&u->wst); }
|
| 46 | 51 |
void op_dup(Uxn *u) { push8(&u->wst, peek8(&u->wst, 0)); }
|
| 47 | 52 |
void op_swp(Uxn *u) { Uint8 b = pop8(&u->wst), a = pop8(&u->wst); push8(&u->wst, b); push8(&u->wst, a); }
|
| 48 | 53 |
void op_ovr(Uxn *u) { push8(&u->wst, peek8(&u->wst, 1)); }
|
| 49 | 54 |
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); }
|
| 50 |
-void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); }
|
|
| 51 |
-void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
|
|
| 52 |
-void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); }
|
|
| 55 |
+void op_wsr(Uxn *u) { Uint8 a = pop8(&u->wst); push8(&u->rst, a); u->balance++; }
|
|
| 56 |
+void op_rsw(Uxn *u) { Uint8 a = pop8(&u->rst); push8(&u->wst, a); u->balance--; }
|
|
| 53 | 57 |
/* Arithmetic */ |
| 54 | 58 |
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); }
|
| 55 | 59 |
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(
|
| 66 | 70 |
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); } }
|
| 67 | 71 |
void op_ldr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->wst, mempeek16(&u->ram, a)); }
|
| 68 | 72 |
void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); }
|
| 73 |
+void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b & a); }
|
|
| 74 |
+void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); }
|
|
| 75 |
+void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); }
|
|
| 76 |
+void op_ror16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b >> a); }
|
|
| 69 | 77 |
/* Stack(16-bits) */ |
| 70 | 78 |
void op_pop16(Uxn *u) { pop16(&u->wst); }
|
| 71 | 79 |
void op_dup16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 0)); }
|
| 72 | 80 |
void op_swp16(Uxn *u) { Uint16 b = pop16(&u->wst), a = pop16(&u->wst); push16(&u->wst, b); push16(&u->wst, a); }
|
| 73 | 81 |
void op_ovr16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 1)); }
|
| 74 | 82 |
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); }
|
| 75 |
-void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b & a); }
|
|
| 76 |
-void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); }
|
|
| 77 |
-void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); }
|
|
| 83 |
+void op_wsr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->rst, a); u->balance += 2; }
|
|
| 84 |
+void op_rsw16(Uxn *u) { Uint16 a = pop16(&u->rst); push16(&u->wst, a); u->balance -= 2; }
|
|
| 78 | 85 |
/* Arithmetic(16-bits) */ |
| 79 | 86 |
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); }
|
| 80 | 87 |
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-
|
| 87 | 94 |
|
| 88 | 95 |
void (*ops[])(Uxn *u) = {
|
| 89 | 96 |
op_brk, op_nop, op_lit, op_lix, op_ior, op_iow, op_ldr, op_str, |
| 90 |
- op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, |
|
| 91 |
- op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, |
|
| 97 |
+ op_jmp, op_jsr, op_nop, op_rts, op_and, op_ora, op_rol, op_ror, |
|
| 98 |
+ op_pop, op_dup, op_swp, op_ovr, op_rot, op_wsr, op_rsw, op_nop, |
|
| 92 | 99 |
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, |
| 93 | 100 |
/* 16-bit */ |
| 94 | 101 |
op_brk, op_nop16, op_lit16, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, |
| 95 |
- op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, |
|
| 96 |
- op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16, |
|
| 102 |
+ op_jmp, op_jsr, op_nop, op_rts, op_and16, op_ora16, op_rol16, op_ror16, |
|
| 103 |
+ op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_wsr16, op_rsw16, op_nop, |
|
| 97 | 104 |
op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16 |
| 98 | 105 |
}; |
| 99 | 106 |
|
| 100 | 107 |
Uint8 opr[][2] = {
|
| 101 | 108 |
{0,0}, {0,0}, {0,0}, {0,0}, {1,1}, {1,0}, {2,1}, {3,0},
|
| 102 |
- {2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
|
|
| 103 |
- {1,0}, {1,2}, {2,2}, {2,3}, {3,3}, {2,1}, {2,1}, {2,1},
|
|
| 109 |
+ {2,0}, {2,0}, {0,0}, {0,0}, {2,1}, {2,1}, {2,1}, {2,1},
|
|
| 110 |
+ {1,0}, {1,2}, {2,2}, {2,3}, {3,3}, {1,0}, {0,1}, {2,1},
|
|
| 104 | 111 |
{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
|
| 105 | 112 |
/* 16-bit */ |
| 106 | 113 |
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
|
| 107 | 114 |
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
|
| 108 |
- {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
|
|
| 115 |
+ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {0,0}, /* TODO */
|
|
| 109 | 116 |
{4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2}, {4,2}
|
| 110 | 117 |
}; |
| 111 | 118 |
|