open ( d -- flag ) create file d, size 0 blocks, returning 0 if ok
extent ( d -- u ) return the number of blocks in file d, or -1 if none
delete ( d -- ) delete file named d if it exists
extend ( d -- flag ) append a block to file d, returning 0 if ok
filename ( c-addr u -- d ) convert ASCII filename to a double number
.filename ( d -- ) print the filename d
file ( u -- d ) return name of the uth file in the directory or 0
maxfiles ( -- 50 ) return the maximum valid file index
index ( d u1 -- u2 ) return the block number for block u1 of file dSo maybe make this filesystem work on triad units: an index fits in a byte, more space for longer filenames. Not sure what to do with the extra block in the filesystem triad.
i think that, if you want to put the metadata into multiple blocks, you need to have some control over the order of buffer saving. one way to do this would be to have two copies of the metadata that you alternate between, which would be desirable anyway in case of power loss during metadata writes. maybe once every 30 seconds, say. after your last modification to replica tweedledee and before your first modification to replica tweedledum, you would call save-buffers, ensuring that briefly tweedledee is also consistent on disk (tweedledum already having been consistent), even if buffer evictions later put tweedledee into a torn state
then the question is how, upon startup, to know whether to use tweedledee or tweedledum? maybe an update serial number at the beginning and end of the block that has to match?
using a cluster size larger than the forth block size seems like it might complicate the calling interface somewhat
glad to hear from you!
I wasn't proposing keeping file metadata in multiple blocks -- just, might as well consider if any functionality might be worth adding in the remaining block of the filesystem triad, if it's gonna be a triad (source code, metadata, empty). (This makes the larger minimum size of these triads a bit of an attractive nuisance from a "Forth Zen" pov...)
before that, though, he was using ram as his 'block file' (i think having reduced from 1024-byte blocks to 256-byte blocks) and only using the disk to make changes persistent. also he still recompiles programs from source every time he switches context from one program to another; the program he's switching from gets discarded, and the one he's switching to gets recompiled
i remember having to defragment my floppy under the p-system in order to make a big enough piece of free space for the file i wanted to copy onto it. i have the vague memory that cp/m supported non-contiguous files; hdos certainly did
while i don't intend to question your assertion that forth users at the time maintained their tables of contents blocks manually, it seems like you could implement a fat-like directory-maintenance system in less than one screen of code. like cp/m, you could maintain file sizes in blocks rather than in bytes (but 1024-byte blocks, of course); like some dec tape formats (?), you could use four bytes for the filename with a weird encoding (forth's native base 36 instead of dec radix-50). suppose you have a double-sided disk with 40 tracks of 9 512-byte sectors per side; that's 720 in total, or 360 forth blocks. you can't fit a block number into one byte, so the simplest thing is to use two. so if you want to make fat-style linked lists, you need 720 bytes of block numbers, for the following block number. that leaves you 304 bytes for filenames and starting block numbers; if filenames are 4 bytes and starting block numbers are 2 bytes you have room for 50 files, which is probably okay
so i feel like maintaining a table of contents automatically would have cost about 1% of the disk space (1 block for the code and 1 block for the directory and allocation table), so it would have been a good idea
the interface might look something like
and from there you can use the usual forth block words to read or modify the contents of the files, such as block, update, load, and save-buffers. things like refill and thru, which presuppose semantics for the sequencing of block numbers, might benefit from file-aware versions. for example, you might supplement thru with a word old which loads each block of a file, whatever sequence they're in on disk: or i guess that, if you can trust the code being loaded to not leave crap on the stack between blocks, it might be justifiable to just write you might also want to list the directory of files: