diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 1949520..ebb2e4f 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -820,10 +820,26 @@ than one disk exists. That is the whole reason this was affordable. The version is not among them. It is checked at mount and thrown away, because a version one disk's zero parent already reads as "in the root", which is where all of its files are. -**Paths do not name a drive yet.** `drive 1` then a path is how you reach the other disk, so -copying between two of them is not possible in one command. A prefix like `1:/notes` is the -obvious next thing and it touches the path walker, which is why it is not in the same change -as the record. +**A path may name a drive**, as a digit and a colon on the front: `1:/notes`, or `1:` on its +own for wherever that drive already was. It is handled where every path in the system arrives, +so it works for anything that takes one rather than for whichever commands somebody remembered. + +**Naming a drive goes there and stays there.** Switching for the length of one command and +switching back reads better in a listing and cannot work: what a path resolves to is a start +block and a length, and those mean nothing without the drive they were read from. A `load` +that resolved on drive 1 and then read its blocks on drive 0 would read the right blocks of +the wrong disk. + +**A name that begins with a digit is still a name**, because the colon is the whole of what +tells the two apart. `2things` is a directory; `2:` is a drive. + +A drive the machine cannot read makes the whole path unfindable, and says so as `no such +file` - which it is, since there is nowhere for the rest of it to be. + +**Copying between two disks is still not one command.** Each path resolves on its own drive +and the drive stays where the last path left it, so a copy would read from one and write to +the other with only one of them selected. That wants the copy itself to change drives between +blocks, which is a change to `Copy` rather than to paths. ### Bank Numbers Are One Namespace: diff --git a/Programs/CosmOS/Source/sbfs.asm b/Programs/CosmOS/Source/sbfs.asm index a0d50e6..0f9b5e6 100644 --- a/Programs/CosmOS/Source/sbfs.asm +++ b/Programs/CosmOS/Source/sbfs.asm @@ -414,12 +414,118 @@ sbfsFindRoot: ADD RET +; ---- Is there a drive on the front of this path, and can we go there? ---- +; +; A digit and a colon. Q is zero if the path is usable, whether or not one was there; Q is one +; if a drive was named and it is not one this machine can read, which makes the whole path +; unfindable - because it is. +; +; NAMING A DRIVE GOES THERE AND STAYS THERE. The alternative was to switch for the operation +; and switch back, which reads better in a listing and cannot work: what a path resolves to is +; a start block and a length, and those mean nothing without the drive they were read from. A +; load that resolved on drive 1 and then read on drive 0 would read the right blocks of the +; wrong disk. +sbfsPathDrive: + SETD.1 SbfsPathAt + LDD.0.1 + LDA.0 + INIB 0d48 ; '0' + CCF + SUB + BRC sbfsPathNoDrive ; Borrowed, so it is below '0' and not a digit. + MVQA + INIB 0d10 + CCF + SUB + BNC sbfsPathNoDrive ; Ten or more, so not a digit either. + + ; The character after it has to be a colon, or this is a name that begins with a digit. + ; DP1 is still SbfsPathAt, from the top of this routine. + LDD.0.1 + INCD.0 + LDA.0 + INIB 0d58 ; ':' + CCF + SUB + BNQ sbfsPathNoDrive + + ; It is a drive. Is it one this machine has, with something readable in it? + LDD.0.1 + LDA.0 + INIB 0d48 + CCF + SUB + MVQA + SETD.1 SbfsPathWanted + STA.1 + CALL sbfsDriveBit + MVQA + SETD.1 SbfsMounted + LDB.1 + AND + BRQ sbfsPathBadDrive + + SETD.1 SbfsPathWanted + LDA.1 + CALL sbfsUse + + ; Past the digit and the colon. What follows is an ordinary path, and a bare "1:" is an + ; empty one - which walks to where that drive already was. + SETD.1 SbfsPathAt + LDD.0.1 + INCD.0 + INCD.0 + STD.0.1 + +sbfsPathNoDrive: + RSTA + RSTB + CCF + ADD + RET + +sbfsPathBadDrive: + RSTA + INIB 0d1 + CCF + ADD + RET + ; The walk itself. Q is zero if the whole path was walked, and SbfsAt says where it ended - ; which may be the root, and that is an answer rather than a failure. sbfsWalk: SETD.1 SbfsPathAt STD.0.1 + ; ---- A drive in front of the path ---- + ; + ; Done here because this is where every path in the system arrives - eight callers between + ; the shell, the config reader and this file - so naming a drive works everywhere at once + ; rather than in whichever commands somebody remembered. + CALL sbfsPathDrive + BNQ sbfsWalkNoDrive + + ; ---- And DP0 has to be told ---- + ; + ; sbfsPathDrive moved SbfsPathAt past the digit and the colon, but RET put DP0 back the way + ; it found it - so the test below for a leading separator was reading the DIGIT and calling + ; every prefixed path relative. It only showed when the drive being named was standing + ; somewhere other than its root, because a relative walk from the root is an absolute one. + SETD.1 SbfsPathAt + LDD.0.1 + BRI sbfsWalkPath + +; A drive that this machine cannot read makes the path unfindable, because it is: there is +; nowhere for the rest of it to be. +sbfsWalkNoDrive: + RSTA + INIB 0d1 + CCF + ADD + RET + +sbfsWalkPath: + ; Where it starts. A path beginning with a separator is measured from the root, which is ; zero because a parent is an entry index PLUS ONE and the root is not an entry. ; Anything else is measured from wherever the machine already is. @@ -3381,6 +3487,8 @@ SbfsDriveCount: 0x00 SbfsDriveAt: 0x00 +SbfsPathWanted: + 0x00 SbfsFileStart: 0x00 0x00 diff --git a/SplitBit Test Manual.md b/SplitBit Test Manual.md index e112c50..250b27e 100644 --- a/SplitBit Test Manual.md +++ b/SplitBit Test Manual.md @@ -79,7 +79,7 @@ from `make`, not from here. ### 1. Recorded output `Tests/run.sh` assembles each program named in `Tests/manifest`, runs it, and compares -everything it printed against a file in `Tests/expected`. 180 tests, of which 118 run, 35 +everything it printed against a file in `Tests/expected`. 181 tests, of which 119 run, 35 only assemble, 16 are expected to fail to assemble, and 11 boot from ROM with no image given at all. diff --git a/Tests/expected/cosmosDrivePath.out b/Tests/expected/cosmosDrivePath.out new file mode 100644 index 0000000..dc1862f --- /dev/null +++ b/Tests/expected/cosmosDrivePath.out @@ -0,0 +1,9 @@ +CosmOS +> /notes> 1 +/notes> > 0 +> /2things> 1 +/2things> > /2things> 1 +/2things> no such file +/2things> halted +Execution halted. +[exit 0] diff --git a/Tests/expected/cosmosDrives.out b/Tests/expected/cosmosDrives.out index bd0ee99..0f02d1a 100644 --- a/Tests/expected/cosmosDrives.out +++ b/Tests/expected/cosmosDrives.out @@ -20,7 +20,8 @@ loop.script 35 17 files > > other.txt 28 notes