Working toward bidirectional talk between devices and program

This commit is contained in:
neauoire 2021-04-24 09:43:30 -07:00
parent e792fd01b7
commit 5c5b767eaf
7 changed files with 132 additions and 94 deletions

View File

@ -32,7 +32,7 @@ else
fi fi
echo "Assembling.." echo "Assembling.."
./bin/assembler projects/demos/bifurcan.usm bin/boot.rom ./bin/assembler projects/examples/devices/console.lib.usm bin/boot.rom
echo "Running.." echo "Running.."
if [ "${2}" = '--cli' ]; if [ "${2}" = '--cli' ];

View File

@ -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

View File

@ -6,20 +6,11 @@
|10 @Console [ &pad $8 &char $1 ] |10 @Console [ &pad $8 &char $1 ]
( variables )
|0000
@number [ &started $1 ]
( init ) ( init )
|0100 ( -> ) |0100 ( -> )
;hello-word ;print JSR2 ;hello-word ;print JSR2
#ffff ;print-hexadecimal JSR2
;is-word ;print JSR2
#ffff ;print-decimal JSR2
BRK BRK
@ -28,48 +19,9 @@ BRK
&loop &loop
( send ) DUP2 GET .Console/char DEO ( send ) DUP2 GET .Console/char DEO
( incr ) #0001 ADD2 ( incr ) #0001 ADD2
( loop ) DUP2 GET ,&loop JNZ ( loop ) DUP2 GET #00 NEQ ,&loop JNZ
POP2 POP2
RTN RTN
@print-hexadecimal ( short -- ) @hello-word "hello 20 "World!
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

View File

@ -38,7 +38,7 @@ printstack(Stack *s)
#pragma mark - Devices #pragma mark - Devices
void void
console_poke(Device *d, Uint8 b0, Uint8 b1) console_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
switch(b0) { switch(b0) {
case 0x08: printf("%c", b1); break; case 0x08: printf("%c", b1); break;
@ -51,7 +51,7 @@ console_poke(Device *d, Uint8 b0, Uint8 b1)
} }
void void
file_poke(Device *d, Uint8 b0, Uint8 b1) file_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
Uint8 read = b0 == 0xd; Uint8 read = b0 == 0xd;
if(read || b0 == 0xf) { if(read || b0 == 0xf) {
@ -71,7 +71,7 @@ file_poke(Device *d, Uint8 b0, Uint8 b1)
} }
void void
ppnil(Device *d, Uint8 b0, Uint8 b1) nil_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
(void)d; (void)d;
(void)b0; (void)b0;
@ -106,13 +106,13 @@ main(int argc, char **argv)
if(!loaduxn(&u, argv[1])) if(!loaduxn(&u, argv[1]))
return error("Load", "Failed"); return error("Load", "Failed");
portuxn(&u, 0x00, "console", console_poke); portuxn(&u, 0x00, "console", console_talk);
portuxn(&u, 0x01, "empty", ppnil); portuxn(&u, 0x01, "empty", nil_talk);
portuxn(&u, 0x02, "empty", ppnil); portuxn(&u, 0x02, "empty", nil_talk);
portuxn(&u, 0x03, "empty", ppnil); portuxn(&u, 0x03, "empty", nil_talk);
portuxn(&u, 0x04, "empty", ppnil); portuxn(&u, 0x04, "empty", nil_talk);
portuxn(&u, 0x05, "empty", ppnil); portuxn(&u, 0x05, "empty", nil_talk);
portuxn(&u, 0x06, "file", file_poke); portuxn(&u, 0x06, "file", file_talk);
start(&u); start(&u);
return 0; return 0;

View File

@ -182,7 +182,7 @@ doctrl(Uxn *u, SDL_Event *event, int z)
#pragma mark - Devices #pragma mark - Devices
void void
system_poke(Device *d, Uint8 b0, Uint8 b1) system_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
putcolors(&ppu, &d->dat[0x8]); putcolors(&ppu, &d->dat[0x8]);
reqdraw = 1; reqdraw = 1;
@ -191,19 +191,19 @@ system_poke(Device *d, Uint8 b0, Uint8 b1)
} }
void void
console_poke(Device *d, Uint8 b0, Uint8 b1) console_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
switch(b0) { switch(b0) {
case 0x8: printf("%c", b1); break; case 0x8: printf("%c", d->dat[0x8]); break;
case 0x9: printf("0x%02x\n", b1); break; case 0x9: printf("0x%02x", d->dat[0x9]); break;
case 0xb: printf("0x%04x\n", (d->dat[0xa] << 8) + b1); break; case 0xb: printf("0x%04x", mempeek16(d->dat, 0xa)); break;
case 0xd: printf("%s\n", &d->mem[(d->dat[0xc] << 8) + b1]); break; case 0xd: printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break;
} }
fflush(stdout); fflush(stdout);
} }
void void
screen_poke(Device *d, Uint8 b0, Uint8 b1) screen_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
if(b0 == 0xe) { if(b0 == 0xe) {
Uint16 x = mempeek16(d->dat, 0x8); Uint16 x = mempeek16(d->dat, 0x8);
@ -220,7 +220,7 @@ screen_poke(Device *d, Uint8 b0, Uint8 b1)
} }
void void
file_poke(Device *d, Uint8 b0, Uint8 b1) file_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
Uint8 read = b0 == 0xd; Uint8 read = b0 == 0xd;
if(read || b0 == 0xf) { if(read || b0 == 0xf) {
@ -240,7 +240,7 @@ file_poke(Device *d, Uint8 b0, Uint8 b1)
} }
static void static void
audio_poke(Device *d, Uint8 b0, Uint8 b1) audio_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
if(b0 == 0xa) { if(b0 == 0xa) {
if(b1 >= apu.n_notes) apu.notes = SDL_realloc(apu.notes, (b1 + 1) * sizeof(Note)); 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 void
datetime_poke(Device *d, Uint8 b0, Uint8 b1) datetime_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
time_t seconds = time(NULL); time_t seconds = time(NULL);
struct tm *t = localtime(&seconds); struct tm *t = localtime(&seconds);
@ -280,7 +280,7 @@ datetime_poke(Device *d, Uint8 b0, Uint8 b1)
} }
void void
ppnil(Device *d, Uint8 b0, Uint8 b1) nil_talk(Device *d, Uint8 b0, Uint8 b1, Uint8 rw)
{ {
(void)d; (void)d;
(void)b0; (void)b0;
@ -350,22 +350,22 @@ main(int argc, char **argv)
if(!init(&u)) if(!init(&u))
return error("Init", "Failed"); return error("Init", "Failed");
devsystem = portuxn(&u, 0x0, "system", system_poke); devsystem = portuxn(&u, 0x0, "system", system_talk);
portuxn(&u, 0x1, "console", console_poke); portuxn(&u, 0x1, "console", console_talk);
devscreen = portuxn(&u, 0x2, "screen", screen_poke); devscreen = portuxn(&u, 0x2, "screen", screen_talk);
devapu = portuxn(&u, 0x3, "audio", audio_poke); devapu = portuxn(&u, 0x3, "audio", audio_talk);
devctrl = portuxn(&u, 0x4, "controller", ppnil); devctrl = portuxn(&u, 0x4, "controller", nil_talk);
portuxn(&u, 0x5, "---", ppnil); portuxn(&u, 0x5, "---", nil_talk);
devmouse = portuxn(&u, 0x6, "mouse", ppnil); devmouse = portuxn(&u, 0x6, "mouse", nil_talk);
devfile = portuxn(&u, 0x7, "file", file_poke); devfile = portuxn(&u, 0x7, "file", file_talk);
portuxn(&u, 0x8, "---", ppnil); portuxn(&u, 0x8, "---", nil_talk);
portuxn(&u, 0x9, "midi", ppnil); portuxn(&u, 0x9, "midi", nil_talk);
portuxn(&u, 0xa, "datetime", datetime_poke); portuxn(&u, 0xa, "datetime", datetime_talk);
portuxn(&u, 0xb, "---", ppnil); portuxn(&u, 0xb, "---", nil_talk);
portuxn(&u, 0xc, "---", ppnil); portuxn(&u, 0xc, "---", nil_talk);
portuxn(&u, 0xd, "---", ppnil); portuxn(&u, 0xd, "---", nil_talk);
portuxn(&u, 0xe, "---", ppnil); portuxn(&u, 0xe, "---", nil_talk);
portuxn(&u, 0xf, "---", ppnil); portuxn(&u, 0xf, "---", nil_talk);
apu.channel_ptr = &devapu->dat[0xa]; apu.channel_ptr = &devapu->dat[0xa];

View File

@ -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]; } 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; } void mempoke8(Uint8 *m, Uint16 a, Uint8 b) { m[a] = b; }
Uint8 mempeek8(Uint8 *m, Uint16 a) { return m[a]; } 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); } 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]; } 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); } void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
Uint16 pop16(Stack *s) { return pop8(s) + (pop8(s) << 8); } 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); } 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 * 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]; Device *d = &u->dev[id];
d->addr = id * 0x10; d->addr = id * 0x10;
d->mem = u->ram.dat; d->mem = u->ram.dat;
d->poke = pofn; d->talk = talkfn;
printf("Device added #%02x: %s, at 0x%04x \n", id, name, d->addr); printf("Device added #%02x: %s, at 0x%04x \n", id, name, d->addr);
return d; return d;
} }

View File

@ -32,7 +32,7 @@ struct Uxn;
typedef struct Device { typedef struct Device {
Uint8 addr, dat[16], *mem; Uint8 addr, dat[16], *mem;
void (*poke)(struct Device *d, Uint8, Uint8); void (*talk)(struct Device *d, Uint8, Uint8, Uint8);
} Device; } Device;
typedef struct Uxn { typedef struct Uxn {
@ -47,4 +47,4 @@ int evaluxn(Uxn *u, Uint16 vec);
void mempoke16(Uint8 *m, Uint16 a, Uint16 b); void mempoke16(Uint8 *m, Uint16 a, Uint16 b);
Uint16 mempeek16(Uint8 *m, Uint16 a); Uint16 mempeek16(Uint8 *m, Uint16 a);
Device *portuxn(Uxn *u, Uint8 id, char *name, void (*pofn)(Device *, Uint8, Uint8)); Device *portuxn(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *, Uint8, Uint8, Uint8));