uxn

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

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

Redesigned devices

Diffstat:
Massembler.c | 2+-
Mbuild.sh | 10++++++----
Mcli.c | 26+++++++++++++-------------
Memulator.c | 27++++++++++++++++++++++++---
Mexamples/hello.usm | 4+---
Aexamples/pixel.usm | 20++++++++++++++++++++
Mexamples/test.usm | 10+++++++---
Muxn.c | 28++++++++--------------------
Muxn.h | 10+++++-----
9 files changed, 85 insertions(+), 52 deletions(-)

diff --git a/assembler.c b/assembler.c @@ -31,7 +31,7 @@ Program p; /* clang-format off */ char ops[][4] = { - "BRK", "LIT", "---", "---", "PEK", "POK", "LDR", "STR", + "BRK", "LIT", "---", "---", "IOR", "IOW", "LDR", "STR", "JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---", "POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL", "ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" diff --git a/build.sh b/build.sh @@ -8,19 +8,21 @@ clang-format -i assembler.c rm -f ./bin/assembler rm -f ./bin/boot.rom 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 assembler.c -o bin/assembler -./bin/assembler examples/hello.usm bin/boot.rom -# Cli -clang-format -i cli.c +# Core clang-format -i uxn.h 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 # Emulator -# clang-format -i emulator.c +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 # run +./bin/assembler examples/hello.usm bin/boot.rom ./bin/cli bin/boot.rom diff --git a/cli.c b/cli.c @@ -20,19 +20,19 @@ error(char *msg, const char *err) return 0; } -void -console_onread(Uint8 *b) +Uint8 +console_onread(Uint8 b) { (void)b; + return 0; } -void -console_onwrite(Uint8 *b) +Uint8 +console_onwrite(Uint8 b) { - if(b) { - printf("%c", *b); - *b = 0x00; - } + if(b) + printf("%c", b); + return 0; } void @@ -64,7 +64,7 @@ echom(Memory *m, Uint16 len, char *name) void echof(Uxn *c) { - printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n", + printf("\nEnded @ %d steps | hf: %x sf: %x sf: %x cf: %x\n", c->counter, getflag(&c->status, FLAG_HALT) != 0, getflag(&c->status, FLAG_SHORT) != 0, @@ -82,14 +82,14 @@ main(int argc, char **argv) return error("Boot", "Failed"); if(!loaduxn(&u, argv[1])) return error("Load", "Failed"); - portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); + portuxn(&u, "console", console_onread, console_onwrite); evaluxn(&u, u.vreset); evaluxn(&u, u.vframe); - -/* + + /* echos(&u.wst, 0x40, "stack"); echom(&u.ram, 0x40, "ram"); - echof(&u); */ + echof(&u); return 0; } diff --git a/emulator.c b/emulator.c @@ -150,13 +150,33 @@ dokey(SDL_Event *event) #pragma mark - Devices void -console_onread(void) +console_onread(Uint8 *b) { + (void)b; } void -console_onwrite(void) +console_onwrite(Uint8 *b) { + if(b) { + printf("%c", *b); + fflush(stdout); + *b = 0x00; + } +} + +Uint8 ppumem[5]; + +void +ppur(Uint8 *b) +{ +} + +void +ppuw(Uint8 *b) +{ + + printf("%02x\n", *b); } int @@ -201,7 +221,8 @@ main(int argc, char **argv) if(!init()) return error("Init", "Failed"); - portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); + portuxn(&u, 0xfff0, console_onread, console_onwrite); + portuxn(&u, 0xfff2, ppur, ppuw); start(&u); diff --git a/examples/hello.usm b/examples/hello.usm @@ -1,15 +1,13 @@ ( hello world ) ;iterator -:dev1r FFF0 -:dev1w FFF1 |0100 @RESET @word1 "hello_word ( len: 0x0b ) @loop - ,dev1w STR ( write to stdout ) + ,00 IOW ( write to device#0 ) ,incr JSR ( increment itr ) ,word1 ,strlen JSR ( get strlen ) NEQ ,loop ROT JSR? ( loop != strlen ) diff --git a/examples/pixel.usm b/examples/pixel.usm @@ -0,0 +1,20 @@ +( hello world ) + +:stdr FFF0 +:stdw FFF1 +:ppur FFF2 +:ppuw FFF3 + +|0100 @RESET + + ,11 ,ppuw STR ( x0 ) + ,23 ,ppuw STR ( x1 ) + ,12 ,ppuw STR ( y0 ) + ,34 ,ppuw STR ( y1 ) + ,01 ,ppuw STR ( clr ) + +BRK + +|c000 @FRAME BRK +|d000 @ERROR BRK +|FFFA .RESET .FRAME .ERROR diff --git a/examples/test.usm b/examples/test.usm @@ -1,11 +1,15 @@ ( my default test file ) ;iterator -:dev1r FFF0 -:dev1w FFF1 |0100 @RESET -,01 ,02 ,03 + + ,01 ,00 IOW + ,02 ,00 IOW + ,03 ,00 IOW + ,04 ,00 IOW + ,05 ,00 IOW + BRK |c000 @FRAME BRK diff --git a/uxn.c b/uxn.c @@ -33,8 +33,10 @@ 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_ldr(Uxn *u) { wspush8(u, u->ram.dat[wspop16(u)]); } -void op_str(Uxn *u) { u->ram.dat[wspop16(u)] = wspop8(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_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 */ void op_jmp(Uxn *u) { u->ram.ptr = wspop16(u); } void op_jsr(Uxn *u) { u->rst.dat[u->rst.ptr++] = u->ram.ptr; u->ram.ptr = wspop16(u); } @@ -77,7 +79,7 @@ void op_gth16(Uxn *u) { Uint16 a = wspop16(u), b = wspop16(u); wspush8(u, b > a) void op_lth16(Uxn *u) { Uint16 a = wspop16(u), b = wspop16(u); wspush8(u, b < a); } void (*ops[])(Uxn *u) = { - op_brk, op_lit, op_nop, op_nop, op_nop, op_nop, op_ldr, op_str, + op_brk, op_lit, op_nop, op_nop, op_ior, op_iow, op_ldr, op_str, op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, @@ -86,7 +88,7 @@ void (*ops[])(Uxn *u) = { }; Uint8 opr[][2] = { - {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {3,0}, + {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {2,0}, {2,1}, {3,0}, {2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {1,0}, {1,2}, {2,2}, {3,3}, {3,3}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, @@ -114,17 +116,6 @@ lituxn(Uxn *u, Uint8 instr) } int -devuxn(Uxn *u) -{ - int i; - for(i = 0; i < u->devices; ++i) { - u->dev[i].wfn(&u->ram.dat[u->dev[i].w]); - u->dev[i].rfn(&u->ram.dat[u->dev[i].r]); - } - return 1; -} - -int opcuxn(Uxn *u, Uint8 instr) { Uint8 op = instr & 0x1f; @@ -139,7 +130,6 @@ opcuxn(Uxn *u, Uint8 instr) return haltuxn(u, "Stack overflow", instr); if(!getflag(&u->status, FLAG_COND) || (getflag(&u->status, FLAG_COND) && wspop8(u))) (*ops[op])(u); - devuxn(u); return 1; } @@ -197,13 +187,11 @@ loaduxn(Uxn *u, char *filepath) /* to start: evaluxn(u, u->vreset); */ int -portuxn(Uxn *u, Uint16 r, Uint16 w, void (*onread)(Uint8 *), void (*onwrite)(Uint8 *)) +portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8)) { Device *d = &u->dev[u->devices++]; - d->r = r; - d->w = w; d->rfn = onread; d->wfn = onwrite; - printf("Created device: #%d, at r:%04x w:%04x\n", u->devices, r, w); + printf("Device#%d: %s \n", u->devices, name); return 1; } diff --git a/uxn.h b/uxn.h @@ -35,9 +35,9 @@ typedef struct { } Memory; typedef struct { - Uint16 r, w; - void (*rfn)(Uint8 *); - void (*wfn)(Uint8 *); + Uint16 index; + Uint8 (*rfn)(Uint8); + Uint8 (*wfn)(Uint8); } Device; typedef struct { @@ -46,7 +46,7 @@ typedef struct { Stack8 wst; Stack16 rst; Memory ram; - Device dev[64]; + Device dev[256]; } Uxn; void setflag(Uint8 *status, char flag, int b); @@ -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, Uint16 r, Uint16 w, void (*onread)(Uint8 *), void (*onwrite)(Uint8 *)); +int portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8));