A program can see a directory
Every file service took a name a program already knew - read it, save it, rename it, delete it, ask how big it is - and none of them could find out what names there are. dir could list only because it lives in the shell and calls the filesystem directly. So a file manager, a backup, and the package manager still to come were each unwritable for want of this. osDirFirst and osDirNext. DP0 says where to put the name and B how much room, the same bargain osArgument and osWhereAmI offer. Q ANSWERS THE KIND rather than a yes or no, so one value says both whether there is an entry and what it is: 0 a file, 1 a directory, 2 a save that stopped before it committed, 0xFF nothing more. A caller that only wants names tests for 0xFF and ignores the rest. The size is deliberately not in it. A walk hands back a name, and a program that wants the size asks osFileInfo about that name - the alternative being a record in memory whose shape both sides have to agree on, which services.asm went out of its way to avoid for file sizes. Walk.asm is the first program that can see a directory, and it asks osFileInfo about each entry BETWEEN two steps of the walk. That is the hazard rather than decoration: where a walk has got to and where the last file asked about lives are both held by the system, and two things sharing one position would show as a listing that stopped early or said a name twice. Then the same walk in /Apps, since one that only ever ran at the root would not have proved it walks where you are. A directory is not asked about at all. osFileInfo answers for one perfectly well and says nought blocks, which is true and reads as a size - and nought is a size a file can genuinely have. The lint baseline moves by one. The kind is decided by a chain of bit tests in the shape dir already uses five hundred lines away, and arms of a comparison chain each loading the same variable are the case this project's own rule says not to collapse: the repetition is what lets a new arm be dropped in anywhere. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
b83ba5bf7a
commit
2ad8edf9bc
@@ -6184,6 +6184,82 @@ fileForget:
|
||||
; Blocks, not bytes, and that is forced rather than chosen: a file on a sixteen megabyte
|
||||
; disk is up to twenty four bits long, which does not fit in a pointer. Blocks do, and the
|
||||
; bytes in the last one come back from osFileBlock when the reader gets there.
|
||||
; ---- Walking a directory on a program's behalf ----
|
||||
;
|
||||
; The one thing the filesystem could do that no program could ask for. dir has always been
|
||||
; able to list because it lives in here; a loaded program had no way to find out what names
|
||||
; exist at all, which left a file manager, a backup, and the package manager still to come
|
||||
; all unable to be written.
|
||||
;
|
||||
; Two entry points into one routine, because the difference between them is a single call.
|
||||
;
|
||||
; Q ANSWERS THE KIND, so one value says both whether there is an entry and what it is: 0 a
|
||||
; file, 1 a directory, 2 a save that stopped before it committed, 0xFF nothing more. A
|
||||
; caller that only wants names tests for 0xFF and ignores the rest.
|
||||
handleDirFirst:
|
||||
SETD.2 DiskReady
|
||||
LDA.2
|
||||
BRA dirWalkNoMore
|
||||
CALL sbfsFirst
|
||||
BRI dirWalkGot
|
||||
|
||||
handleDirNext:
|
||||
SETD.2 DiskReady
|
||||
LDA.2
|
||||
BRA dirWalkNoMore
|
||||
CALL sbfsNext
|
||||
|
||||
dirWalkGot:
|
||||
BNQ dirWalkNoMore
|
||||
|
||||
; The name first, because working out the kind wants the registers. B is still the room
|
||||
; the caller asked for: a CALL puts it back, and nothing above has taken it.
|
||||
PSHD.0
|
||||
POPD.1
|
||||
SETD.0 SbfsName
|
||||
CALL copyText
|
||||
|
||||
; ---- What kind of thing it is ----
|
||||
;
|
||||
; Asked in the same order dir asks it. An unfinished save is looked at FIRST because it is
|
||||
; the one thing here that is not really a file yet, and it is SHOWN rather than hidden:
|
||||
; the bytes are all there under that name, so a program that can see it is a program that
|
||||
; can rename it back.
|
||||
SETD.2 SbfsFoundFlags
|
||||
LDA.2
|
||||
INIB 0x04
|
||||
AND
|
||||
BNQ dirWalkUnfinished
|
||||
|
||||
SETD.2 SbfsFoundFlags
|
||||
LDA.2
|
||||
INIB 0x02
|
||||
AND
|
||||
BNQ dirWalkDirectory
|
||||
|
||||
RSTA
|
||||
BRI dirWalkAnswer
|
||||
|
||||
dirWalkDirectory:
|
||||
INIA 0d1
|
||||
BRI dirWalkAnswer
|
||||
|
||||
dirWalkUnfinished:
|
||||
INIA 0d2
|
||||
BRI dirWalkAnswer
|
||||
|
||||
dirWalkNoMore:
|
||||
; A machine with no disk has nothing to walk, and says the same thing as a walk that has
|
||||
; run out. There is no third answer worth telling apart: a caller that cannot list is a
|
||||
; caller that lists nothing either way.
|
||||
INIA 0xFF
|
||||
|
||||
dirWalkAnswer:
|
||||
RSTB
|
||||
CCF
|
||||
ADD ; A is the answer, so Q becomes it.
|
||||
SRET
|
||||
|
||||
handleFileInfo:
|
||||
SETD.2 DiskReady
|
||||
LDA.2
|
||||
@@ -8652,6 +8728,8 @@ CommandLine:
|
||||
osLastStatus handleLastStatus
|
||||
osTakeScreen handleTakeScreen
|
||||
osWhereAmI handleWhereAmI
|
||||
osDirFirst handleDirFirst
|
||||
osDirNext handleDirNext
|
||||
osBootState handleBootState
|
||||
osBootSettle handleBootSettle
|
||||
Device 0x20 diskDone
|
||||
|
||||
Reference in New Issue
Block a user