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
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' ];

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 ]
( 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!

View File

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

View File

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

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]; }
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;
}

View File

@ -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));
Device *portuxn(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *, Uint8, Uint8, Uint8));