Browse code

Added controller example

neauoire authored on 14/02/2021 19:51:36
Showing 7 changed files
... ...
@@ -44,6 +44,8 @@ evaluxn(u, u->vframe); /* Each frame
44 44
 - `+12ef`, a literal signed short.
45 45
 - `-1a`, a literal signed byte(negative).
46 46
 - `-12ef`, a literal signed short(negative).
47
+- `.ab`, a raw byte in memory.
48
+- `.abcd`, a raw short in memory.
47 49
 
48 50
 ### Special
49 51
 
... ...
@@ -81,6 +83,21 @@ BRK
81 83
 |FFFA .RESET .FRAME .ERROR
82 84
 ```
83 85
 
86
+## Emulator
87
+
88
+### Controller(dev/ctrl)
89
+
90
+A device that works like a NES controller, each button is a bit from a single byte.
91
+
92
+- Ctrl
93
+- Alt
94
+- Escape
95
+- Return
96
+- Up
97
+- Down
98
+- Left
99
+- Right
100
+
84 101
 ## TODOs
85 102
 
86 103
 - Defines?
... ...
@@ -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/test.usm bin/boot.rom
27
+./bin/assembler examples/controller.usm bin/boot.rom
28 28
 ./bin/emulator bin/boot.rom
... ...
@@ -37,7 +37,7 @@ SDL_Renderer *gRenderer;
37 37
 SDL_Texture *gTexture;
38 38
 Uint32 *pixels;
39 39
 
40
-Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
40
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devctrl;
41 41
 
42 42
 #pragma mark - Helpers
43 43
 
... ...
@@ -65,9 +65,7 @@ drawchr(Uint32 *dst, int x, int y, Uint8 *sprite)
65 65
 		for(h = 0; h < 8; h++) {
66 66
 			int ch1 = ((sprite[v] >> h) & 0x1);
67 67
 			int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
68
-			int clr = ch1 + ch2;
69
-			int guides = GUIDES && !clr && ((x + y) / 8) % 2;
70
-			putpixel(dst, x + 7 - h, y + v, guides ? 4 : clr);
68
+			putpixel(dst, x + 7 - h, y + v, ch1 + ch2);
71 69
 		}
72 70
 }
73 71
 
... ...
@@ -192,8 +190,25 @@ domouse(SDL_Event *event)
192 190
 void
193 191
 dokey(SDL_Event *event)
194 192
 {
195
-	(void)event;
196
-	/* printf("key\n"); */
193
+}
194
+
195
+void
196
+doctrl(SDL_Event *event, int z)
197
+{
198
+	Uint8 flag = 0x00;
199
+	if(SDL_GetModState() & KMOD_LCTRL || SDL_GetModState() & KMOD_RCTRL)
200
+		flag = 0x01;
201
+	if(SDL_GetModState() & KMOD_LALT || SDL_GetModState() & KMOD_RALT)
202
+		flag = 0x02;
203
+	switch(event->key.keysym.sym) {
204
+	case SDLK_ESCAPE: flag = 0x04; break;
205
+	case SDLK_RETURN: flag = 0x08; break;
206
+	case SDLK_UP: flag = 0x10; break;
207
+	case SDLK_DOWN: flag = 0x20; break;
208
+	case SDLK_LEFT: flag = 0x40; break;
209
+	case SDLK_RIGHT: flag = 0x80; break;
210
+	}
211
+	setflag(&devctrl->mem[0], flag, z);
197 212
 }
198 213
 
199 214
 #pragma mark - Devices
... ...
@@ -296,6 +311,20 @@ keyw(Device *d, Memory *m, Uint8 b)
296 311
 	return 0;
297 312
 }
298 313
 
314
+Uint8
315
+ctrlr(Device *d, Memory *m, Uint8 b)
316
+{
317
+	return d->mem[b];
318
+}
319
+
320
+Uint8
321
+ctrlw(Device *d, Memory *m, Uint8 b)
322
+{
323
+	(void)d;
324
+	(void)b;
325
+	return 0;
326
+}
327
+
299 328
 #pragma mark - Generics
300 329
 
301 330
 int
... ...
@@ -314,20 +343,21 @@ start(Uxn *u)
314 343
 		if(tick < ticknext)
315 344
 			SDL_Delay(ticknext - tick);
316 345
 		ticknext = tick + (1000 / FPS);
317
-		evaluxn(u, u->vframe);
318 346
 		while(SDL_PollEvent(&event) != 0) {
319 347
 			switch(event.type) {
320 348
 			case SDL_QUIT: quit(); break;
321 349
 			case SDL_MOUSEBUTTONUP:
322 350
 			case SDL_MOUSEBUTTONDOWN:
323 351
 			case SDL_MOUSEMOTION: domouse(&event); break;
324
-			case SDL_KEYDOWN: dokey(&event); break;
352
+			case SDL_KEYDOWN: doctrl(&event, 1); break;
353
+			case SDL_KEYUP: doctrl(&event, 0); break;
325 354
 			case SDL_WINDOWEVENT:
326 355
 				if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
327 356
 					redraw(pixels);
328 357
 				break;
329 358
 			}
330 359
 		}
360
+		evaluxn(u, u->vframe);
331 361
 	}
332 362
 }
333 363
 
... ...
@@ -350,6 +380,7 @@ main(int argc, char **argv)
350 380
 	devmouse = portuxn(&u, "mouse", mouser, mousew);
351 381
 	devkey = portuxn(&u, "key", keyr, keyw);
352 382
 	devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
383
+	devctrl = portuxn(&u, "ctrl", ctrlr, ctrlw);
353 384
 
354 385
 	start(&u);
355 386
 
356 387
new file mode 100644
... ...
@@ -0,0 +1,54 @@
1
+( comment )
2
+
3
+:dev/r fff8 ( const read port )
4
+:dev/w fff9 ( const write port )
5
+
6
+;x 2 ;y 2
7
+
8
+|0100 @RESET 
9
+
10
+	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
11
+	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
12
+
13
+	#0080 ,x STR2
14
+	#0040 ,y STR2
15
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
16
+
17
+BRK
18
+
19
+|0200 @SPRITESHEET
20
+
21
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
22
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
23
+
24
+BRK
25
+
26
+|c000 @FRAME 
27
+
28
+	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
29
+	,y LDR2 #0001 SUB2 ,y STR2
30
+	@next0
31
+	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
32
+	,y LDR2 #0001 ADD2 ,y STR2
33
+	@next1
34
+	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
35
+	,x LDR2 #0001 SUB2 ,x STR2
36
+	@next2
37
+	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
38
+	,x LDR2 #0001 ADD2 ,x STR2
39
+	@next3
40
+	( redraw )
41
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
42
+
43
+BRK
44
+
45
+@putsprite
46
+	IOW2 ( y short )
47
+	IOW2 ( x short )
48
+	IOW2 ( sprite address )
49
+	IOW  ( redraw byte )
50
+	RTS
51
+
52
+|d000 @ERROR BRK 
53
+
54
+|FFFA .RESET .FRAME .ERROR
0 55
new file mode 100644
... ...
@@ -0,0 +1,46 @@
1
+( comment )
2
+
3
+:dev/w fff9 ( const write port )
4
+
5
+|0100 @RESET 
6
+
7
+	#01 ,dev/w STR                           ( set dev/write to screen ) 
8
+
9
+	( draw 1 pixel )
10
+	#00 #01 #0021 #0021 ,putpixel JSR
11
+
12
+	#04 ,dev/w STR                           ( set dev/write to screen ) 
13
+
14
+	#00 ,star_icn #0001 #0001 ,putsprite JSR
15
+	#00 ,star_icn #0031 #0021 ,putsprite JSR
16
+	#00 ,cursor_icn #0021 #0016 ,putsprite JSR
17
+	#00 ,star_icn #0055 #0042 ,putsprite JSR
18
+	#01 ,cursor_icn #0067 #0031 ,putsprite JSR
19
+
20
+BRK
21
+
22
+@putsprite
23
+	IOW2 ( y short )
24
+	IOW2 ( x short )
25
+	IOW2 ( sprite address )
26
+	IOW  ( redraw byte )
27
+	RTS
28
+
29
+@putpixel 
30
+	IOW2 ( y short )
31
+	IOW2 ( x short )
32
+	IOW  ( color byte )
33
+	IOW  ( redraw byte )
34
+	RTS
35
+
36
+|0200 @SPRITESHEET
37
+
38
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
39
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
40
+
41
+BRK
42
+
43
+|c000 @FRAME BRK
44
+|d000 @ERROR BRK 
45
+
46
+|FFFA .RESET .FRAME .ERROR
... ...
@@ -1,22 +1,44 @@
1 1
 ( comment )
2 2
 
3
+:dev/r fff8 ( const read port )
3 4
 :dev/w fff9 ( const write port )
4 5
 
6
+;x 2 ;y 2
7
+
5 8
 |0100 @RESET 
6 9
 
7
-	#01 ,dev/w STR                           ( set dev/write to screen ) 
10
+	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
11
+	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
12
+
13
+	#0080 ,x STR2
14
+	#0040 ,y STR2
15
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
8 16
 
9
-	( draw 1 pixel )
10
-	#00 #01 #0021 #0021 ,putpixel JSR
17
+BRK
18
+
19
+|0200 @SPRITESHEET
11 20
 
12
-	#04 ,dev/w STR                           ( set dev/write to screen ) 
21
+@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
22
+@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
13 23
 
14
-	#00 ,star_icn #0001 #0001 ,putsprite JSR
24
+BRK
15 25
 
16
-	#00 ,star_icn #0031 #0021 ,putsprite JSR
17
-	#00 ,cursor_icn #0021 #0016 ,putsprite JSR
18
-	#00 ,star_icn #0055 #0042 ,putsprite JSR
19
-	#01 ,cursor_icn #0067 #0031 ,putsprite JSR
26
+|c000 @FRAME 
27
+
28
+	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
29
+	,y LDR2 #0001 SUB2 ,y STR2
30
+	@next0
31
+	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
32
+	,y LDR2 #0001 ADD2 ,y STR2
33
+	@next1
34
+	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
35
+	,x LDR2 #0001 SUB2 ,x STR2
36
+	@next2
37
+	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
38
+	,x LDR2 #0001 ADD2 ,x STR2
39
+	@next3
40
+	( redraw )
41
+	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
20 42
 
21 43
 BRK
22 44
 
... ...
@@ -27,21 +49,6 @@ BRK
27 49
 	IOW  ( redraw byte )
28 50
 	RTS
29 51
 
30
-@putpixel 
31
-	IOW2 ( y short )
32
-	IOW2 ( x short )
33
-	IOW  ( color byte )
34
-	IOW  ( redraw byte )
35
-	RTS
36
-
37
-|0200 @SPRITESHEET
38
-
39
-@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
40
-@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
41
-
42
-BRK
43
-
44
-|c000 @FRAME BRK
45 52
 |d000 @ERROR BRK 
46 53
 
47 54
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -30,10 +30,10 @@ 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 31
 Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
32 32
 /* I/O */
33
-void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
33
+void op_brk(Uxn *u) { setflag(&u->status, FLAG_HALT, 1); }
34 34
 void op_lit(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("0x%02x ", pop8(&u->wst)); }
36
+void op_nop(Uxn *u) { printf("0x%02x \n", pop8(&u->wst)); fflush(stdout); }
37 37
 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))); }
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, &u->ram, a); }
39 39
 void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }