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
97 lines
5.3 KiB
NASM
97 lines
5.3 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 0x2FFF, 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.
|
|
;
|
|
; That sentence said 0x1000 for a while after the system's half of Data Memory was
|
|
; doubled, twelve lines above the paragraph that explains the doubling. A stale number is
|
|
; bad enough; a stale number sitting next to the correction is worse, because whichever
|
|
; one a reader takes is a coin toss.
|
|
;
|
|
; 0x5000 6144 the label index, 1536 entries of four
|
|
; 0x6800 16384 the label names, packed end to end
|
|
; 0xA800 256 one block of the output file, on its way to the disk
|
|
; 0xA900 17152 free
|
|
; 0xE000 1792 the vector names, 64 entries of twenty eight
|
|
; 0xE700 2048 the reader's stack, six levels of 301
|
|
; 0xEF00 368 which files have been included, sixteen names of 23
|
|
;
|
|
; IT USED TO START AT 0x8000, and the reason given was that everything above the
|
|
; assembler's own data is free. That was true when it was written and stopped being true
|
|
; without anything noticing: the system kept below 0x1000 then, and its data now reaches
|
|
; 0x1FFF, and the assembler's own moved from 0x1000 to 0x2000 with it. The floor came up
|
|
; and the map stayed where it was, leaving sixteen kilobytes between the two that nothing
|
|
; touched.
|
|
;
|
|
; Starting above the assembler's own data takes that back. It began at 0x4000 with the data
|
|
; from 0x2000, and moved to 0x5000 when the system was given another page and every
|
|
; application's data moved to 0x3000 with it - THE FLOOR CAME UP A SECOND TIME, exactly as
|
|
; the paragraph above says it did the first, and this time the check below said so before
|
|
; anything ran: the assembler's data reached 0x40D6 and the index began at 0x4000, so the
|
|
; buffers were sitting on the variables.
|
|
;
|
|
; There is still nearly four kilobytes of slack in front of this, and room for the data to
|
|
; double before the two would meet. `make test` measures that gap now
|
|
; rather than trusting this paragraph, and measures the floor above as well, because both
|
|
; of those numbers describe the machine AROUND this file and neither is enforced by a line
|
|
; of code anywhere.
|
|
;
|
|
; THE ROOM WENT TO ALL THREE OF THE BUFFERS THAT WERE FULL, and there turned out to be
|
|
; three rather than one. The output was the obvious wall - cosmos.bin was 13,245 bytes
|
|
; against 13,312, which is sixty seven - so it was given the lot, and the very next thing
|
|
; added to the system ran out of LABEL NAMES instead, at 8,081 of 8,192. Two ceilings a
|
|
; 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 IS NO LONGER HELD AT ALL. It used to be built whole in memory and handed over
|
|
; at the end, which is what made a buffer of eighteen kilobytes the largest thing this
|
|
; machine could assemble. The file is produced in order, so it is written as it is made,
|
|
; through one block of window - and the eighteen kilobytes that were its share are free.
|
|
;
|
|
; What to do with them is not obvious and does not have to be decided today. Nothing here
|
|
; is close to full: the names are at half, the index at a third, and the output has no
|
|
; ceiling of its own any more. Leaving the room unclaimed is better than sharing it out
|
|
; among buffers that do not need it, because an unclaimed page is available to whichever
|
|
; one turns out to want it.
|
|
;
|
|
; 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.
|
|
;
|
|
; The reader's levels went from 293 to 301 when an include gained somewhere to be looked
|
|
; for: the name in each level is a PATH now, and "/Lib/" is five characters of it. Six
|
|
; levels of 301 is 1806, so the room here has to stay above that - which is why the include
|
|
; list moved up rather than the stack simply being asked to fit.
|
|
;
|
|
; 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:
|
|
0x50 0x00
|
|
ScratchLabArena:
|
|
0x68 0x00
|
|
ScratchWindow:
|
|
0xA8 0x00
|
|
ScratchVecNames:
|
|
0xE0 0x00
|
|
ScratchSrcStack:
|
|
0xE7 0x00
|
|
ScratchIncNames:
|
|
0xEF 0x00
|