... | ... |
@@ -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)); } |