uxn

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

commit 5c5b767eafef9b82cfaa976469f133e8f88bddeb
parent e792fd01b756238a6e25a18aef57782d65a20460
Author: neauoire <aliceffekt@gmail.com>
Date:   Sat, 24 Apr 2021 09:43:30 -0700

Working toward bidirectional talk between devices and program

Diffstat:
Mbuild.sh | 2+-
Aprojects/examples/devices/console.lib.usm | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mprojects/examples/devices/console.usm | 53+++--------------------------------------------------
Msrc/debugger.c | 20++++++++++----------
Msrc/emulator.c | 54+++++++++++++++++++++++++++---------------------------
Msrc/uxn.c | 8++++----
Msrc/uxn.h | 6+++---
7 files changed, 134 insertions(+), 95 deletions(-)

diff --git a/build.sh b/build.sh @@ -32,7 +32,7 @@ else fi echo "Assembling.." -./bin/assembler projects/demos/bifurcan.usm bin/boot.rom +./bin/assembler projects/examples/devices/console.lib.usm bin/boot.rom echo "Running.." if [ "${2}" = '--cli' ]; diff --git a/projects/examples/devices/console.lib.usm b/projects/examples/devices/console.lib.usm @@ -0,0 +1,86 @@ +( dev/console ) + +%RTN { JMP2r } +%PRINT { .Console/string DEO2 } +%BR { #0a .Console/char DEO } + +( devices ) + +|10 @Console [ &pad $8 &char $1 &byte $1 &short $2 &string $2 ] + +( variables ) + +|0000 + +@number [ &started $1 ] + +( init ) + +|0100 ( -> ) + + [ ;char-txt PRINT ] #42 .Console/char DEO BR + [ ;byte-txt PRINT ] #ab .Console/byte DEO BR + [ ;short-txt PRINT ] #cdef .Console/short DEO2 BR + [ ;string-txt PRINT ] ;hello-word .Console/string DEO2 BR + + ;hello-word ;print JSR2 + #ffff ;print-hexadecimal JSR2 + ;is-word ;print JSR2 + #ffff ;print-decimal JSR2 + +BRK + +@print ( addr -- ) + + &loop + ( send ) DUP2 GET .Console/char DEO + ( incr ) #0001 ADD2 + ( loop ) DUP2 GET ,&loop JNZ + POP2 + +RTN + +@print-hexadecimal ( short -- ) + LIT '0 .Console/char DEO + LIT 'x .Console/char DEO + DUP2 #000c SFT2 ,&digit JSR + DUP2 #0008 SFT2 ,&digit JSR + DUP2 #0004 SFT2 ,&digit JSR + ,&digit JSR +RTN + + &digit + #0f AND DUP #0a LTH ,&not-alpha JNZ + #27 ADD + &not-alpha + LIT '0 ADD .Console/char DEO + POP +RTN + +@print-decimal ( short -- ) + #00 .number/started POK + DUP2 #2710 DIV2 DUP2 ,&digit JSR #2710 MUL2 SUB2 + DUP2 #03e8 DIV2 DUP2 ,&digit JSR #03e8 MUL2 SUB2 + DUP2 #0064 DIV2 DUP2 ,&digit JSR #0064 MUL2 SUB2 + DUP2 #000a DIV2 DUP2 ,&digit JSR #000a MUL2 SUB2 + ,&digit JSR + .number/started PEK ,&end JNZ + LIT '0 .Console/char DEO + &end +RTN + + &digit + SWP POP + DUP .number/started PEK ORA #02 JNZ + POP JMP2r + LIT '0 ADD .Console/char DEO + #01 .number/started POK +RTN + +@char-txt "char: 20 $1 +@byte-txt "byte: 20 $1 +@short-txt "short: 20 $1 +@string-txt "string: 20 $1 + +@hello-word "hello 20 "World! 0a 00 +@is-word 20 "is 20 00 diff --git a/projects/examples/devices/console.usm b/projects/examples/devices/console.usm @@ -6,20 +6,11 @@ |10 @Console [ &pad $8 &char $1 ] -( variables ) - -|0000 - -@number [ &started $1 ] - ( init ) |0100 ( -> ) ;hello-word ;print JSR2 - #ffff ;print-hexadecimal JSR2 - ;is-word ;print JSR2 - #ffff ;print-decimal JSR2 BRK @@ -28,48 +19,9 @@ BRK &loop ( send ) DUP2 GET .Console/char DEO ( incr ) #0001 ADD2 - ( loop ) DUP2 GET ,&loop JNZ + ( loop ) DUP2 GET #00 NEQ ,&loop JNZ POP2 RTN -@print-hexadecimal ( short -- ) - LIT '0 .Console/char DEO - LIT 'x .Console/char DEO - DUP2 #000c SFT2 ,&digit JSR - DUP2 #0008 SFT2 ,&digit JSR - DUP2 #0004 SFT2 ,&digit JSR - ,&digit JSR -RTN - - &digit - #0f AND DUP #0a LTH ,&not-alpha JNZ - #27 ADD - &not-alpha - LIT '0 ADD .Console/char DEO - POP -RTN - -@print-decimal ( short -- ) - #00 .number/started POK - DUP2 #2710 DIV2 DUP2 ,&digit JSR #2710 MUL2 SUB2 - DUP2 #03e8 DIV2 DUP2 ,&digit JSR #03e8 MUL2 SUB2 - DUP2 #0064 DIV2 DUP2 ,&digit JSR #0064 MUL2 SUB2 - DUP2 #000a DIV2 DUP2 ,&digit JSR #000a MUL2 SUB2 - ,&digit JSR - .number/started PEK ,&end JNZ - LIT '0 .Console/char DEO - &end -RTN - - &digit - SWP POP - DUP .number/started PEK ORA #02 JNZ - POP JMP2r - LIT '0 ADD .Console/char DEO - #01 .number/started POK -RTN - -@hello-word "hello 20 "World! 0a 00 -@is-word 20 "is 20 00 - +@hello-word "hello 20 "World! +\ No newline at end of file diff --git a/src/debugger.c b/src/debugger.c @@ -38,7 +38,7 @@ printstack(Stack *s) #pragma mark - Devices void -console_poke(Device *d, Uint8 b0, Uint8 b1) +console_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { switch(b0) { case 0x08: printf("%c", b1); break; @@ -51,7 +51,7 @@ console_poke(Device *d, Uint8 b0, Uint8 b1) } void -file_poke(Device *d, Uint8 b0, Uint8 b1) +file_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { Uint8 read = b0 == 0xd; if(read || b0 == 0xf) { @@ -71,7 +71,7 @@ file_poke(Device *d, Uint8 b0, Uint8 b1) } void -ppnil(Device *d, Uint8 b0, Uint8 b1) +nil_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { (void)d; (void)b0; @@ -106,13 +106,13 @@ main(int argc, char **argv) if(!loaduxn(&u, argv[1])) return error("Load", "Failed"); - portuxn(&u, 0x00, "console", console_poke); - portuxn(&u, 0x01, "empty", ppnil); - portuxn(&u, 0x02, "empty", ppnil); - portuxn(&u, 0x03, "empty", ppnil); - portuxn(&u, 0x04, "empty", ppnil); - portuxn(&u, 0x05, "empty", ppnil); - portuxn(&u, 0x06, "file", file_poke); + portuxn(&u, 0x00, "console", console_talk); + portuxn(&u, 0x01, "empty", nil_talk); + portuxn(&u, 0x02, "empty", nil_talk); + portuxn(&u, 0x03, "empty", nil_talk); + portuxn(&u, 0x04, "empty", nil_talk); + portuxn(&u, 0x05, "empty", nil_talk); + portuxn(&u, 0x06, "file", file_talk); start(&u); return 0; diff --git a/src/emulator.c b/src/emulator.c @@ -182,7 +182,7 @@ doctrl(Uxn *u, SDL_Event *event, int z) #pragma mark - Devices void -system_poke(Device *d, Uint8 b0, Uint8 b1) +system_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { putcolors(&ppu, &d->dat[0x8]); reqdraw = 1; @@ -191,19 +191,19 @@ system_poke(Device *d, Uint8 b0, Uint8 b1) } void -console_poke(Device *d, Uint8 b0, Uint8 b1) +console_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { switch(b0) { - case 0x8: printf("%c", b1); break; - case 0x9: printf("0x%02x\n", b1); break; - case 0xb: printf("0x%04x\n", (d->dat[0xa] << 8) + b1); break; - case 0xd: printf("%s\n", &d->mem[(d->dat[0xc] << 8) + b1]); break; + case 0x8: printf("%c", d->dat[0x8]); break; + case 0x9: printf("0x%02x", d->dat[0x9]); break; + case 0xb: printf("0x%04x", mempeek16(d->dat, 0xa)); break; + case 0xd: printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break; } fflush(stdout); } void -screen_poke(Device *d, Uint8 b0, Uint8 b1) +screen_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { if(b0 == 0xe) { Uint16 x = mempeek16(d->dat, 0x8); @@ -220,7 +220,7 @@ screen_poke(Device *d, Uint8 b0, Uint8 b1) } void -file_poke(Device *d, Uint8 b0, Uint8 b1) +file_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { Uint8 read = b0 == 0xd; if(read || b0 == 0xf) { @@ -240,7 +240,7 @@ file_poke(Device *d, Uint8 b0, Uint8 b1) } static void -audio_poke(Device *d, Uint8 b0, Uint8 b1) +audio_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { if(b0 == 0xa) { if(b1 >= apu.n_notes) apu.notes = SDL_realloc(apu.notes, (b1 + 1) * sizeof(Note)); @@ -261,7 +261,7 @@ audio_poke(Device *d, Uint8 b0, Uint8 b1) } void -datetime_poke(Device *d, Uint8 b0, Uint8 b1) +datetime_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { time_t seconds = time(NULL); struct tm *t = localtime(&seconds); @@ -280,7 +280,7 @@ datetime_poke(Device *d, Uint8 b0, Uint8 b1) } void -ppnil(Device *d, Uint8 b0, Uint8 b1) +nil_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw) { (void)d; (void)b0; @@ -350,22 +350,22 @@ main(int argc, char **argv) if(!init(&u)) return error("Init", "Failed"); - devsystem = portuxn(&u, 0x0, "system", system_poke); - portuxn(&u, 0x1, "console", console_poke); - devscreen = portuxn(&u, 0x2, "screen", screen_poke); - devapu = portuxn(&u, 0x3, "audio", audio_poke); - devctrl = portuxn(&u, 0x4, "controller", ppnil); - portuxn(&u, 0x5, "---", ppnil); - devmouse = portuxn(&u, 0x6, "mouse", ppnil); - devfile = portuxn(&u, 0x7, "file", file_poke); - portuxn(&u, 0x8, "---", ppnil); - portuxn(&u, 0x9, "midi", ppnil); - portuxn(&u, 0xa, "datetime", datetime_poke); - portuxn(&u, 0xb, "---", ppnil); - portuxn(&u, 0xc, "---", ppnil); - portuxn(&u, 0xd, "---", ppnil); - portuxn(&u, 0xe, "---", ppnil); - portuxn(&u, 0xf, "---", ppnil); + devsystem = portuxn(&u, 0x0, "system", system_talk); + portuxn(&u, 0x1, "console", console_talk); + devscreen = portuxn(&u, 0x2, "screen", screen_talk); + devapu = portuxn(&u, 0x3, "audio", audio_talk); + devctrl = portuxn(&u, 0x4, "controller", nil_talk); + portuxn(&u, 0x5, "---", nil_talk); + devmouse = portuxn(&u, 0x6, "mouse", nil_talk); + devfile = portuxn(&u, 0x7, "file", file_talk); + portuxn(&u, 0x8, "---", nil_talk); + portuxn(&u, 0x9, "midi", nil_talk); + portuxn(&u, 0xa, "datetime", datetime_talk); + portuxn(&u, 0xb, "---", nil_talk); + portuxn(&u, 0xc, "---", nil_talk); + portuxn(&u, 0xd, "---", nil_talk); + portuxn(&u, 0xe, "---", nil_talk); + portuxn(&u, 0xf, "---", nil_talk); apu.channel_ptr = &devapu->dat[0xa]; diff --git a/src/uxn.c b/src/uxn.c @@ -21,8 +21,8 @@ Uint8 pop8(Stack *s) { if (s->ptr == 0) { s->error = 1; return 0; } return s->d Uint8 peek8(Stack *s, Uint8 a) { if (s->ptr < a + 1) s->error = 1; return s->dat[s->ptr - a - 1]; } void mempoke8(Uint8 *m, Uint16 a, Uint8 b) { m[a] = b; } Uint8 mempeek8(Uint8 *m, Uint16 a) { return m[a]; } -void devpoke8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->poke(d, a & 0x0f, b); } -Uint8 devpeek8(Device *d, Uint8 a) { return d->dat[a & 0xf]; } +void devpoke8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, b, 1); } +Uint8 devpeek8(Device *d, Uint8 a) { return d->dat[a & 0xf]; d->talk(d, a & 0x0f, 0, 0); } void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } Uint16 pop16(Stack *s) { return pop8(s) + (pop8(s) << 8); } Uint16 peek16(Stack *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); } @@ -179,12 +179,12 @@ loaduxn(Uxn *u, char *filepath) } Device * -portuxn(Uxn *u, Uint8 id, char *name, void (*pofn)(Device *d, Uint8 b0, Uint8 b1)) +portuxn(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)) { Device *d = &u->dev[id]; d->addr = id * 0x10; d->mem = u->ram.dat; - d->poke = pofn; + d->talk = talkfn; printf("Device added #%02x: %s, at 0x%04x \n", id, name, d->addr); return d; } diff --git a/src/uxn.h b/src/uxn.h @@ -32,7 +32,7 @@ struct Uxn; typedef struct Device { Uint8 addr, dat[16], *mem; - void (*poke)(struct Device *d, Uint8, Uint8); + void (*talk)(struct Device *d, Uint8, Uint8, Uint8); } Device; typedef struct Uxn { @@ -47,4 +47,4 @@ int evaluxn(Uxn *u, Uint16 vec); void mempoke16(Uint8 *m, Uint16 a, Uint16 b); Uint16 mempeek16(Uint8 *m, Uint16 a); -Device *portuxn(Uxn *u, Uint8 id, char *name, void (*pofn)(Device *, Uint8, Uint8)); -\ No newline at end of file +Device *portuxn(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *, Uint8, Uint8, Uint8)); +\ No newline at end of file