Files
SplitBit-Emulator/Programs/CosmOS/Assembler/scratch.asm
T
AnachronautandClaude Opus 5 fb335681d2 M4: SplitBit assembles SplitBit, and then assembles itself
> load Asm.sbx
    > run cosmos.asm
    wrote cosmos.bin: program 7036, data 2448, labels 475
    > run Asm.asm
    wrote Asm.sbx: program 7533, data 4099, labels 555

Both byte for byte identical to what the host assembler builds from the
same source. The machine now builds the operating system it is running on,
and builds the thing that built it.

THE CHECK THAT MATTERS MOST IS THE THIRD ONE. A binary that matches could
still have come from an assembler wrong in some way this particular source
happens not to exercise. So Tests/native.sh boots the CosmOS that CosmOS
built and has THAT assemble CosmOS again - and the second generation is
identical to the first, down to the cycle count. It is a fixed point: the
machinery has been through itself. After this the host is a convenience
rather than a necessity.

WHAT STOOD IN THE WAY was not the assembler. It loaded, faulted at 7,780
cycles, and the fault was in CosmOS: a loaded program is staged at 0x8000
before being blitted into place, so the whole FILE has to fit in the 32,768
bytes above it. The assembler's file was 33,983, and 22K of that was
zeroed scratch buffers - because #Reserve emits what it reserves.

None of that is initialised data. It is scratch, wanted only while the
assembler runs, and while it runs everything above its own data is free.
So the buffers are a MAP now rather than declarations - Assembler/scratch.asm
writes down six addresses and the file carries none of it. 33,983 bytes
became 11,648, and the assembler could load itself.

The map has a file of its own because the reader and the label table both
need addresses out of it while neither includes the other.

The sizes are cut to the largest thing it is asked to build, and that turns
out not to be the operating system: the assembler is 555 labels and 11,648
bytes of output against CosmOS's 475 and 9,564. The hardest thing this
assembles is itself.

Also: sizing it for CosmOS meant raising the label table, and raising the
label table is what pushed the file over the staging limit. The two facts
only met because the first one was tried.

Speed, measured rather than guessed: CosmOS takes 80,168,646 cycles, which
is eighty seconds of emulated time and under a second under --fast. Most of
it is a straight walk of 475 label names, several thousand times. Sorting
or bucketing that is easy and was deliberately not written before there was
something to measure.

make run-cosmos now puts every source file on the disk, so the whole thing
can be done rather than read about.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-08-21 12:03:31 -04:00

45 lines
2.0 KiB
NASM

; Where the assembler's big buffers live.
;
; A map rather than a set of declarations, and it has a file of its own because the reader
; and the label table both need addresses out of it while neither includes the other.
;
#Data
; NOT #Reserve, AND THAT IS THE WHOLE POINT. Reserved space in a segment is written into
; the file as zeroes and copied at load, so 22K of scratch made a 34K file - and a loaded
; program is staged at 0x8000 before being put in place, which leaves exactly 32,768 bytes
; for the whole of it. The assembler could not load itself.
;
; None of this is initialised data. It is scratch, wanted only while the assembler is
; running, and while it is running everything above its own data is free: the system keeps
; 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.
;
; 0x8000 3072 the label index, 768 entries of four
; 0x8C00 8192 the label names, packed end to end
; 0xAC00 13312 the binary being built
; 0xE000 1792 the vector names, 64 entries of twenty eight
; 0xE700 1758 the reader's stack, six levels of 293
; 0xEE00 368 which files have been included, sixteen names of 23
;
; That ends at 0xEF70, with the Stack coming down from 0xFFFF above it - about four
; kilobytes, against the tens of bytes of CALL frames this ever nests.
;
; THE TWO THINGS THAT DECIDE THESE SIZES are the largest program it will be asked to build
; and the largest one it will be asked to read. CosmOS is 475 labels and 9,564 bytes of
; output; the assembler itself is 555 labels, about 6,800 bytes of name and 11,648 of output. The
; second is bigger than the first, which is worth knowing: the hardest thing this assembles
; is not the operating system, it is itself.
ScratchLabIndex:
0x80 0x00
ScratchLabArena:
0x8C 0x00
ScratchImage:
0xAC 0x00
ScratchVecNames:
0xE0 0x00
ScratchSrcStack:
0xE7 0x00
ScratchIncNames:
0xEE 0x00