diff --git a/README.md b/README.md index 0cd373c..a2f7a36 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,8 @@ RTS |FF00 ;dev/console Console -|FFF0 [ f3f0 f30b f30a ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ f3f0 f30b f30a ] ( palette ) ``` ## Emulator diff --git a/assembler.c b/assembler.c index de7f2bf..4947932 100644 --- a/assembler.c +++ b/assembler.c @@ -295,11 +295,15 @@ pass1(FILE *f) addr += 1; else { switch(w[0]) { - case '|': addr = shex(w + 1); break; + case '|': + if(shex(w + 1) < addr) + return error("Memory Overlap", w); + addr = shex(w + 1); + break; case '<': addr -= shex(w + 1); break; case '>': addr += shex(w + 1); break; - case '=': addr += 4; break; /* STR helper */ - case '~': addr += 4; break; /* LDR helper */ + case '=': addr += 4; break; /* STR helper (lit addr-hb addr-lb str) */ + case '~': addr += 4; break; /* LDR helper (lit addr-hb addr-lb ldr) */ case ',': addr += 3; break; case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break; case '+': /* signed positive */ @@ -345,12 +349,12 @@ pass2(FILE *f) else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1); else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1); else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1); - else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w+1), 1); pushbyte(findopcode(findlabellen(w+1) == 2? "STR2" : "STR"), 0); } + else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w+1), 1); pushbyte(findopcode(findlabellen(w+1) == 2 ? "STR2" : "STR"), 0); } else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w+1), 1); pushbyte(findopcode(findlabellen(w+1) == 2 ? "LDR2" : "LDR"), 0); } + else if(w[0] == '=' && sihx(w + 1)) { pushshort(shex(w + 1), 1); pushbyte(findopcode("STR2"), 0); } + else if(w[0] == '~' && sihx(w + 1)) { pushshort(shex(w + 1), 1); pushbyte(findopcode("LDR2"), 0); } else if((l = findlabel(w + 1))) pushshort(findlabeladdr(w+1), w[0] == ','); - else { - return error("Unknown label in second pass", w); - } + else return error("Unknown label in second pass", w); /* clang-format on */ } return 1; diff --git a/build.sh b/build.sh index 6f35a7f..a7b2e56 100755 --- a/build.sh +++ b/build.sh @@ -20,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr # cc uxn.c emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/emulator # run -./bin/assembler examples/dev.ctrl.usm bin/boot.rom +./bin/assembler examples/dev.mouse.usm bin/boot.rom ./bin/emulator bin/boot.rom diff --git a/emulator.c b/emulator.c index e50ca38..749a9eb 100644 --- a/emulator.c +++ b/emulator.c @@ -65,7 +65,7 @@ SDL_Texture *gTexture; Uint32 *pixels; Screen screen; -Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devctrl; +Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devctrl, *devsystem; #pragma mark - Helpers @@ -368,6 +368,13 @@ sprite_poke(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1) return b1; } +Uint8 +system_poke(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1) +{ + printf("system_poke\n"); + return b1; +} + Uint8 ppnil(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1) { @@ -384,7 +391,7 @@ start(Uxn *u) { int ticknext = 0; evaluxn(u, u->vreset); - loadtheme(u->ram.dat + 0xfff0); + loadtheme(u->ram.dat + 0xfff8); if(screen.reqdraw) redraw(pixels, u); while(1) { @@ -435,10 +442,14 @@ main(int argc, char **argv) devkey = portuxn(&u, "key", ppnil, ppnil); devmouse = portuxn(&u, "mouse", ppnil, ppnil); - u.ram.dat[0xff10] = (HOR * 8 >> 8) & 0xff; - u.ram.dat[0xff11] = HOR * 8 & 0xff; - u.ram.dat[0xff12] = (VER * 8 >> 8) & 0xff; - u.ram.dat[0xff13] = VER * 8 & 0xff; + u.devices = 7; + devsystem = portuxn(&u, "system", ppnil, system_poke); + + /* Write screen size to dev/screen */ + u.ram.dat[devscreen->addr + 0] = (HOR * 8 >> 8) & 0xff; + u.ram.dat[devscreen->addr + 1] = HOR * 8 & 0xff; + u.ram.dat[devscreen->addr + 2] = (VER * 8 >> 8) & 0xff; + u.ram.dat[devscreen->addr + 3] = VER * 8 & 0xff; start(&u); quit(); diff --git a/examples/dev.console.usm b/examples/dev.console.usm index cc057b7..819b62d 100644 --- a/examples/dev.console.usm +++ b/examples/dev.console.usm @@ -25,5 +25,5 @@ RTS |FF00 ;dev/console Console -|FFF0 [ f3f0 f30b f30a ] ( palette ) -|FFFA .RESET .FRAME .ERROR \ No newline at end of file +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ f3f0 f30b f30a ] ( palette ) \ No newline at end of file diff --git a/examples/dev.ctrl.usm b/examples/dev.ctrl.usm index eca15fe..4fb86f0 100644 --- a/examples/dev.ctrl.usm +++ b/examples/dev.ctrl.usm @@ -75,5 +75,5 @@ RTS |FF20 ;dev/sprite Sprite |FF30 ;dev/ctrl Controller -|FFF0 [ 0daf 02ff 035f ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ 0daf 02ff 035f ] ( palette ) diff --git a/examples/dev.key.usm b/examples/dev.key.usm index 67d540c..d055f1c 100644 --- a/examples/dev.key.usm +++ b/examples/dev.key.usm @@ -130,5 +130,5 @@ RTS |FF20 ;dev/sprite Sprite |FF40 ;dev/key Keyboard -|FFF0 [ f0ff f00f f00f ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ f0ff f00f f00f ] ( palette ) diff --git a/examples/dev.mouse.usm b/examples/dev.mouse.usm index 878f5a3..4b3e181 100644 --- a/examples/dev.mouse.usm +++ b/examples/dev.mouse.usm @@ -4,8 +4,10 @@ &Sprite { pad 8 x 2 y 2 addr 2 color 1 } &Mouse { x 2 y 2 state 1 chord 1 } +&Label2d { x 2 y 2 color 1 addr 2 } &Point2d { x 2 y 2 } +;label Label2d ;cat Point2d ;mouse Point2d ;pos Point2d @@ -23,42 +25,37 @@ BRK -|c000 @FRAME +|0200 @FRAME - ( clear last cursor ) - #10 ,clear_icn ~mouse.x ~mouse.y ,draw-sprite JSR - ( record mouse positions ) - ~dev/mouse.x =mouse.x ~dev/mouse.y =mouse.y + ,draw-cursor JSR + ( reset timer -> move cat tail ) - ~dev/mouse.state #01 NEQ ,no-click ROT JMP? POP2 + ,no-click ~dev/mouse.state #00 EQU JMP? POP2 #50 =timer @no-click - ( detect click ) - ~dev/mouse.state #11 NEQ ,no-click12 ROT JMP? POP2 - ,mouse12_text #0058 #0040 ,draw-label JSR + ,no-click12 ~dev/mouse.state #11 NEQ JMP? POP2 + #0058 #0040 #01 ,mouse12_text ,draw-label JSR #10 ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR ~color ,mouse12_icn #0048 #0040 ,draw-sprite JSR ,end-click JMP @no-click12 - ~dev/mouse.state #01 NEQ ,no-click1 ROT JMP? POP2 - ,mouse1_text #0058 #0040 ,draw-label JSR + ,no-click1 ~dev/mouse.state #01 NEQ JMP? POP2 + #0058 #0040 #01 ,mouse1_text ,draw-label JSR #12 ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR ~color ,mouse1_icn #0048 #0040 ,draw-sprite JSR ,end-click JMP @no-click1 - ~dev/mouse.state #10 NEQ ,no-click2 ROT JMP? POP2 - ,mouse2_text #0058 #0040 ,draw-label JSR + ,no-click2 ~dev/mouse.state #10 NEQ JMP? POP2 + #0058 #0040 #01 ,mouse2_text ,draw-label JSR #13 ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR ~color ,mouse2_icn #0048 #0040 ,draw-sprite JSR ,end-click JMP @no-click2 ( default ) - ,mouse0_text #0058 #0040 ,draw-label JSR + #0058 #0040 #01 ,mouse0_text ,draw-label JSR ~color ,mouse0_icn #0048 #0040 ,draw-sprite JSR - #11 ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR @end-click - ( animate ) ,animate-polycat JSR ( update last pos ) @@ -66,6 +63,21 @@ BRK BRK +@draw-cursor + + ~mouse.x ~dev/mouse.x NEQU2 + ~mouse.y ~dev/mouse.y NEQU2 + + #0000 EQU2 RTS? ( Return if unchanged ) + + ( clear last cursor ) + #10 ,clear_icn ~mouse.x ~mouse.y ,draw-sprite JSR + ( record mouse positions ) + ~dev/mouse.x =mouse.x ~dev/mouse.y =mouse.y + #11 ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR + +RTS + @draw-polycat ( ears ) @@ -117,14 +129,16 @@ RTS RTS -@draw-label ( text x1 y1 ) - =pos.y =pos.x +@draw-label ( x y color addr ) + + ( load ) =label.addr =label.color =dev/sprite.y =dev/sprite.x ~label.addr @draw-label-loop - ( draw ) ~pos.x ~pos.y =dev/sprite.y =dev/sprite.x DUP2 LDR #00 SWP #0008 MUL2 ,font ADD2 =dev/sprite.addr ~color =dev/sprite.color + ( draw ) DUP2 LDR #00 SWP #0008 MUL2 ,font ADD2 =dev/sprite.addr ~label.color =dev/sprite.color ( incr ) #0001 ADD2 - ( incr ) ~pos.x #0008 ADD2 =pos.x + ( incr ) ~dev/sprite.x #0008 ADD2 =dev/sprite.x DUP2 LDR #00 NEQ ,draw-label-loop ROT JMP? POP2 POP2 + RTS @draw-sprite @@ -211,10 +225,11 @@ RTS @mouse2_text [ mouse _2 ] <1 .00 @mouse12_text [ mouse 12 ] <1 .00 +|d000 @ERROR BRK + |FF10 ;dev/screen Screen |FF20 ;dev/sprite Sprite |FF50 ;dev/mouse Mouse -|d000 @ERROR BRK -|FFF0 [ 0f85 0fd5 0fb5 ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ 0f85 0fd5 0fb5 ] ( palette ) diff --git a/examples/dev.screen.usm b/examples/dev.screen.usm index e4c0d11..97579ff 100644 --- a/examples/dev.screen.usm +++ b/examples/dev.screen.usm @@ -53,5 +53,5 @@ BRK |FF10 ;dev/screen Screen |FF20 ;dev/sprite Sprite -|FFF0 [ f0ac f0bb f053 ] ( palette ) -|FFFA .RESET .FRAME .ERROR ( vectors ) +|FFF0 .RESET .FRAME .ERROR ( vectors ) +|FFF8 [ f0ac f0bb f053 ] ( palette ) diff --git a/examples/gui.picture.usm b/examples/gui.picture.usm index a3dc159..f98600f 100644 --- a/examples/gui.picture.usm +++ b/examples/gui.picture.usm @@ -312,5 +312,5 @@ RTS |FF10 ;dev/screen Screen |FF20 ;dev/sprite Sprite -|FFF0 [ 0ffc 0f0b 0f03 ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ 0ffc 0f0b 0f03 ] ( palette ) diff --git a/examples/gui.shapes.usm b/examples/gui.shapes.usm index a7c94ae..9bb0cf3 100644 --- a/examples/gui.shapes.usm +++ b/examples/gui.shapes.usm @@ -149,5 +149,5 @@ RTS |FF10 ;dev/screen Screen |FF20 ;dev/sprite Sprite -|FFF0 [ 0f0f 0fff 0ff0 ] ( palette ) -|FFFA .RESET .FRAME .ERROR ( vectors ) \ No newline at end of file +|FFF0 .RESET .FRAME .ERROR ( vectors ) +|FFF8 [ 0f0f 0fff 0ff0 ] ( palette ) \ No newline at end of file diff --git a/examples/old.hover.usm b/examples/old.hover.usm index 2c741bb..ed2ff20 100644 --- a/examples/old.hover.usm +++ b/examples/old.hover.usm @@ -180,5 +180,5 @@ RTS |d000 @ERROR BRK -|FFF0 [ e2af eab2 e652 ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ e2af eab2 e652 ] ( palette ) diff --git a/examples/old.paint.usm b/examples/old.paint.usm index 66eeb64..e531edb 100644 --- a/examples/old.paint.usm +++ b/examples/old.paint.usm @@ -91,5 +91,5 @@ BRK |d000 @ERROR BRK -|FFF0 [ f1c3 f12e f12a ] ( palette ) -|FFFA .RESET .FRAME .ERROR +|FFF0 .RESET .FRAME .ERROR +|FFF8 [ f1c3 f12e f12a ] ( palette ) diff --git a/uxn.c b/uxn.c index 6c77ba0..99cd20c 100644 --- a/uxn.c +++ b/uxn.c @@ -193,9 +193,9 @@ loaduxn(Uxn *u, char *filepath) if(!(f = fopen(filepath, "rb"))) return haltuxn(u, "Missing input rom.", 0); fread(u->ram.dat, sizeof(u->ram.dat), 1, f); - u->vreset = mempeek16(u, 0xfffa); - u->vframe = mempeek16(u, 0xfffc); - u->verror = mempeek16(u, 0xfffe); + u->vreset = mempeek16(u, 0xfff0); + u->vframe = mempeek16(u, 0xfff2); + u->verror = mempeek16(u, 0xfff4); printf("Uxn loaded[%s] vrst:%04x vfrm:%04x verr:%04x.\n", filepath, u->vreset,