commit fd9089a7b775fb90f9362e961cd2feb28b9878ce
parent 41843e3beb031e7da86f400a2d961f18eee2c1cf
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 8 Aug 2022 14:55:52 -0400
wip
Diffstat:
9 files changed, 100 insertions(+), 27 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
TARGETS = dusk
-BOOTFS_SRC = fs/xcomp/bootlo.fs fs/xcomp/boothi.fs
+BOOTFS_SRC = fs/xcomp/bootlo.fs posix/glue.fs fs/xcomp/boothi.fs
ALLSRCS = $(shell find fs)
all: $(TARGETS)
diff --git a/fs/doc/file.txt b/fs/doc/file.txt
@@ -1,41 +1,84 @@
-# File API
+# File subsystem
-The File API is a specialization of the I/O API (doc/io) for accessing files in
-a filesystem. It also works with "handles", which we call File handle. Of
-course, it starts with the I/O prelude, but then adds its own prelude:
+The file subsystem allows the system to interact with filesystems.
-(I/O prelude)
-fseek
-fclose
+Files and directories all live within filesystems. More than one filesystem can
+be active at once and each of these filesystems is designated by a letter. For
+example, the boot filesystem is always "A". There's a maximum of 26 active
+filesystems.
-These words have the following meaning:
+Filesystems contain files and directories. A file is a blob of data that exists
+within a directory. A directory is a container for files and other directories.
+Each filesystem has one root directory.
-fseek ( pos hdl -- )
- Place the handle at offset "pos" (in bytes).
+Files and directories are referred to with strings of characters that we call
+"paths". Those paths begin with a filesystem identifier, followed by name of
+files and directory. A directory name can be followed by a "/" character to
+indicate that we want to refer to one of its child.
-fclose ( hdl -- )
- Close handle and free its resources. When a handle is closed, operations on
- it become noops (read return 0, writes/seeks do nothing)
+There is also the concept of an "active" directory. When paths don't start with
+a drive letter, the path is relative to this active directory. A that starting
+with "/" refer to the root directory of the active directory's filesystem. The
+initial active directory is the boot filesystem's root directory (A:).
+
+Examples:
+
+A: root of filesystem A
+A:foo.txt file "foo.txt" inside A's root directory
+B:foo/bar.fs file "bar.fs" inside "foo" directory inside B's root
+bar.fs file "bar.fs" in active directory
+/foo.fs file "foo.fs" in active filesystem's root directory
-## Global aliases
+## Filesystem API
-On top of that, the File API also define global aliases in which the current
-active filesystem will plug itself:
+When the code refers to a filesystem, it does so through a definite structure:
-fchild ( dirid name -- id )
+4b Drive pointer (see doc/drive)
+4b first sector of FS
+4b fchild
+4b fopen
+4b fnewfile
+
+The word pointers have the specifications below. For each of these words, "fs"
+refers to a filesystem, a pointer to the structure decribed above.
+
+fchild ( dirid name fs -- id )
Enumerate the contents of directory "dirid" and look for name "name". If
found, returns the ID of the child (either a file or directory), otherwise,
return 0. See below for the concept of "ID".
-fopen ( id -- hdl )
+fopen ( id fs -- hdl )
Open file at path and return a handle through which other file-related word
identify the target file. Once a file isn't used anymore, it should be
closed with fclose. Aborts on error.
-fnewfile ( dirid name -- id )
+fnewfile ( dirid name fs -- id )
Create a new empty file named "name" in "dirid" and return the ID of the new
file. Aborts on error.
+For each of those words above, the file subsystem implements a global word with
+the same signatures, except for the "fs" argument which is absent. Those words
+operate on the active filesystem.
+
+## File API
+
+The File API is a specialization of the I/O API (doc/io) for accessing files in
+a filesystem. It also works with "handles", which we call File handle. Of
+course, it starts with the I/O prelude, but then adds its own prelude:
+
+(I/O prelude)
+fseek
+fclose
+
+These words have the following meaning:
+
+fseek ( pos hdl -- )
+ Place the handle at offset "pos" (in bytes).
+
+fclose ( hdl -- )
+ Close handle and free its resources. When a handle is closed, operations on
+ it become noops (read return 0, writes/seeks do nothing)
+
## Common API
On top of those words, the File subsystem implements those words:
diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs
@@ -222,3 +222,11 @@ create fcursors( FCursorSize FCURSORCNT * allot0
dup fatbuf( - bufsec BPB_BytsPerSec * + ( dirent doffset ) r@ 32 + !
-1 r@ FCUR_clusteridx! 0 r@ FCUR_pos!
DIR_FileSize r@ FCUR_size! ( ) r> ;
+
+\ TODO: support more than one at once
+create FATFS
+ fatdrv ,
+ 0 ,
+ ' fatchild ,
+ ' fatopenlo ,
+ ' abort ,
diff --git a/fs/sys/file.fs b/fs/sys/file.fs
@@ -1,6 +1,10 @@
\ File subsystem, see doc/file
0 S" lib" fchild S" io.fs" fchild fload
+26 const MAXFSCNT
+create filesystems MAXFSCNT CELLSZ * allot0
+activefs filesystems ! \ record our boot FS in the list
+
0 value curdir
create _buf $100 allot
@@ -29,7 +33,7 @@ create _buf $100 allot
dup while 2dup 4 + @ = if 2drop 1 exit then @ repeat 2drop 0 ;
: ?f<< word findpath# dup floaded? if drop else fload then ;
-: fseek ( pos hdl -- ) dup 12 + @ execute ;
+12 smethod fseek ( pos hdl -- )
?f<< /lib/scratch.fs
diff --git a/fs/xcomp/boothi.fs b/fs/xcomp/boothi.fs
@@ -1,6 +1,6 @@
0 value curhdl \ handle of the file currently being read
0 value fecho
-: fclose ( hdl -- ) dup 16 + @ execute ;
+16 smethod fclose ( hdl -- )
: \s curhdl ?dup if fclose then ;
: f< ( -- c )
1 curhdl dup @ ( 'freadbuf ) execute if c@ else -1 ( EOF ) then
diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs
@@ -81,6 +81,10 @@
: &+@ ( n -- ) doer , does> @ + @ ;
: &+! ( n -- ) doer , does> @ + ! ;
: field ( off -- ) doer , does> ( a 'w ) @ + to? ?dup if execute else @ then ;
+\ A structure method. Called with a strucure as the top argument and will
+\ execute the word pointer at a specific offset with that structure pointer
+\ till on the top of PS.
+: smethod ( off -- ) doer , does> @ over + @ execute ;
\ while..repeat
: while [compile] if swap ; immediate
@@ -162,8 +166,16 @@ alias noop [then]
\ Drive API
\ Anticipating lib/drive
: drvsecsz ( drv -- ) @ ;
-: drv@ ( sec dst drv -- ) dup 4 + @ execute ;
-: drv! ( sec src drv -- ) dup 8 + @ execute ;
+4 smethod drv@ ( sec dst drv -- )
+8 smethod drv! ( sec dst drv -- )
+
+\ File API
+\ Anticipating lib/file
+\ TODO: pass FS to methods, like the docs say
+0 value activefs
+: fchild ( dirid name -- id ) activefs 8 + @ execute ;
+: fopen ( id -- hdl ) activefs 12 + @ execute ;
+: fnewfile ( dirid name fs -- hdl ) activefs 16 + @ execute ;
\ Autoloading
0 value floaded \ address of the current "loaded file" structure
diff --git a/fs/xcomp/pc/glue2.fs b/fs/xcomp/pc/glue2.fs
@@ -1,5 +1,4 @@
\ Glue code that goes between the filesystem part and boothi
-alias fatopenlo fopen
-alias fatchild fchild
+FATFS to activefs
0 S" drv" fchild S" pc" fchild S" int13h.fs" fchild floaded,
0 S" fs" fchild S" fatlo.fs" fchild floaded,
diff --git a/posix/glue.fs b/posix/glue.fs
@@ -0,0 +1,7 @@
+create POSIXFS
+ 0 , 0 ,
+ ' _fchild ,
+ ' _fopen ,
+ ' abort ,
+
+POSIXFS to activefs
diff --git a/posix/vm.c b/posix/vm.c
@@ -847,7 +847,7 @@ static char *opnames[OPCNT] = {
"or", "xor", "bool", "not", "<", "<<c", ">>c", "lshift",
"rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)",
"stack?", "maybeword", "word", "parse", "[]=", "find", "'", "to",
- ",\"", NULL, "[", "runword", "exit", "fchild", "fopen", "_freadbuf",
+ ",\"", NULL, "[", "runword", "exit", "_fchild", "_fopen", "_freadbuf",
"_fclose"};
static void oprun1() { // run next op