Say what went wrong, and give the file tools room for a path

The makefile on the disk was fine. "Makefile" is not "makefile", and SBFS names are case
sensitive - but neither tool said so, and both failed in ways that pointed somewhere else.

MORE PRINTED A NUMBER THAT MEANT NOTHING. "cannot find the file, error 2" invents a
vocabulary the system does not have: the filesystem library documents its answer as zero or
not zero, never as a code, so 2 could not be looked up anywhere. It says "there is no file by
that name" now, which is the only way opening fails that a person can do anything about, and
is nearly always a name typed slightly wrong.

EDIT SAID "0 LINES", which is also what an empty file that IS on the disk says. A name typed
slightly wrong therefore looked exactly like the document you meant to open, right up until
you saved it somewhere new. It says "new file" instead.

Two bugs came out of writing that, and both are worth more than the feature.

The first is mine and the label lied to me: loadNothing is not where a load FAILS, it is
where every load FINISHES, reached at the end of splitLast on files that opened perfectly
well. A flag set there on the strength of the name was set on everything. It is called
loadDone now, and the failure has its own name.

The second is older and general: a program is loaded once and may be run many times, so
"load Edit.sbx" then "run" twice is two sessions over one copy of the Data Segment. Anything
a session changes has to be put back by the session. A zero written in the Data Segment is
the state a program starts in the first time and never again - and cosmosEdit runs Edit twice
from one load, which is why it caught it immediately.

AND THE FILE TOOLS COULD NOT ADDRESS THE TREE THEY NOW HAVE. Edit took 23 characters of name
and More and Type took 29, which were right when everything lived in the root. With the
sources mirrored onto the disk, "/Source/CosmOS/Assembler/classify.asm" is an ordinary thing
to type - thirty-seven characters, cut down to a name meaning something else, or nothing. All
of them take sixty-three now, which is what the shell reads of a command line, so nothing
longer can arrive. Wander with it, since a directory is a path too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-29 09:24:10 -04:00
co-authored by Claude Opus 5
parent 0852666e73
commit 7073b972e6
7 changed files with 80 additions and 25 deletions
+54 -5
View File
@@ -54,8 +54,15 @@
#Base 0x4000
start:
; ---- Room for a PATH, not a name ----
;
; Sixty-three, which was twenty-three. That was the right size when everything lived in
; the root and a name was a name. The disk now carries the whole source tree, so
; "/Source/CosmOS/Assembler/classify.asm" is an ordinary thing to type - thirty-seven
; characters, and it was being cut down to a name that meant something else, or nothing.
; The shell reads sixty-three characters of command line, so nothing longer can arrive.
SETD.0 FileName
INIB 0d23
INIB 0d63
SWI osArgument
SETD.0 FileName
LDA.0
@@ -78,6 +85,14 @@ start:
RSTA
SETD.0 TooLong
STA.0
; ---- Cleared here rather than in the Data Segment ----
;
; A program is loaded once and may be run many times: "load Edit.sbx" then "run" twice is
; two sessions over one copy of the data, so anything a session changes has to be put back
; by the session and not by the loader. A zero written in the Data Segment is the state
; this program starts in the FIRST time and never again.
SETD.0 IsNew
STA.0
CALL loadFile
SETD.0 TooLong
@@ -88,6 +103,17 @@ start:
SWI osPrintString
SETD.0 CommaText
SWI osPrintString
; A file that was not there is a new document, which this is the way to start - but say so,
; rather than saying nothing and letting it look like an empty one that already existed.
SETD.0 IsNew
LDA.0
BRA sayCount
SETD.0 NewText
SWI osPrintString
CALL newLine
BRI announced
sayCount:
CALL countLines
MVQA
CALL printByte
@@ -102,6 +128,7 @@ oneLine:
sayLines:
SWI osPrintString
CALL newLine
announced:
commandLoop:
SETD.0 PromptText
@@ -578,7 +605,7 @@ loadFile:
SETD.0 FileName
SETD.1 0x40 0x00
SWI osFileRead
BNQ loadNothing
BNQ loadNew
; How many bytes came back. The service says so in DP3, which is one of the two things a
; service is allowed to answer in, and a file that fits in memory has a length that fits
@@ -677,13 +704,29 @@ splitLast:
; A file that does not end in a newline still has a last line in it.
SETD.2 EntryLength
LDA.2
BRA loadNothing
BRA loadDone
RSTA
STA.1
SETD.0 Entry
CALL makeNode
CALL appendNode
loadNothing:
; ---- Where a load finishes ----
;
; NOT WHERE ONE FAILS, which the old name for this said and which is a different thing: every
; successful load arrives here too, once its last line has been dealt with. That is worth
; being plain about, because a flag set here on the strength of the name was set on every
; file that opened perfectly well.
loadDone:
RET
; A name that is not on the disk is a new document rather than a mistake, which is what makes
; this the way to start one. Remembered, because "0 lines" is what an empty file that IS on
; the disk also says, and a name typed slightly wrong looks exactly like the document you
; meant to open - right up until you save it somewhere new.
loadNew:
SETD.0 IsNew
INIA 0x01
STA.0
RET
; DP3 is a node. Puts it on the end of the list.
@@ -838,6 +881,8 @@ ColonText:
": "
CommaText:
", "
NewText:
"new file"
LinesText:
" lines"
LineText:
@@ -861,8 +906,12 @@ NoWriteText:
TooLongText:
"a line in it is longer than this can edit, so it has not been opened"
; Whether the name was not on the disk, which makes this a new document rather than one
; being opened. Zero until loadFile finds out otherwise.
IsNew:
0x00
FileName:
#Reserve 0d24
#Reserve 0d64
Command:
#Reserve 0d41
; A hundred and twenty eight and the zero that ends it, which is what a line is everywhere
+17 -11
View File
@@ -12,7 +12,7 @@
start:
SETD.0 Name
INIB 0d29
INIB 0d63
SWI osArgument
SETD.0 Name
LDA.0
@@ -111,19 +111,23 @@ noName:
SWI osPrintString
INIA 0d2
SWI osExit
; ---- What went wrong, in words ----
;
; It used to print the number the filesystem answered with, as "error 2". THERE IS NO SUCH
; VOCABULARY: the library documents its answer as zero or not zero and never as a code, so
; the number named nothing and could not be looked up - it just looked like it could.
;
; A name that is not on the disk is the only way opening fails that a person can do anything
; about, and it is nearly always a name typed slightly wrong. Saying so is more use than any
; number would have been.
openFailed:
SETD.0 OpenError
SWI osPrintString
BRI printError
BRI failed
readFailed:
SETD.0 ReadError
SWI osPrintString
printError:
RSTA
MVQB
SWI osPrintNumber
SETD.0 NewLine
SWI osPrintString
failed:
; ITS OWN EXIT, and it did not have one. This fell through into finished and reported
; that everything was fine, having just printed the reason it was not - which nobody
; noticed while the only reader was a person, who could see both.
@@ -140,9 +144,11 @@ Usage:
"more: give me a file name
"
OpenError:
"more: cannot find the file, error "
"more: there is no file by that name
"
ReadError:
"more: cannot read the file, error "
"more: the disk would not give me that file
"
NewLine:
0x0A 0x00
MorePrompt:
@@ -150,7 +156,7 @@ MorePrompt:
ClearPrompt:
0x0A 0x00
Name:
#Reserve 0d29
#Reserve 0d64
Remaining:
0x00 0x00
LinesLeft:
+2 -2
View File
@@ -10,7 +10,7 @@
start:
SETD.0 Name
INIB 0d29
INIB 0d63
SWI osArgument
SETD.0 Name
LDA.0
@@ -81,7 +81,7 @@ ReadError:
NewLine:
0x0A 0x00
Name:
#Reserve 0d29
#Reserve 0d64
Remaining:
0x00 0x00
+2 -2
View File
@@ -16,7 +16,7 @@ start:
; Where to go is the argument. Nothing else about this program says a directory name, so
; running it anywhere else moves it anywhere else.
SETD.0 Where
INIB 0d40
INIB 0d63
SWI osArgument
SETD.0 Where
LDA.0
@@ -88,7 +88,7 @@ noFile:
#Base 0x2000
Where:
#Reserve 0d40
#Reserve 0d64
Left:
0x00 0x00
Went:
+1 -1
View File
@@ -503,7 +503,7 @@ Typed in as bytes, checked by disassembling it back, and run. It ends with `SWI
`Edit` is the first program on this machine that makes a file a person typed - every byte on every disk before it was put there by the host tool. It is line oriented in the manner of `ed`: `l` lists, `a` adds at the end, `i` and `c` and `d` take a line number, `w` writes and `q` stops.
It includes nothing but `services.asm` and `text.asm`: the filesystem and the console are the system's, asked for rather than carried. That is what brought `Edit` down from 4,941 bytes to 2,157 bytes without a line of its own logic changing - and the way that was checked is worth knowing, because the recorded output of the `cosmosEdit` test did not move by a single byte across the rewrite.
It includes nothing but `services.asm` and `text.asm`: the filesystem and the console are the system's, asked for rather than carried. That is what brought `Edit` down from 4,941 bytes to 2,243 bytes without a line of its own logic changing - and the way that was checked is worth knowing, because the recorded output of the `cosmosEdit` test did not move by a single byte across the rewrite.
**A line it reads in is at most 128 characters**, the same length a line is everywhere else
on this machine, and a file with a longer one is refused rather than opened. Refused rather