Working toward bidirectional talk between devices and program
This commit is contained in:
parent
e792fd01b7
commit
5c5b767eaf
2
build.sh
2
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' ];
|
||||
|
|
|
@ -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 ,¬-alpha JNZ
|
||||
#27 ADD
|
||||
¬-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
|
|
@ -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 ,¬-alpha JNZ
|
||||
#27 ADD
|
||||
¬-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!
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
Loading…
Reference in New Issue