commit 784df943d2654ded23c408182d8f060464da5c6d
parent fcd062ff22ee7b7ab9a763e47f0d44f991a62689
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 26 Nov 2022 21:16:44 -0500
emul/uxn: add file device to varvara
read only for now
Diffstat:
7 files changed, 96 insertions(+), 17 deletions(-)
diff --git a/fs/emul/uxn/varvara.fs b/fs/emul/uxn/varvara.fs
@@ -0,0 +1,51 @@
+?f<< /emul/uxn/vm.fs
+
+: slen0 ( a -- len )
+ 0 swap $100 [c]? ( idx )
+ dup 0< if abort" string too long" then ;
+
+: short@ ( a -- n ) c@+ 8 lshift swap c@ or ;
+: short! ( n a -- ) over 8 rshift swap c!+ c! ;
+: devshort@ ( idx dev -- n ) Device dat + short@ ;
+: devshort! ( n idx dev -- ) Device dat + short! ;
+
+: consoledei ( dev port -- c )
+ nip 2 = if stdin else 0 then ;
+: consoledeo ( dev port -- )
+ 8 = if Device dat 8 + c@ stdout else drop then ;
+
+create _fnbuf $101 allot
+create _files 8 allot0 \ 2 pointers to file cursors
+: _devfile' ( dev -- file' )
+ Device port 1 and CELLSZ * _files + ;
+
+: filedei 2drop 0 ;
+: filedeo ( dev port -- ) case ( dev ) \ V1=case
+ $9 of = \ name(addr)
+ dup _devfile' @ ?dup if File :close then
+ 8 over devshort@ uxn_ram + ( dev a )
+ dup slen0 dup _fnbuf c! _fnbuf 1+ swap move ( dev )
+ \ _fnbuf now holds stringified filename
+ _fnbuf curpath :find ( dev path )
+ 2dup bool swap 2 swap devshort! ( dev path ) ?dup if
+ Path :open swap _devfile' !
+ else ( dev ) drop then
+ endof
+ $d of = \ read(addr)
+ dup >r _devfile' @ ?dup if ( hdl ) >r \ V2=dev V3=hdl
+ $a V2 devshort@ ( readlen )
+ V3 File size V3 File pos - ( readlen maxlen )
+ min dup if ( len )
+ $c V2 devshort@ uxn_ram + over V3 ( n a n hdl )
+ File :read then ( res ) rdrop
+ else ( ) 0 then ( res )
+ $2 r> devshort!
+ endof
+ drop
+ endcase ;
+
+: varvara_init
+ uxn_init
+ $1 ['] consoledei ['] consoledeo uxn_set_dev
+ $a ['] filedei ['] filedeo uxn_set_dev
+ $b ['] filedei ['] filedeo uxn_set_dev ;
diff --git a/fs/emul/uxn/vm.c b/fs/emul/uxn/vm.c
@@ -13,6 +13,7 @@ struct Stack {
};
struct Device {
+ unsigned char port;
unsigned char dat[$10];
unsigned char (*dei)(Device*, unsigned char);
void (*deo)(Device*, unsigned char);
@@ -204,15 +205,6 @@ void uxn_exec() {
}
}
-/* Console */
-unsigned char console_dei(Device *d, unsigned char port) {
- if (port == 2) return stdin(); else return 0;
-}
-
-void console_deo(Device *d, unsigned char port) {
- if (port == 8) stdout(d->dat[port]);
-}
-
void uxn_init() {
int i;
pc = $100;
@@ -221,12 +213,18 @@ void uxn_init() {
src = &wst;
dst = &rst;
for (i=0; i<$10; i++) {
+ dev[i].port = i;
dev[i].dei = nulldei;
dev[i].deo = nulldeo;
memset(dev[i].dat, 0, $10);
}
- dev[1].dei = console_dei;
- dev[1].deo = console_deo;
}
unsigned int* uxn_ram() { return ram; }
+void uxn_set_dev(
+ int port,
+ unsigned char (*dei)(Device*, unsigned char),
+ void (*deo)(Device*, unsigned char)) {
+ dev[port].dei = dei;
+ dev[port].deo = deo;
+}
diff --git a/fs/emul/uxn/vm.fs b/fs/emul/uxn/vm.fs
@@ -1,3 +1,6 @@
\ uxn VM
?f<< /comp/c/lib.fs
cc<< /emul/uxn/vm.c
+
+S" Device" findTypedef CType :export
+
diff --git a/fs/tests/emul/uxn/file.bin b/fs/tests/emul/uxn/file.bin
Binary files differ.
diff --git a/fs/tests/emul/uxn/file.tal b/fs/tests/emul/uxn/file.tal
@@ -0,0 +1,21 @@
+( Read "hello.txt" in memory and spit to console )
+
+|10 @Console &vector $2 &read $1 &pad $5 &write $1 &err $1
+|a0 @File1 &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
+|b0 @File2 &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
+
+|0000 @dst
+|0100
+ ;fname .File1/name DEO2
+ #0100 .File1/length DEO2
+ ;dst .File1/read DEO2
+
+ ;dst @while
+ ( send ) LDAk .Console/write DEO
+ ( loop ) INC2 LDAk ,while JCN
+ POP2
+
+BRK
+
+@fname "/tests/emul/uxn/hello.txt 00
+
diff --git a/fs/tests/emul/uxn/hello.txt b/fs/tests/emul/uxn/hello.txt
@@ -0,0 +1 @@
+Hello from File!
diff --git a/fs/tests/emul/uxn/vm.fs b/fs/tests/emul/uxn/vm.fs
@@ -1,17 +1,17 @@
?f<< /tests/harness.fs
-?f<< /emul/uxn/vm.fs
+?f<< /emul/uxn/varvara.fs
testbegin
\ Testing uxn VM
\ Compiled from dummy.tal with uxn's official assembler
: _load ( path -- )
uxn_ram $100 + swap curpath :find# Path :open tuck File :readall File :close ;
S" /tests/emul/uxn/hello.bin" _load
-uxn_init
+varvara_init
capture uxn_exec
S" Hello World!" #s=
S" /tests/emul/uxn/fib.bin" _load
-uxn_init
+varvara_init
create expected 47 nc,
46 $00 $01 $00 $02 $00 $03 $00 $05 $00 $08 $00 $0d $00 $15 $00 $22 $00 $37
$00 $59 $00 $90 $00 $e9 $01 $79 $02 $62 $03 $db $06 $3d $0a $18 $10 $55
@@ -19,14 +19,19 @@ create expected 47 nc,
capture uxn_exec expected 47 []= #
S" /tests/emul/uxn/hexfmt.bin" _load
-uxn_init
+varvara_init
capture uxn_exec S" 1234abcd" #s=
S" /tests/emul/uxn/tests.bin" _load
-uxn_init
+varvara_init
capture uxn_exec S" X" #s=
S" /tests/emul/uxn/deideo.bin" _load
-uxn_init
+varvara_init
capture uxn_exec Z S" Z" #s=
+
+S" /tests/emul/uxn/file.bin" _load
+varvara_init
+capture uxn_exec
+S" Hello from File!\n" #s=
testend