| ... | ... |
@@ -31,7 +31,7 @@ Program p; |
| 31 | 31 |
/* clang-format off */ |
| 32 | 32 |
|
| 33 | 33 |
char ops[][4] = {
|
| 34 |
- "BRK", "---", "LI1", "LIX", "IOR", "IOW", "LDR", "STR", |
|
| 34 |
+ "BRK", "NOP", "LI1", "LIX", "IOR", "IOW", "LDR", "STR", |
|
| 35 | 35 |
"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---", |
| 36 | 36 |
"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL", |
| 37 | 37 |
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" |
| ... | ... |
@@ -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/draw.usm bin/boot.rom |
|
| 27 |
+./bin/assembler examples/test.usm bin/boot.rom |
|
| 28 | 28 |
./bin/emulator bin/boot.rom |
| 29 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,44 @@ |
| 1 |
+( draw routines ) |
|
| 2 |
+ |
|
| 3 |
+:dev/r fff8 ( std read port ) |
|
| 4 |
+:dev/w fff9 ( std write port ) |
|
| 5 |
+ |
|
| 6 |
+;x_ 2 ;y_ 2 ;x0 2 ;y0 2 ;x1 2 ;y1 2 ;color 1 |
|
| 7 |
+ |
|
| 8 |
+|0100 @RESET |
|
| 9 |
+ |
|
| 10 |
+ ( set dev/write to screen ) |
|
| 11 |
+ ,01 ,dev/w STR |
|
| 12 |
+ ,01 ,color STR |
|
| 13 |
+ |
|
| 14 |
+ ( init positions ) |
|
| 15 |
+ ,0020 ,x0 STR^ ,0018 ,y0 STR^ |
|
| 16 |
+ ,0030 ,x1 STR^ ,0048 ,y1 STR^ |
|
| 17 |
+ ,x0 LDR^ ,x_ STR^ ,y0 LDR^ ,y_ STR^ |
|
| 18 |
+ |
|
| 19 |
+ ( draw control points ) |
|
| 20 |
+ ,02 ,color STR |
|
| 21 |
+ ,x0 LDR^ ,y0 LDR^ ,putpixel JSR |
|
| 22 |
+ ,x1 LDR^ ,y1 LDR^ ,putpixel JSR |
|
| 23 |
+ |
|
| 24 |
+ ,redraw JSR |
|
| 25 |
+ |
|
| 26 |
+BRK |
|
| 27 |
+ |
|
| 28 |
+@redraw |
|
| 29 |
+ ,0000 IOW^ |
|
| 30 |
+ ,0000 IOW^ |
|
| 31 |
+ ,00 IOW |
|
| 32 |
+ ,01 IOW |
|
| 33 |
+ RTS |
|
| 34 |
+ |
|
| 35 |
+@putpixel |
|
| 36 |
+ IOW^ ( y short ) |
|
| 37 |
+ IOW^ ( x short ) |
|
| 38 |
+ ,color LDR IOW ( color byte ) |
|
| 39 |
+ ,00 IOW ( redraw byte ) |
|
| 40 |
+ RTS |
|
| 41 |
+ |
|
| 42 |
+|c000 @FRAME BRK |
|
| 43 |
+|d000 @ERROR BRK |
|
| 44 |
+|FFFA .RESET .FRAME .ERROR |
| ... | ... |
@@ -25,15 +25,15 @@ void mempoke16(Memory *m, Uint16 a, Uint16 b) { mempoke8(m, a, b >> 8); mempok
|
| 25 | 25 |
Uint16 mempeek16(Memory *m, Uint16 a) { return (mempeek8(m, a) << 8) + mempeek8(m, a + 1); }
|
| 26 | 26 |
void push8(St8 *s, Uint8 a) { s->dat[s->ptr++] = a; }
|
| 27 | 27 |
Uint8 pop8(St8 *s) { return s->dat[--s->ptr]; }
|
| 28 |
-Uint8 peek8(St8 *s, Uint8 a) { return s->dat[s->ptr - a]; }
|
|
| 28 |
+Uint8 peek8(St8 *s, Uint8 a) { return s->dat[s->ptr - a - 1]; }
|
|
| 29 | 29 |
void push16(St8 *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
|
| 30 | 30 |
Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
|
| 31 |
-Uint16 peek16(St8 *s, Uint8 a) { return (peek8(s, a) << 8) + peek8(s, a + 1); }
|
|
| 31 |
+Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
|
|
| 32 | 32 |
/* I/O */ |
| 33 | 33 |
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
| 34 | 34 |
void op_li1(Uxn *u) { u->literal += 1; }
|
| 35 | 35 |
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
| 36 |
-void op_nop(Uxn *u) { printf("NOP"); (void)u; }
|
|
| 36 |
+void op_nop(Uxn *u) { printf("%02x\n", pop8(&u->wst)); }
|
|
| 37 | 37 |
void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, pop8(&u->wst))); }
|
| 38 | 38 |
void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, a); }
|
| 39 | 39 |
void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }
|
| ... | ... |
@@ -44,9 +44,9 @@ void op_jsr(Uxn *u) { push16(&u->rst, u->ram.ptr); u->ram.ptr = pop16(&u->wst);
|
| 44 | 44 |
void op_rts(Uxn *u) { u->ram.ptr = pop16(&u->rst); }
|
| 45 | 45 |
/* Stack */ |
| 46 | 46 |
void op_pop(Uxn *u) { pop8(&u->wst); }
|
| 47 |
-void op_dup(Uxn *u) { push8(&u->wst, peek8(&u->wst, 1)); }
|
|
| 47 |
+void op_dup(Uxn *u) { push8(&u->wst, peek8(&u->wst, 0)); }
|
|
| 48 | 48 |
void op_swp(Uxn *u) { Uint8 b = pop8(&u->wst), a = pop8(&u->wst); push8(&u->wst, b); push8(&u->wst, a); }
|
| 49 |
-void op_ovr(Uxn *u) { Uint8 a = peek8(&u->wst,2); push8(&u->wst, a); }
|
|
| 49 |
+void op_ovr(Uxn *u) { push8(&u->wst, peek8(&u->wst, 1)); }
|
|
| 50 | 50 |
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); }
|
| 51 | 51 |
void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b & a); }
|
| 52 | 52 |
void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
|
| ... | ... |
@@ -61,15 +61,16 @@ void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
|
| 61 | 61 |
void op_gth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b > a); }
|
| 62 | 62 |
void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b < a); }
|
| 63 | 63 |
/* --- */ |
| 64 |
+void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
|
|
| 64 | 65 |
void op_ior16(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push16(&u->wst, (dev->read(dev, a) << 8) + dev->read(dev, a + 1)); }
|
| 65 | 66 |
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, b); dev->write(dev, a); } }
|
| 66 | 67 |
void op_ldr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->wst, mempeek16(&u->ram, a)); }
|
| 67 | 68 |
void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); }
|
| 68 | 69 |
/* Stack(16-bits) */ |
| 69 | 70 |
void op_pop16(Uxn *u) { pop16(&u->wst); }
|
| 70 |
-void op_dup16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 2)); }
|
|
| 71 |
+void op_dup16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 0)); }
|
|
| 71 | 72 |
void op_swp16(Uxn *u) { Uint16 b = pop16(&u->wst), a = pop16(&u->wst); push16(&u->wst, b); push16(&u->wst, a); }
|
| 72 |
-void op_ovr16(Uxn *u) { Uint16 a = peek16(&u->wst, 4); push16(&u->wst, a); }
|
|
| 73 |
+void op_ovr16(Uxn *u) { push16(&u->wst, peek16(&u->wst, 1)); }
|
|
| 73 | 74 |
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); }
|
| 74 | 75 |
void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b & a); }
|
| 75 | 76 |
void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); }
|
| ... | ... |
@@ -90,7 +91,7 @@ void (*ops[])(Uxn *u) = {
|
| 90 | 91 |
op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, |
| 91 | 92 |
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, |
| 92 | 93 |
/* 16-bit */ |
| 93 |
- op_brk, op_nop, op_li1, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, |
|
| 94 |
+ op_brk, op_nop16, op_li1, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, |
|
| 94 | 95 |
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, |
| 95 | 96 |
op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16, |
| 96 | 97 |
op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16 |
| ... | ... |
@@ -99,7 +100,7 @@ void (*ops[])(Uxn *u) = {
|
| 99 | 100 |
Uint8 opr[][2] = {
|
| 100 | 101 |
{0,0}, {0,0}, {0,0}, {0,0}, {1,1}, {1,0}, {2,1}, {3,0},
|
| 101 | 102 |
{2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
|
| 102 |
- {1,0}, {1,2}, {2,2}, {3,3}, {3,3}, {2,1}, {2,1}, {2,1},
|
|
| 103 |
+ {1,0}, {1,2}, {2,2}, {2,3}, {3,3}, {2,1}, {2,1}, {2,1},
|
|
| 103 | 104 |
{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
|
| 104 | 105 |
/* 16-bit */ |
| 105 | 106 |
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
|