News for hackers. Stuff that matters.
Re:Konilo: A personal computing system in Forth by kragen on Saturday March 02, 2024 @06:11PM (#39576667)
chuck moore is running colorforth as a process under windows these days because it's gotten too hard to write the damn device drivers

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

    open   ( d u -- flag )  create file named d, size u blocks, returning 0 on success
    extent ( d -- u )       return the number of blocks in file d, or 0 if nonexistent
    delete ( d -- )         delete file named d if it exists
    filename ( c-addr u -- d )  convert ascii filename to a double-precision number
    .filename ( d -- )      print the filename d
    file   ( u -- d )       return the name of the uth file in the directory or 0 if none
    maxfiles ( -- 50 )      return the maximum possible file index to pass to file
    index  ( d u1 -- u2 )   return the block number for block u of file d
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:

    2variable oldfile  
    : old ( d -- ) 2dup oldfile 2!  extent 0 ?do  oldfile 2@ i index load  loop ;
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

    : old ( d -- ) 2dup  extent 0 ?do  2dup i index load  loop  2drop ;
you might also want to list the directory of files:

    : stat ( d -- ) 2dup or if 2dup .filename ." " extent . cr else 2drop then ;
    : ls-l ( -- ) maxfiles 0 do i file stat loop ;
Re:Konilo: A personal computing system in Forth by kragen on Sunday March 03, 2024 @12:22AM (#39578641)
on further consideration, i think that interface requires about one and a half blocks of code to implement. this interface would be more useful and have a simpler implementation

    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 d
Re:Konilo: A personal computing system in Forth by abecedarius on Sunday March 03, 2024 @01:06PM (#39582816)
In the Forth golden age there was a convention of grouping blocks in triads -- you could print one per page. E.g. when I proposed to rewrite the "full-screen-style" editor at FORTH, Inc., they were like "if you think you can get it down from 4 blocks to 3, then go ahead" so it wouldn't be wasting 2/3 of a triad. (You might remember this, it was the more-conventional editor they didn't use, contributed by a customer.)

So 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.

Re:Konilo: A personal computing system in Forth by kragen on Sunday March 03, 2024 @04:12PM (#39584592)
that makes sense; i had seen forth printed that way but had forgotten about it. i think the code was printed side by side with the shadow screens (the comments), requiring 132 columns (4 of padding i suppose)

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!

Re:Konilo: A personal computing system in Forth by abecedarius on Sunday March 03, 2024 @04:41PM (#39584775)
Hope you're well!

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...)

Re:Konilo: A personal computing system in Forth by kragen on Sunday March 03, 2024 @07:48PM (#39585950)
oh, yeah, that makes sense. you could probably fit most of the standard cp/m or unix filesystem utilities into the remainder; cp, rm, mv, cat, head, and so on. maybe nsweep

i'm, eh, not dead