commit 1cc7abea54148a693120e1755866b1828f7292b6
parent b3ff7af8a382c216502c140c1a77e15734773b83
Author: neauoire <aliceffekt@gmail.com>
Date:   Sun, 14 Feb 2021 11:51:36 -0800
Added controller example
Diffstat:
7 files changed, 190 insertions(+), 35 deletions(-)
diff --git a/README.md b/README.md
@@ -44,6 +44,8 @@ evaluxn(u, u->vframe); /* Each frame
 - `+12ef`, a literal signed short.
 - `-1a`, a literal signed byte(negative).
 - `-12ef`, a literal signed short(negative).
+- `.ab`, a raw byte in memory.
+- `.abcd`, a raw short in memory.
 
 ### Special
 
@@ -81,6 +83,21 @@ BRK
 |FFFA .RESET .FRAME .ERROR
 ```
 
+## Emulator
+
+### Controller(dev/ctrl)
+
+A device that works like a NES controller, each button is a bit from a single byte.
+
+- Ctrl
+- Alt
+- Escape
+- Return
+- Up
+- Down
+- Left
+- Right
+
 ## TODOs
 
 - Defines?
diff --git 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/test.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
@@ -37,7 +37,7 @@ SDL_Renderer *gRenderer;
 SDL_Texture *gTexture;
 Uint32 *pixels;
 
-Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devctrl;
 
 #pragma mark - Helpers
 
@@ -65,9 +65,7 @@ drawchr(Uint32 *dst, int x, int y, Uint8 *sprite)
 		for(h = 0; h < 8; h++) {
 			int ch1 = ((sprite[v] >> h) & 0x1);
 			int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
-			int clr = ch1 + ch2;
-			int guides = GUIDES && !clr && ((x + y) / 8) % 2;
-			putpixel(dst, x + 7 - h, y + v, guides ? 4 : clr);
+			putpixel(dst, x + 7 - h, y + v, ch1 + ch2);
 		}
 }
 
@@ -192,8 +190,25 @@ domouse(SDL_Event *event)
 void
 dokey(SDL_Event *event)
 {
-	(void)event;
-	/* printf("key\n"); */
+}
+
+void
+doctrl(SDL_Event *event, int z)
+{
+	Uint8 flag = 0x00;
+	if(SDL_GetModState() & KMOD_LCTRL || SDL_GetModState() & KMOD_RCTRL)
+		flag = 0x01;
+	if(SDL_GetModState() & KMOD_LALT || SDL_GetModState() & KMOD_RALT)
+		flag = 0x02;
+	switch(event->key.keysym.sym) {
+	case SDLK_ESCAPE: flag = 0x04; break;
+	case SDLK_RETURN: flag = 0x08; break;
+	case SDLK_UP: flag = 0x10; break;
+	case SDLK_DOWN: flag = 0x20; break;
+	case SDLK_LEFT: flag = 0x40; break;
+	case SDLK_RIGHT: flag = 0x80; break;
+	}
+	setflag(&devctrl->mem[0], flag, z);
 }
 
 #pragma mark - Devices
@@ -296,6 +311,20 @@ keyw(Device *d, Memory *m, Uint8 b)
 	return 0;
 }
 
+Uint8
+ctrlr(Device *d, Memory *m, Uint8 b)
+{
+	return d->mem[b];
+}
+
+Uint8
+ctrlw(Device *d, Memory *m, Uint8 b)
+{
+	(void)d;
+	(void)b;
+	return 0;
+}
+
 #pragma mark - Generics
 
 int
@@ -314,20 +343,21 @@ start(Uxn *u)
 		if(tick < ticknext)
 			SDL_Delay(ticknext - tick);
 		ticknext = tick + (1000 / FPS);
-		evaluxn(u, u->vframe);
 		while(SDL_PollEvent(&event) != 0) {
 			switch(event.type) {
 			case SDL_QUIT: quit(); break;
 			case SDL_MOUSEBUTTONUP:
 			case SDL_MOUSEBUTTONDOWN:
 			case SDL_MOUSEMOTION: domouse(&event); break;
-			case SDL_KEYDOWN: dokey(&event); break;
+			case SDL_KEYDOWN: doctrl(&event, 1); break;
+			case SDL_KEYUP: doctrl(&event, 0); break;
 			case SDL_WINDOWEVENT:
 				if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
 					redraw(pixels);
 				break;
 			}
 		}
+		evaluxn(u, u->vframe);
 	}
 }
 
@@ -350,6 +380,7 @@ main(int argc, char **argv)
 	devmouse = portuxn(&u, "mouse", mouser, mousew);
 	devkey = portuxn(&u, "key", keyr, keyw);
 	devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
+	devctrl = portuxn(&u, "ctrl", ctrlr, ctrlw);
 
 	start(&u);
 
diff --git a/examples/controller.usm b/examples/controller.usm
@@ -0,0 +1,54 @@
+( comment )
+
+:dev/r fff8 ( const read port )
+:dev/w fff9 ( const write port )
+
+;x 2 ;y 2
+
+|0100 @RESET 
+
+	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
+	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
+
+	#0080 ,x STR2
+	#0040 ,y STR2
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
+
+BRK
+
+|0200 @SPRITESHEET
+
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
+
+BRK
+
+|c000 @FRAME 
+
+	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
+	,y LDR2 #0001 SUB2 ,y STR2
+	@next0
+	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
+	,y LDR2 #0001 ADD2 ,y STR2
+	@next1
+	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
+	,x LDR2 #0001 SUB2 ,x STR2
+	@next2
+	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
+	,x LDR2 #0001 ADD2 ,x STR2
+	@next3
+	( redraw )
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
+
+BRK
+
+@putsprite
+	IOW2 ( y short )
+	IOW2 ( x short )
+	IOW2 ( sprite address )
+	IOW  ( redraw byte )
+	RTS
+
+|d000 @ERROR BRK 
+
+|FFFA .RESET .FRAME .ERROR
diff --git a/examples/sprite.usm b/examples/sprite.usm
@@ -0,0 +1,46 @@
+( comment )
+
+:dev/w fff9 ( const write port )
+
+|0100 @RESET 
+
+	#01 ,dev/w STR                           ( set dev/write to screen ) 
+
+	( draw 1 pixel )
+	#00 #01 #0021 #0021 ,putpixel JSR
+
+	#04 ,dev/w STR                           ( set dev/write to screen ) 
+
+	#00 ,star_icn #0001 #0001 ,putsprite JSR
+	#00 ,star_icn #0031 #0021 ,putsprite JSR
+	#00 ,cursor_icn #0021 #0016 ,putsprite JSR
+	#00 ,star_icn #0055 #0042 ,putsprite JSR
+	#01 ,cursor_icn #0067 #0031 ,putsprite JSR
+
+BRK
+
+@putsprite
+	IOW2 ( y short )
+	IOW2 ( x short )
+	IOW2 ( sprite address )
+	IOW  ( redraw byte )
+	RTS
+
+@putpixel 
+	IOW2 ( y short )
+	IOW2 ( x short )
+	IOW  ( color byte )
+	IOW  ( redraw byte )
+	RTS
+
+|0200 @SPRITESHEET
+
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
+
+BRK
+
+|c000 @FRAME BRK
+|d000 @ERROR BRK 
+
+|FFFA .RESET .FRAME .ERROR
diff --git a/examples/test.usm b/examples/test.usm
@@ -1,22 +1,44 @@
 ( comment )
 
+:dev/r fff8 ( const read port )
 :dev/w fff9 ( const write port )
 
+;x 2 ;y 2
+
 |0100 @RESET 
 
-	#01 ,dev/w STR                           ( set dev/write to screen ) 
+	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
+	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
+
+	#0080 ,x STR2
+	#0040 ,y STR2
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
 
-	( draw 1 pixel )
-	#00 #01 #0021 #0021 ,putpixel JSR
+BRK
+
+|0200 @SPRITESHEET
 
-	#04 ,dev/w STR                           ( set dev/write to screen ) 
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
 
-	#00 ,star_icn #0001 #0001 ,putsprite JSR
+BRK
 
-	#00 ,star_icn #0031 #0021 ,putsprite JSR
-	#00 ,cursor_icn #0021 #0016 ,putsprite JSR
-	#00 ,star_icn #0055 #0042 ,putsprite JSR
-	#01 ,cursor_icn #0067 #0031 ,putsprite JSR
+|c000 @FRAME 
+
+	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
+	,y LDR2 #0001 SUB2 ,y STR2
+	@next0
+	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
+	,y LDR2 #0001 ADD2 ,y STR2
+	@next1
+	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
+	,x LDR2 #0001 SUB2 ,x STR2
+	@next2
+	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
+	,x LDR2 #0001 ADD2 ,x STR2
+	@next3
+	( redraw )
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
 
 BRK
 
@@ -27,21 +49,6 @@ BRK
 	IOW  ( redraw byte )
 	RTS
 
-@putpixel 
-	IOW2 ( y short )
-	IOW2 ( x short )
-	IOW  ( color byte )
-	IOW  ( redraw byte )
-	RTS
-
-|0200 @SPRITESHEET
-
-@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
-@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
-
-BRK
-
-|c000 @FRAME BRK
 |d000 @ERROR BRK 
 
 |FFFA .RESET .FRAME .ERROR
diff --git a/uxn.c b/uxn.c
@@ -30,10 +30,10 @@ void   push16(St8 *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
 Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
 Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
 /* I/O */
-void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
+void op_brk(Uxn *u) { setflag(&u->status, FLAG_HALT, 1); }
 void op_lit(Uxn *u) { u->literal += 1; }
 void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
-void op_nop(Uxn *u) { printf("0x%02x ", pop8(&u->wst)); }
+void op_nop(Uxn *u) { printf("0x%02x \n", pop8(&u->wst)); fflush(stdout); }
 void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, &u->ram, pop8(&u->wst))); }
 void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, &u->ram, a); }
 void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }