CosmOS had 1,161 bytes of Program Memory left before the address applications load at, and Tab completion is not going to fit in that with anything to spare. So the wall moves up one page: the system keeps below 0x4FFF and 0x2FFF, and an application is based at 0x5000 and 0x3000. A PAGE IS A CHEAP THING TO GIVE IT AND AN EXPENSIVE THING TO RUN OUT OF. An application still has 44K of Program Memory before the vector table and the largest one here uses 7.5K, so what was taken from applications is space nothing has ever asked for - while what the system gained is the difference between building the next thing and counting bytes while building it. Not doubling, which was the version that would have cost application space worth minding. One page, and the same again when it is needed. Nothing in the machine knows where the wall is, so this is 34 #Base lines, one threshold in the fault handler, and the table in the CosmOS README that Tests/docs.sh reads its limits out of. The native assembler's scratch map had to move with it, and docs.sh said so before anything ran: its data reached 0x40D6 and its buffers began at 0x4000, so they were sitting on its variables. That file already carries a paragraph about the floor coming up and the map staying where it was. It has happened twice now, and been caught by a check the first time wrote. Twenty three recordings are the same runs a page higher. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
183 lines
3.8 KiB
NASM
183 lines
3.8 KiB
NASM
; A program that keeps a file without knowing how a filesystem works.
|
|
;
|
|
; INCLUDES NOTHING BUT THE SERVICE NAMES. No sbfs.asm, no console.asm - the system has both
|
|
; of those running already, and this asks it rather than carrying a second copy. That is the
|
|
; whole point of the program: if it works, a tool that edits documents does not need two and
|
|
; a half kilobytes of filesystem bound into it.
|
|
;
|
|
; It writes a file, reads it back, says how big it was, renames it, and takes it away again,
|
|
; which is every file service there is.
|
|
;
|
|
; ---- What you will see before the handlers are written ----
|
|
;
|
|
; The numbers are pinned but nothing answers to them yet, so the first call dispatches
|
|
; through an empty vector and the machine stops:
|
|
;
|
|
; Fault: Software vector 21, dispatched from Program Address 0x200B, has no handler
|
|
; installed.
|
|
;
|
|
; That is the fault working properly rather than the program being broken. A vector with
|
|
; nothing in it is not a jump to address zero; it is a stop, with the vector named and the
|
|
; place it was called from named, which is as much as the machine can know.
|
|
|
|
#Include services.asm
|
|
|
|
#Program
|
|
|
|
#Base 0x5000
|
|
|
|
start:
|
|
; ---- Write it ----
|
|
;
|
|
; A and B together are how many bytes there are, most significant first, which is the
|
|
; same sixteen bits a length always is on this machine.
|
|
SETD.0 Name
|
|
SETD.1 Body
|
|
RSTA
|
|
INIB 0d22 ; The text and its newline. NOT the zero the assembler put
|
|
SWI osFileSave ; after it: a text file ends where the text ends.
|
|
BNQ noSave
|
|
SETD.0 SavedText
|
|
SWI osPrintString
|
|
|
|
; ---- Read it back ----
|
|
;
|
|
; DP3 comes back holding how many bytes there were, because that 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
|
|
; in a pointer.
|
|
SETD.0 Name
|
|
SETD.1 Landing
|
|
SWI osFileRead
|
|
BNQ noRead
|
|
SETD.0 ReadText
|
|
SWI osPrintString
|
|
|
|
PSHD.3
|
|
POPB ; The low byte is on top, the way a pointer is pushed.
|
|
POPA
|
|
SWI osPrintNumber
|
|
SETD.0 BytesText
|
|
SWI osPrintString
|
|
|
|
; And now the length is needed for something rather than just reported. What came back is
|
|
; a file, not a string: nothing on the disk ends in a zero byte, because the entry says
|
|
; where it stops instead. So a zero goes on the end before it can be printed as one.
|
|
SETD.1 Landing
|
|
PSHD.3
|
|
POPB
|
|
POPA
|
|
walkToEnd:
|
|
BRB atEnd
|
|
INCD.1
|
|
DECB
|
|
BRI walkToEnd
|
|
atEnd:
|
|
RSTA
|
|
STA.1
|
|
|
|
SETD.0 Landing
|
|
SWI osPrintString
|
|
|
|
; ---- Call it something else ----
|
|
SETD.0 Name
|
|
SETD.1 OtherName
|
|
SWI osFileRename
|
|
BNQ noRename
|
|
SETD.0 RenamedText
|
|
SWI osPrintString
|
|
|
|
; ---- And take it away ----
|
|
SETD.0 OtherName
|
|
SWI osFileDelete
|
|
BNQ noDelete
|
|
SETD.0 DeletedText
|
|
SWI osPrintString
|
|
|
|
; Reading it now should fail, and a service saying no is not the same as one that is not
|
|
; there: this comes back with an answer rather than stopping the machine.
|
|
SETD.0 OtherName
|
|
SETD.1 Landing
|
|
SWI osFileRead
|
|
BRQ stillThere
|
|
SETD.0 GoneText
|
|
SWI osPrintString
|
|
RSTA
|
|
SWI osExit
|
|
|
|
stillThere:
|
|
SETD.0 StillText
|
|
SWI osPrintString
|
|
RSTA
|
|
SWI osExit
|
|
|
|
noSave:
|
|
SETD.0 NoSaveText
|
|
SWI osPrintString
|
|
INIA 0d1
|
|
SWI osExit
|
|
noRead:
|
|
SETD.0 NoReadText
|
|
SWI osPrintString
|
|
INIA 0d1
|
|
SWI osExit
|
|
noRename:
|
|
SETD.0 NoRenameText
|
|
SWI osPrintString
|
|
INIA 0d1
|
|
SWI osExit
|
|
noDelete:
|
|
SETD.0 NoDeleteText
|
|
SWI osPrintString
|
|
INIA 0d1
|
|
SWI osExit
|
|
|
|
#Data
|
|
|
|
#Base 0x3000
|
|
|
|
Name:
|
|
"kept.txt"
|
|
OtherName:
|
|
"moved.txt"
|
|
|
|
Body:
|
|
"a file kept by asking
|
|
"
|
|
|
|
SavedText:
|
|
"saved it
|
|
"
|
|
ReadText:
|
|
"read it back, "
|
|
BytesText:
|
|
" bytes:
|
|
"
|
|
RenamedText:
|
|
"renamed it
|
|
"
|
|
DeletedText:
|
|
"deleted it
|
|
"
|
|
GoneText:
|
|
"and it is gone
|
|
"
|
|
StillText:
|
|
"but it is still there
|
|
"
|
|
|
|
NoSaveText:
|
|
"it would not save
|
|
"
|
|
NoReadText:
|
|
"it would not read
|
|
"
|
|
NoRenameText:
|
|
"it would not rename
|
|
"
|
|
NoDeleteText:
|
|
"it would not delete
|
|
"
|
|
|
|
Landing:
|
|
#Reserve 0d256
|