Edit: use the system's services instead of carrying the filesystem

The editor included sbfs.asm and console.asm, which was 3235 of its 4941
bytes. Both come out: reading and writing a file, printing and reading a
line are services now, and sbfsMount goes entirely because the system has
already mounted the disk. Only text.asm remains, at 357 bytes, because
textSame and textNumber own nothing and touch no device - sharing those is
a linker's job rather than an operating system's.

4941 bytes to 1983, a little better than predicted because dropping the
mount and the blocks-and-tail arithmetic went with the library rather than
being translated.

ConsoleEndOfInput went with console.asm, so the end of input is now read
from the console status port. That is better than what it replaced: the
port is there whether or not the system is.

Nothing it does changed, and that is checked rather than asserted. The
recorded output of the cosmosEdit test does not move by a single byte
across this commit - a test written days before the rewrite, checking a
property rather than an output, and therefore able to verify a change it
knew nothing about.

One thing is lost and worth naming: there is no way to ask whether a disk
is present, so the editor's "there is no disk" message is gone. On a
diskless machine it now opens an empty document and fails at w instead. The
shell already refuses to load without a disk, so the editor cannot normally
be reached that way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Anachronaut
2026-08-19 18:19:51 -04:00
co-authored by Claude Opus 5
parent 0b6d2be43f
commit 3e87a67809
+90 -73
View File
@@ -75,33 +75,39 @@ start:
RSTA RSTA
STA.0 STA.0
CALL sbfsMount
BNQ noDisk
CALL loadFile CALL loadFile
SETD.0 FileName SETD.0 FileName
CALL printString SWI osPrintString
SETD.0 CommaText SETD.0 CommaText
CALL printString SWI osPrintString
CALL countLines CALL countLines
MVQA MVQA
CALL printByteDecimal CALL printByte
; One line is not one lines. The same care the shell's file listing takes, for the same
; reason: it costs four instructions and reads as carelessness without them.
DECA
BRA oneLine
SETD.0 LinesText SETD.0 LinesText
CALL printString BRI sayLines
oneLine:
SETD.0 LineText
sayLines:
SWI osPrintString
CALL newLine CALL newLine
commandLoop: commandLoop:
SETD.0 PromptText SETD.0 PromptText
CALL printString SWI osPrintString
SETD.0 Command SETD.0 Command
INIB 0d40 INIB 0d40
CALL readLine SWI osReadLine
; Running out of typing ends it, the same way it ends the shell. ; Running out of typing ends it, the same way it ends the shell.
SETD.0 ConsoleEndOfInput INA 0x01
LDA.0 INIB 0x02 ; ENDED
BNA quit AND
BNQ quit
SETD.0 Command SETD.0 Command
LDA.0 LDA.0
@@ -150,7 +156,7 @@ commandArgument:
BRQ quit BRQ quit
SETD.0 WhatText SETD.0 WhatText
CALL printString SWI osPrintString
CALL newLine CALL newLine
BRI commandLoop BRI commandLoop
@@ -159,15 +165,10 @@ quit:
noName: noName:
SETD.0 NoNameText SETD.0 NoNameText
CALL printString SWI osPrintString
CALL newLine CALL newLine
SWI osExit SWI osExit
noDisk:
SETD.0 NoDiskText
CALL printString
CALL newLine
SWI osExit
; ---- The commands ---- ; ---- The commands ----
@@ -189,13 +190,14 @@ doInsert:
BRA insertNeedsLine BRA insertNeedsLine
insertLoop: insertLoop:
SETD.0 EnteringText SETD.0 EnteringText
CALL printString SWI osPrintString
SETD.0 Entry SETD.0 Entry
INIB 0d80 INIB 0d80
CALL readLine SWI osReadLine
SETD.0 ConsoleEndOfInput INA 0x01
LDA.0 INIB 0x02 ; ENDED
BNA commandLoop AND
BNQ commandLoop
; A line that is just a dot ends it, which is the oldest convention there is for this. ; A line that is just a dot ends it, which is the oldest convention there is for this.
SETD.0 Entry SETD.0 Entry
@@ -216,7 +218,7 @@ insertLoop:
insertNeedsLine: insertNeedsLine:
SETD.0 NeedsLineText SETD.0 NeedsLineText
CALL printString SWI osPrintString
CALL newLine CALL newLine
BRI commandLoop BRI commandLoop
@@ -228,13 +230,14 @@ doChange:
BNQ noSuchLine BNQ noSuchLine
SETD.0 EnteringText SETD.0 EnteringText
CALL printString SWI osPrintString
SETD.0 Entry SETD.0 Entry
INIB 0d80 INIB 0d80
CALL readLine SWI osReadLine
SETD.0 ConsoleEndOfInput INA 0x01
LDA.0 INIB 0x02 ; ENDED
BNA commandLoop AND
BNQ commandLoop
SETD.0 Entry SETD.0 Entry
CALL makeNode CALL makeNode
@@ -257,7 +260,7 @@ doDelete:
noSuchLine: noSuchLine:
SETD.0 NoLineText SETD.0 NoLineText
CALL printString SWI osPrintString
CALL newLine CALL newLine
BRI commandLoop BRI commandLoop
@@ -265,17 +268,17 @@ doWrite:
CALL writeFile CALL writeFile
BNQ writeFailed BNQ writeFailed
SETD.0 WrittenText SETD.0 WrittenText
CALL printString SWI osPrintString
SETD.0 WroteSize SETD.0 WroteSize
CALL printWordDecimal CALL printWord
SETD.0 BytesText SETD.0 BytesText
CALL printString SWI osPrintString
CALL newLine CALL newLine
BRI commandLoop BRI commandLoop
writeFailed: writeFailed:
SETD.0 NoWriteText SETD.0 NoWriteText
CALL printString SWI osPrintString
CALL newLine CALL newLine
BRI commandLoop BRI commandLoop
@@ -513,9 +516,9 @@ listStep:
SETD.0 Counted SETD.0 Counted
LDA.0 LDA.0
CALL printByteDecimal CALL printByte
SETD.0 ColonText SETD.0 ColonText
CALL printString SWI osPrintString
PSHD.3 PSHD.3
POPD.1 POPD.1
@@ -558,23 +561,19 @@ listDone:
; document rather than a mistake, which is what makes this the way to start one. ; document rather than a mistake, which is what makes this the way to start one.
loadFile: loadFile:
SETD.0 FileName SETD.0 FileName
CALL sbfsFind
BNQ loadNothing
SETD.1 0x40 0x00 SETD.1 0x40 0x00
CALL sbfsRead SWI osFileRead
BNQ loadNothing BNQ loadNothing
; How many bytes came back: the block count is the high byte of the length and the tail ; How many bytes came back. The service says so in DP3, which is one of the two things a
; is the low one, which is how a size is put together everywhere on this disk. ; service is allowed to answer in, and a file that fits in memory has a length that fits
SETD.0 SbfsFileBlocks ; in a pointer. A name that is not on the disk fails here, and that is a new document
DPUP.0 0d01 ; rather than a mistake.
LDA.0 PSHD.3
SETD.1 ReadLeft POPA ; The low byte is on top, the way a pointer is pushed.
STA.1 POPB
SETD.0 SbfsFileTail
LDA.0
SETD.1 ReadLeft SETD.1 ReadLeft
STB.1
INCD.1 INCD.1
STA.1 STA.1
@@ -715,24 +714,9 @@ writeOut:
; whole blocks and the low byte is the tail. ; whole blocks and the low byte is the tail.
SETD.2 WroteSize SETD.2 WroteSize
STD.1.2 STD.1.2
SETD.0 WroteSize
LDA.0
INIB 0x40
CCF
SUB
MVQA
SETD.0 SbfsFileBlocks
RSTB
STB.0
INCD.0
STA.0
SETD.0 WroteSize
INCD.0
LDA.0
SETD.0 SbfsFileTail
STA.0
; The size the file is about to be, said in bytes, before saving changes what these mean. ; Turn where it stopped into how big it is, which is one subtraction: the high byte less
; 0x40 and the low byte as it stands.
SETD.0 WroteSize SETD.0 WroteSize
LDA.0 LDA.0
INIB 0x40 INIB 0x40
@@ -740,11 +724,44 @@ writeOut:
SUB SUB
MVQA MVQA
SETD.0 WroteSize SETD.0 WroteSize
STA.0 STA.0 ; WroteSize is now a count of bytes, which is what gets printed.
; And into the two registers the service takes a size in.
SETD.0 WroteSize
LDA.0
INCD.0
LDB.0
SETD.0 FileName SETD.0 FileName
SETD.1 0x40 0x00 SETD.1 0x40 0x00
CALL sbfsSaveFile SWI osFileSave
RET
; ---- All that is left of a console library ----
;
; Printing a string and reading a line are services now. These three are only here because
; what a service takes is not quite what the call sites have: a number arrives in two
; registers rather than one or in memory, and a line feed is a string like any other.
newLine:
SETD.0 Break
SWI osPrintString
RET
; A is a byte.
printByte:
PSHA
POPB
RSTA
SWI osPrintNumber
RET
; DP0 is a two byte number, most significant first.
printWord:
LDA.0
INCD.0
LDB.0
SWI osPrintNumber
RET RET
; DP0 is a two byte number, A is a byte. Adds the one to the other. ; DP0 is a two byte number, A is a byte. Adds the one to the other.
@@ -765,6 +782,8 @@ addByteToWord:
#Base 0x1000 #Base 0x1000
Break:
0x0A 0x00
PromptText: PromptText:
"> " "> "
EnteringText: EnteringText:
@@ -775,6 +794,8 @@ CommaText:
", " ", "
LinesText: LinesText:
" lines" " lines"
LineText:
" line"
WrittenText: WrittenText:
"written, " "written, "
BytesText: BytesText:
@@ -785,8 +806,6 @@ WhatText:
"l list, a add, i insert, c change, d delete, w write, q quit" "l list, a add, i insert, c change, d delete, w write, q quit"
NoNameText: NoNameText:
"edit what? try: run edit <file>" "edit what? try: run edit <file>"
NoDiskText:
"there is no disk"
NoLineText: NoLineText:
"there is no such line" "there is no such line"
NeedsLineText: NeedsLineText:
@@ -824,6 +843,4 @@ ReadLeft:
WroteSize: WroteSize:
0x00 0x00 0x00 0x00
#Include sbfs.asm
#Include text.asm #Include text.asm
#Include console.asm