uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit 17578d8bbb44bb4aecb2f487b04acdac8af01e69
parent 56ca1091b456d668b05ccc5c5b60cb19a8859c59
Author: neauoire <aliceffekt@gmail.com>
Date:   Tue,  9 Feb 2021 10:58:06 -0800

Better PPU design

Diffstat:
Mbuild.sh | 12++++++------
Mcli.c | 6++++--
Memulator.c | 61++++++++++++++++++++++++++++++++++++++++---------------------
Mexamples/hello.usm | 2+-
Mexamples/pixel.usm | 32+++++++++++++++++++++-----------
Muxn.c | 7++++---
Muxn.h | 10+++++-----
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));