Two ceilings a hundred bytes apart look like one ceiling

The sixteen kilobytes taken back a moment ago all went to the output image,
because that was the wall: 13,245 bytes of cosmos.bin against 13,312. Lifting
it moved the machine straight into the next one, a hundred and eleven bytes
away - the label names, at 8,081 of 8,192 - and the index was a hundred and
eighteen entries from the same place.

So the room is shared out rather than given to the obvious one. Names and index
both double, and the output takes what is left, which is still four and a half
thousand bytes more than CosmOS needs.

LabLimit and LabRoom in labels.asm have to agree with the map in scratch.asm
and are now said to.

Worth recording how this was found, because it is the good case. The assembler
STOPPED and said "no room left for label names: Mode, at line 3598" - a limit
it checks, names, and points at. Every other ceiling this project has hit went
unnoticed until something downstream broke: a program loaded over the shell, a
path silently cut short, a file reported as itself less 65,536. A limit that
announces itself is worth the handful of instructions it costs.

The output's eighteen kilobytes are temporary. They exist because the assembler
holds a whole finished file in memory before writing it, and the file is
produced in order, so it could be written as it is made.

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-25 14:50:36 -04:00
co-authored by Claude Opus 5
parent ec56439d9a
commit 7cd5e34347
2 changed files with 28 additions and 14 deletions
+9 -4
View File
@@ -297,13 +297,18 @@ LabEnd:
; How many labels there may be, and how many bytes of name between them. ; How many labels there may be, and how many bytes of name between them.
; ;
; SIZED FOR THE ASSEMBLER ITSELF, which turns out to be the largest thing it is asked to ; SIZED FOR THE ASSEMBLER ITSELF, which turns out to be the largest thing it is asked to
; build: 555 labels and about 6,800 bytes of name, against CosmOS's 475 and 5,881. Running into ; build: 555 labels and about 6,800 bytes of name, against CosmOS's 650 and 8,081 - CosmOS is
; either limit says so rather than writing past the end of the table. The buffers live ; the bigger of the two now, and was the smaller when this was written. Running into either
; limit says so rather than writing past the end of the table, and that is what it did. The buffers live
; above the program rather than inside it - see the scratch map in Asm.asm. ; above the program rather than inside it - see the scratch map in Asm.asm.
; Fifteen hundred and thirty six names, and sixteen kilobytes to hold them in. Both were
; half that, and the names ran out first: 8,081 bytes of 8,192, which is a hundred and
; eleven - and the thing that ran into it was one ordinary piece of work adding eighteen
; labels. THESE TWO MUST AGREE WITH THE SCRATCH MAP, which says where the room actually is.
LabLimit: LabLimit:
0x03 0x00 0x06 0x00
LabRoom: LabRoom:
0x20 0x00 0x40 0x00
LabNamed: LabNamed:
": " ": "
+19 -10
View File
@@ -15,9 +15,9 @@
; below 0x1000, the staging area is only in use during a load, and the Stack comes down ; below 0x1000, the staging area is only in use during a load, and the Stack comes down
; from the top. So the addresses are written down here and the file carries none of it. ; from the top. So the addresses are written down here and the file carries none of it.
; ;
; 0x4000 3072 the label index, 768 entries of four ; 0x4000 6144 the label index, 1536 entries of four
; 0x4C00 8192 the label names, packed end to end ; 0x5800 16384 the label names, packed end to end
; 0x6C00 29696 the output file being built ; 0x9800 18432 the output file being built
; 0xE000 1792 the vector names, 64 entries of twenty eight ; 0xE000 1792 the vector names, 64 entries of twenty eight
; 0xE700 2048 the reader's stack, six levels of 301 ; 0xE700 2048 the reader's stack, six levels of 301
; 0xEF00 368 which files have been included, sixteen names of 23 ; 0xEF00 368 which files have been included, sixteen names of 23
@@ -33,11 +33,20 @@
; there is still nearly four kilobytes of slack in front of this - and room for its data to ; there is still nearly four kilobytes of slack in front of this - and room for its data to
; double before the two would meet. ; double before the two would meet.
; ;
; ALL SIXTEEN OF THOSE KILOBYTES WENT TO THE OUTPUT, which was the buffer that was actually ; THE ROOM WENT TO ALL THREE OF THE BUFFERS THAT WERE FULL, and there turned out to be
; full: cosmos.bin is 13,245 bytes against the 13,312 it used to have, which is sixty seven ; three rather than one. The output was the obvious wall - cosmos.bin was 13,245 bytes
; bytes, and the next thing added to the system would have made the machine unable to build ; against 13,312, which is sixty seven - so it was given the lot, and the very next thing
; it. That is a wall the label table is not yet against, so this is not the place to start ; added to the system ran out of LABEL NAMES instead, at 8,081 of 8,192. Two ceilings a
; sharing the room out evenly. ; hundred bytes apart look like one ceiling until the first is lifted.
;
; The index was a hundred and eighteen entries from the same place. So: names doubled,
; index doubled, and the output given what is left, which is still four and a half thousand
; bytes more than CosmOS needs today.
;
; The output's share is temporary. It exists only because the assembler holds a whole
; finished file in memory before writing it, and that is the next thing to go - the file is
; produced in order and could be written as it is made, which would leave this needing three
; blocks rather than eighteen kilobytes.
; ;
; That ends at 0xF070, with the Stack coming down from 0xFFFF above it - nearly four ; That ends at 0xF070, with the Stack coming down from 0xFFFF above it - nearly four
; kilobytes, against the tens of bytes of CALL frames this ever nests. ; kilobytes, against the tens of bytes of CALL frames this ever nests.
@@ -55,9 +64,9 @@
ScratchLabIndex: ScratchLabIndex:
0x40 0x00 0x40 0x00
ScratchLabArena: ScratchLabArena:
0x4C 0x00 0x58 0x00
ScratchImage: ScratchImage:
0x6C 0x00 0x98 0x00
ScratchVecNames: ScratchVecNames:
0xE0 0x00 0xE0 0x00
ScratchSrcStack: ScratchSrcStack: