Browse code

Better PPU design

neauoire authored on 09/02/2021 18:58:06
Showing 7 changed files
... ...
@@ -15,14 +15,14 @@ clang-format -i uxn.c
15 15
 
16 16
 # Cli
17 17
 clang-format -i cli.c
18
-rm -f ./bin/cli
19
-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 cli.c -o bin/cli
18
+# rm -f ./bin/cli
19
+# 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 cli.c -o bin/cli
20 20
 
21 21
 # Emulator
22 22
 clang-format -i emulator.c
23
-# rm -f ./bin/emulator
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
23
+rm -f ./bin/emulator
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/hello.usm bin/boot.rom
28
-./bin/cli bin/boot.rom
27
+./bin/assembler examples/pixel.usm bin/boot.rom
28
+./bin/emulator bin/boot.rom
... ...
@@ -21,15 +21,17 @@ error(char *msg, const char *err)
21 21
 }
22 22
 
23 23
 Uint8
24
-console_onread(Uint8 b)
24
+console_onread(Device *d, Uint8 b)
25 25
 {
26
+	(void)d;
26 27
 	(void)b;
27 28
 	return 0;
28 29
 }
29 30
 
30 31
 Uint8
31
-console_onwrite(Uint8 b)
32
+console_onwrite(Device *d, Uint8 b)
32 33
 {
34
+	(void)d;
33 35
 	if(b)
34 36
 		printf("%c", b);
35 37
 	return 0;
... ...
@@ -53,6 +53,13 @@ clear(Uint32 *dst)
53 53
 			dst[v * WIDTH + h] = theme[0];
54 54
 }
55 55
 
56
+void
57
+putpixel(Uint32 *dst, int x, int y, int color)
58
+{
59
+	if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
60
+		dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
61
+}
62
+
56 63
 void
57 64
 redraw(Uint32 *dst)
58 65
 {
... ...
@@ -149,34 +156,46 @@ dokey(SDL_Event *event)
149 156
 
150 157
 #pragma mark - Devices
151 158
 
152
-void
153
-console_onread(Uint8 *b)
159
+Uint8
160
+console_onread(Device *d, Uint8 b)
154 161
 {
155 162
 	(void)b;
163
+	(void)d;
164
+	return 0;
156 165
 }
157 166
 
158
-void
159
-console_onwrite(Uint8 *b)
167
+Uint8
168
+console_onwrite(Device *d, Uint8 b)
160 169
 {
161
-	if(b) {
162
-		printf("%c", *b);
163
-		fflush(stdout);
164
-		*b = 0x00;
165
-	}
170
+	(void)d;
171
+	if(b)
172
+		printf("%c", b);
173
+	fflush(stdout);
174
+	return 0;
166 175
 }
167 176
 
168
-Uint8 ppumem[5];
169
-
170
-void
171
-ppur(Uint8 *b)
177
+Uint8
178
+ppur(Device *d, Uint8 b)
172 179
 {
180
+	(void)b;
181
+	(void)d;
182
+	return 0;
173 183
 }
174 184
 
175
-void
176
-ppuw(Uint8 *b)
185
+Uint8
186
+ppuw(Device *d, Uint8 b)
177 187
 {
178
-
179
-	printf("%02x\n", *b);
188
+	d->mem[d->len++] = b;
189
+	if(d->len > 5) {
190
+		putpixel(pixels,
191
+			(d->mem[0] << 8) + d->mem[1],
192
+			(d->mem[2] << 8) + d->mem[3],
193
+			d->mem[4]);
194
+		if(d->mem[5])
195
+			redraw(pixels);
196
+		d->len = 0;
197
+	}
198
+	return 0;
180 199
 }
181 200
 
182 201
 int
... ...
@@ -207,11 +226,11 @@ start(Uxn *u)
207 226
 	}
208 227
 }
209 228
 
210
-Uxn u;
211
-
212 229
 int
213 230
 main(int argc, char **argv)
214 231
 {
232
+	Uxn u;
233
+
215 234
 	if(argc < 2)
216 235
 		return error("Input", "Missing");
217 236
 	if(!bootuxn(&u))
... ...
@@ -221,8 +240,8 @@ main(int argc, char **argv)
221 240
 	if(!init())
222 241
 		return error("Init", "Failed");
223 242
 
224
-	portuxn(&u, 0xfff0, console_onread, console_onwrite);
225
-	portuxn(&u, 0xfff2, ppur, ppuw);
243
+	portuxn(&u, "console", console_onread, console_onwrite);
244
+	portuxn(&u, "PPU", ppur, ppuw);
226 245
 
227 246
 	start(&u);
228 247
 
... ...
@@ -4,7 +4,7 @@
4 4
 
5 5
 |0100 @RESET
6 6
 
7
-@word1 "hello_word ( len: 0x0b )
7
+@word1 "hello_world ( len: 0x0b )
8 8
 
9 9
 @loop
10 10
 	,00 IOW ( write to device#0 )
... ...
@@ -1,17 +1,27 @@
1
-( hello world )
2
-
3
-:stdr FFF0
4
-:stdw FFF1
5
-:ppur FFF2
6
-:ppuw FFF3
1
+( draw pixel )
7 2
 
8 3
 |0100 @RESET
9 4
 
10
-	,11 ,ppuw STR ( x0 )
11
-	,23 ,ppuw STR ( x1 )
12
-	,12 ,ppuw STR ( y0 )
13
-	,34 ,ppuw STR ( y1 )
14
-	,01 ,ppuw STR ( clr )
5
+	,0001 IOW ( x0 )
6
+	,0001 IOW ( x1 )
7
+	,0001 IOW ( y0 )
8
+	,0001 IOW ( y1 )
9
+	,0101 IOW ( clr )
10
+	,0001 IOW ( noredraw )
11
+
12
+	,0001 IOW ( x0 )
13
+	,0101 IOW ( x1 )
14
+	,0001 IOW ( y0 )
15
+	,0001 IOW ( y1 )
16
+	,0201 IOW ( clr )
17
+	,0001 IOW ( noredraw )
18
+
19
+	,0001 IOW ( x0 )
20
+	,0201 IOW ( x1 )
21
+	,0001 IOW ( y0 )
22
+	,0001 IOW ( y1 )
23
+	,0301 IOW ( clr )
24
+	,0101 IOW ( redraw! )
15 25
 
16 26
 BRK
17 27
 
... ...
@@ -33,8 +33,8 @@ Uint16 mempeek16(Uxn *u, Uint16 s) { return (u->ram.dat[s] << 8) + (u->ram.dat[s
33 33
 void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
34 34
 void op_lit(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
35 35
 void op_nop(Uxn *u) { printf("NOP"); (void)u; }
36
-void op_ior(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) wspush8(u, dev->rfn(devop)); }
37
-void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) dev->wfn(devop); }
36
+void op_ior(Uxn *u) { Uint8 devid = wspop8(u); Uint16 devop = wspop8(u); Device *dev = &u->dev[devid]; if(devid < u->devices) wspush8(u, dev->rfn(dev,devop)); }
37
+void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint16 devop = wspop8(u); Device *dev = &u->dev[devid]; if(devid < u->devices) dev->wfn(dev,devop); }
38 38
 void op_ldr(Uxn *u) { Uint16 a = wspop16(u); wspush8(u, u->ram.dat[a]); }
39 39
 void op_str(Uxn *u) { Uint16 a = wspop16(u); Uint8 b = wspop8(u); u->ram.dat[a] = b; }
40 40
 /* Logic */
... ...
@@ -187,11 +187,12 @@ loaduxn(Uxn *u, char *filepath)
187 187
 /* to start: evaluxn(u, u->vreset); */
188 188
 
189 189
 int
190
-portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8))
190
+portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8))
191 191
 {
192 192
 	Device *d = &u->dev[u->devices++];
193 193
 	d->rfn = onread;
194 194
 	d->wfn = onwrite;
195
+	d->len = 0;
195 196
 	printf("Device#%d: %s \n", u->devices, name);
196 197
 	return 1;
197 198
 }
... ...
@@ -34,10 +34,10 @@ typedef struct {
34 34
 	Uint8 dat[65536];
35 35
 } Memory;
36 36
 
37
-typedef struct {
38
-	Uint16 index;
39
-	Uint8 (*rfn)(Uint8);
40
-	Uint8 (*wfn)(Uint8);
37
+typedef struct Device {
38
+	Uint8 len, mem[8];
39
+	Uint8 (*rfn)(struct Device *, Uint8);
40
+	Uint8 (*wfn)(struct Device *, Uint8);
41 41
 } Device;
42 42
 
43 43
 typedef struct {
... ...
@@ -54,4 +54,4 @@ int getflag(Uint8 *status, char flag);
54 54
 int loaduxn(Uxn *c, char *filepath);
55 55
 int bootuxn(Uxn *c);
56 56
 int evaluxn(Uxn *u, Uint16 vec);
57
-int portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8));
57
+int portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8));