Browse code

Added chr/icn parser to PPU

neauoire authored on 14/02/2021 18:22:42
Showing 6 changed files
... ...
@@ -213,8 +213,8 @@ pass1(FILE *f)
213 213
 		else {
214 214
 			switch(w[0]) {
215 215
 			case '|': addr = shex(w + 1); break;
216
-			case '.': addr += 2; break;
217 216
 			case ',': addr += 3; break;
217
+			case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break;
218 218
 			case '+': /* signed positive */
219 219
 			case '-': /* signed negative */
220 220
 			case '#': addr += (slen(w + 1) == 2 ? 2 : 3); break;
... ...
@@ -242,8 +242,10 @@ pass2(FILE *f)
242 242
 		else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
243 243
 		else if(w[0] == ':') fscanf(f, "%s", w);
244 244
 		else if(w[0] == ';') fscanf(f, "%s", w);
245
-		else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w), 1); 
246
-		else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w), 1);
245
+		else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 0);
246
+		else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 0);
247
+		else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 1); 
248
+		else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 1);
247 249
 		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
248 250
 		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
249 251
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
... ...
@@ -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/line.usm bin/boot.rom
27
+./bin/assembler examples/test.usm bin/boot.rom
28 28
 ./bin/emulator bin/boot.rom
... ...
@@ -37,14 +37,9 @@ SDL_Renderer *gRenderer;
37 37
 SDL_Texture *gTexture;
38 38
 Uint32 *pixels;
39 39
 
40
-Device *devconsole, *devscreen, *devmouse, *devkey;
40
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
41 41
 
42
-int
43
-error(char *msg, const char *err)
44
-{
45
-	printf("Error %s: %s\n", msg, err);
46
-	return 0;
47
-}
42
+#pragma mark - Helpers
48 43
 
49 44
 void
50 45
 clear(Uint32 *dst)
... ...
@@ -59,7 +54,41 @@ void
59 54
 putpixel(Uint32 *dst, int x, int y, int color)
60 55
 {
61 56
 	if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
62
-		dst[y * WIDTH + x] = theme[color];
57
+		dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
58
+}
59
+
60
+void
61
+drawchr(Uint32 *dst, int x, int y, Uint8 *sprite)
62
+{
63
+	int v, h;
64
+	for(v = 0; v < 8; v++)
65
+		for(h = 0; h < 8; h++) {
66
+			int ch1 = ((sprite[v] >> h) & 0x1);
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);
71
+		}
72
+}
73
+
74
+void
75
+drawicn(Uint32 *dst, int x, int y, Uint8 *sprite, int fg, int bg)
76
+{
77
+	int v, h;
78
+	for(v = 0; v < 8; v++)
79
+		for(h = 0; h < 8; h++) {
80
+			int ch1 = (sprite[v] >> (7 - h)) & 0x1;
81
+			putpixel(dst, x + h, y + v, ch1 ? fg : bg);
82
+		}
83
+}
84
+
85
+#pragma mark - Core
86
+
87
+int
88
+error(char *msg, const char *err)
89
+{
90
+	printf("Error %s: %s\n", msg, err);
91
+	return 0;
63 92
 }
64 93
 
65 94
 void
... ...
@@ -170,7 +199,7 @@ dokey(SDL_Event *event)
170 199
 #pragma mark - Devices
171 200
 
172 201
 Uint8
173
-consoler(Device *d, Uint8 b)
202
+consoler(Device *d, Memory *m, Uint8 b)
174 203
 {
175 204
 	(void)b;
176 205
 	(void)d;
... ...
@@ -178,7 +207,7 @@ consoler(Device *d, Uint8 b)
178 207
 }
179 208
 
180 209
 Uint8
181
-consolew(Device *d, Uint8 b)
210
+consolew(Device *d, Memory *m, Uint8 b)
182 211
 {
183 212
 	(void)d;
184 213
 	if(b)
... ...
@@ -188,7 +217,7 @@ consolew(Device *d, Uint8 b)
188 217
 }
189 218
 
190 219
 Uint8
191
-screenr(Device *d, Uint8 b)
220
+ppur(Device *d, Memory *m, Uint8 b)
192 221
 {
193 222
 	switch(b) {
194 223
 	case 0: return (WIDTH >> 8) & 0xff;
... ...
@@ -200,7 +229,7 @@ screenr(Device *d, Uint8 b)
200 229
 }
201 230
 
202 231
 Uint8
203
-screenw(Device *d, Uint8 b)
232
+ppuw(Device *d, Memory *m, Uint8 b)
204 233
 {
205 234
 	d->mem[d->len++] = b;
206 235
 	if(d->len > 5) {
... ...
@@ -216,13 +245,35 @@ screenw(Device *d, Uint8 b)
216 245
 }
217 246
 
218 247
 Uint8
219
-mouser(Device *d, Uint8 b)
248
+ppusr(Device *d, Memory *m, Uint8 b)
249
+{
250
+	return 0;
251
+}
252
+
253
+Uint8
254
+ppusw(Device *d, Memory *m, Uint8 b)
255
+{
256
+	d->mem[d->len++] = b;
257
+	if(d->len > 6) {
258
+		Uint16 x = (d->mem[2] << 8) + d->mem[3];
259
+		Uint16 y = (d->mem[0] << 8) + d->mem[1];
260
+		Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]];
261
+		drawchr(pixels, x, y, chr);
262
+		if(d->mem[6])
263
+			redraw(pixels);
264
+		d->len = 0;
265
+	}
266
+	return 0;
267
+}
268
+
269
+Uint8
270
+mouser(Device *d, Memory *m, Uint8 b)
220 271
 {
221 272
 	return d->mem[b];
222 273
 }
223 274
 
224 275
 Uint8
225
-mousew(Device *d, Uint8 b)
276
+mousew(Device *d, Memory *m, Uint8 b)
226 277
 {
227 278
 	(void)d;
228 279
 	(void)b;
... ...
@@ -230,7 +281,7 @@ mousew(Device *d, Uint8 b)
230 281
 }
231 282
 
232 283
 Uint8
233
-keyr(Device *d, Uint8 b)
284
+keyr(Device *d, Memory *m, Uint8 b)
234 285
 {
235 286
 	(void)d;
236 287
 	(void)b;
... ...
@@ -238,7 +289,7 @@ keyr(Device *d, Uint8 b)
238 289
 }
239 290
 
240 291
 Uint8
241
-keyw(Device *d, Uint8 b)
292
+keyw(Device *d, Memory *m, Uint8 b)
242 293
 {
243 294
 	(void)d;
244 295
 	(void)b;
... ...
@@ -295,9 +346,10 @@ main(int argc, char **argv)
295 346
 		return error("Init", "Failed");
296 347
 
297 348
 	devconsole = portuxn(&u, "console", consoler, consolew);
298
-	devscreen = portuxn(&u, "screen", screenr, screenw);
349
+	devscreen = portuxn(&u, "ppu", ppur, ppuw);
299 350
 	devmouse = portuxn(&u, "mouse", mouser, mousew);
300 351
 	devkey = portuxn(&u, "key", keyr, keyw);
352
+	devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
301 353
 
302 354
 	start(&u);
303 355
 
... ...
@@ -4,16 +4,42 @@
4 4
 
5 5
 |0100 @RESET 
6 6
 
7
-	#00 ,dev/w STR                           ( set dev/write to console ) 
8
-	,string                                  ( add string pointer to stack )
9
-	@loop
10
-		DUP2 LDR IOW                         ( write pointer value to console )
11
-		#0001 ADD2                           ( increment string pointer )
12
-		DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
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
+
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
13 20
 
14 21
 BRK
15 22
 
16
-@string " Hello World "                      ( add string to memory )
23
+@putsprite
24
+	IOW2 ( y short )
25
+	IOW2 ( x short )
26
+	IOW2 ( sprite address )
27
+	IOW  ( redraw byte )
28
+	RTS
29
+
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
17 43
 
18 44
 |c000 @FRAME BRK
19 45
 |d000 @ERROR BRK 
... ...
@@ -34,8 +34,8 @@ 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 36
 void op_nop(Uxn *u) { printf("0x%02x ", pop8(&u->wst)); }
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
-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); }
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
+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)); }
40 40
 void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); }
41 41
 /* Logic */
... ...
@@ -63,8 +63,8 @@ void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
63 63
 /* --- */
64 64
 void op_lit16(Uxn *u) { u->literal += 2; }
65 65
 void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
66
-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)); }
67
-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
+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, &u->ram, a) << 8) + dev->read(dev, &u->ram, a + 1)); }
67
+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, &u->ram, b); dev->write(dev, &u->ram, a); } }
68 68
 void op_ldr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->wst, mempeek16(&u->ram, a)); }
69 69
 void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); }
70 70
 /* Stack(16-bits) */
... ...
@@ -202,7 +202,7 @@ loaduxn(Uxn *u, char *filepath)
202 202
 }
203 203
 
204 204
 Device *
205
-portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Uint8), Uint8 (*wfn)(Device *, Uint8))
205
+portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8))
206 206
 {
207 207
 	Device *d = &u->dev[u->devices++];
208 208
 	d->read = rfn;
... ...
@@ -33,8 +33,8 @@ typedef struct {
33 33
 
34 34
 typedef struct Device {
35 35
 	Uint8 len, mem[8];
36
-	Uint8 (*read)(struct Device *, Uint8);
37
-	Uint8 (*write)(struct Device *, Uint8);
36
+	Uint8 (*read)(struct Device *, Memory *, Uint8);
37
+	Uint8 (*write)(struct Device *, Memory *, Uint8);
38 38
 } Device;
39 39
 
40 40
 typedef struct {
... ...
@@ -50,4 +50,4 @@ int getflag(Uint8 *status, char flag);
50 50
 int loaduxn(Uxn *c, char *filepath);
51 51
 int bootuxn(Uxn *c);
52 52
 int evaluxn(Uxn *u, Uint16 vec);
53
-Device *portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Uint8), Uint8 (*wfn)(Device *, Uint8));
53
+Device *portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8));