commit 17578d8bbb44bb4aecb2f487b04acdac8af01e69
parent 56ca1091b456d668b05ccc5c5b60cb19a8859c59
Author: neauoire <aliceffekt@gmail.com>
Date: Tue, 9 Feb 2021 10:58:06 -0800
Better PPU design
Diffstat:
7 files changed, 81 insertions(+), 49 deletions(-)
diff --git a/build.sh b/build.sh
@@ -15,14 +15,14 @@ clang-format -i uxn.c
# Cli
clang-format -i cli.c
-rm -f ./bin/cli
-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
+# rm -f ./bin/cli
+# 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
# Emulator
clang-format -i emulator.c
-# 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
+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/hello.usm bin/boot.rom
-./bin/cli bin/boot.rom
+./bin/assembler examples/pixel.usm bin/boot.rom
+./bin/emulator bin/boot.rom
diff --git a/cli.c b/cli.c
@@ -21,15 +21,17 @@ error(char *msg, const char *err)
}
Uint8
-console_onread(Uint8 b)
+console_onread(Device *d, Uint8 b)
{
+ (void)d;
(void)b;
return 0;
}
Uint8
-console_onwrite(Uint8 b)
+console_onwrite(Device *d, Uint8 b)
{
+ (void)d;
if(b)
printf("%c", b);
return 0;
diff --git a/emulator.c b/emulator.c
@@ -54,6 +54,13 @@ clear(Uint32 *dst)
}
void
+putpixel(Uint32 *dst, int x, int y, int color)
+{
+ if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
+ dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
+}
+
+void
redraw(Uint32 *dst)
{
SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32));
@@ -149,34 +156,46 @@ dokey(SDL_Event *event)
#pragma mark - Devices
-void
-console_onread(Uint8 *b)
+Uint8
+console_onread(Device *d, Uint8 b)
{
(void)b;
+ (void)d;
+ return 0;
}
-void
-console_onwrite(Uint8 *b)
+Uint8
+console_onwrite(Device *d, Uint8 b)
{
- if(b) {
- printf("%c", *b);
- fflush(stdout);
- *b = 0x00;
- }
+ (void)d;
+ if(b)
+ printf("%c", b);
+ fflush(stdout);
+ return 0;
}
-Uint8 ppumem[5];
-
-void
-ppur(Uint8 *b)
+Uint8
+ppur(Device *d, Uint8 b)
{
+ (void)b;
+ (void)d;
+ return 0;
}
-void
-ppuw(Uint8 *b)
+Uint8
+ppuw(Device *d, Uint8 b)
{
-
- printf("%02x\n", *b);
+ d->mem[d->len++] = b;
+ if(d->len > 5) {
+ putpixel(pixels,
+ (d->mem[0] << 8) + d->mem[1],
+ (d->mem[2] << 8) + d->mem[3],
+ d->mem[4]);
+ if(d->mem[5])
+ redraw(pixels);
+ d->len = 0;
+ }
+ return 0;
}
int
@@ -207,11 +226,11 @@ start(Uxn *u)
}
}
-Uxn u;
-
int
main(int argc, char **argv)
{
+ Uxn u;
+
if(argc < 2)
return error("Input", "Missing");
if(!bootuxn(&u))
@@ -221,8 +240,8 @@ main(int argc, char **argv)
if(!init())
return error("Init", "Failed");
- portuxn(&u, 0xfff0, console_onread, console_onwrite);
- portuxn(&u, 0xfff2, ppur, ppuw);
+ portuxn(&u, "console", console_onread, console_onwrite);
+ portuxn(&u, "PPU", ppur, ppuw);
start(&u);
diff --git a/examples/hello.usm b/examples/hello.usm
@@ -4,7 +4,7 @@
|0100 @RESET
-@word1 "hello_word ( len: 0x0b )
+@word1 "hello_world ( len: 0x0b )
@loop
,00 IOW ( write to device#0 )
diff --git a/examples/pixel.usm b/examples/pixel.usm
@@ -1,17 +1,27 @@
-( hello world )
-
-:stdr FFF0
-:stdw FFF1
-:ppur FFF2
-:ppuw FFF3
+( draw pixel )
|0100 @RESET
- ,11 ,ppuw STR ( x0 )
- ,23 ,ppuw STR ( x1 )
- ,12 ,ppuw STR ( y0 )
- ,34 ,ppuw STR ( y1 )
- ,01 ,ppuw STR ( clr )
+ ,0001 IOW ( x0 )
+ ,0001 IOW ( x1 )
+ ,0001 IOW ( y0 )
+ ,0001 IOW ( y1 )
+ ,0101 IOW ( clr )
+ ,0001 IOW ( noredraw )
+
+ ,0001 IOW ( x0 )
+ ,0101 IOW ( x1 )
+ ,0001 IOW ( y0 )
+ ,0001 IOW ( y1 )
+ ,0201 IOW ( clr )
+ ,0001 IOW ( noredraw )
+
+ ,0001 IOW ( x0 )
+ ,0201 IOW ( x1 )
+ ,0001 IOW ( y0 )
+ ,0001 IOW ( y1 )
+ ,0301 IOW ( clr )
+ ,0101 IOW ( redraw! )
BRK
diff --git a/uxn.c b/uxn.c
@@ -33,8 +33,8 @@ Uint16 mempeek16(Uxn *u, Uint16 s) { return (u->ram.dat[s] << 8) + (u->ram.dat[s
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
void op_lit(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
void op_nop(Uxn *u) { printf("NOP"); (void)u; }
-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)); }
-void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) dev->wfn(devop); }
+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)); }
+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); }
void op_ldr(Uxn *u) { Uint16 a = wspop16(u); wspush8(u, u->ram.dat[a]); }
void op_str(Uxn *u) { Uint16 a = wspop16(u); Uint8 b = wspop8(u); u->ram.dat[a] = b; }
/* Logic */
@@ -187,11 +187,12 @@ loaduxn(Uxn *u, char *filepath)
/* to start: evaluxn(u, u->vreset); */
int
-portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8))
+portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8))
{
Device *d = &u->dev[u->devices++];
d->rfn = onread;
d->wfn = onwrite;
+ d->len = 0;
printf("Device#%d: %s \n", u->devices, name);
return 1;
}
diff --git a/uxn.h b/uxn.h
@@ -34,10 +34,10 @@ typedef struct {
Uint8 dat[65536];
} Memory;
-typedef struct {
- Uint16 index;
- Uint8 (*rfn)(Uint8);
- Uint8 (*wfn)(Uint8);
+typedef struct Device {
+ Uint8 len, mem[8];
+ Uint8 (*rfn)(struct Device *, Uint8);
+ Uint8 (*wfn)(struct Device *, Uint8);
} Device;
typedef struct {
@@ -54,4 +54,4 @@ int getflag(Uint8 *status, char flag);
int loaduxn(Uxn *c, char *filepath);
int bootuxn(Uxn *c);
int evaluxn(Uxn *u, Uint16 vec);
-int portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8));
+int portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8));