diff --git a/Programs/CosmOS/Assembler/Asm.asm b/Programs/CosmOS/Assembler/Asm.asm index 92ca217..0d03936 100644 --- a/Programs/CosmOS/Assembler/Asm.asm +++ b/Programs/CosmOS/Assembler/Asm.asm @@ -2315,17 +2315,21 @@ ImgHold: DropWalk: 0x00 0x00 -; How big an output file this can build. Everything the assembler makes has to fit here at once, -; because a file is written in one call and there is nowhere to put half of one. CosmOS -; itself comes to 9,564 bytes. -; Eighteen kilobytes, and IT HAS TO AGREE WITH THE SCRATCH MAP, which says where that room -; actually is. Three numbers in three files describe these buffers - this one, LabLimit and -; LabRoom in labels.asm, and the map itself - and each of the three has now been the one -; that was left behind while the other two moved. -; Which block of the file is in the window, and whether anything has been put in it. The -; window itself is in scratch, like every other buffer here: a #Reserve is written into the -; file as zeroes and copied at load, and a program that carries its own scratch pays for it -; twice. +; ---- The output, which goes out as it is made ---- +; +; THERE IS NO LIMIT ON HOW BIG A FILE THIS CAN BUILD, and that is the point of the window +; below. The assembler used to hold the whole output in an eighteen kilobyte buffer and +; write it in one call at the end, which made the largest program it could assemble a +; property of ITS OWN memory rather than of the disk - and cosmos.bin reached 13,245 bytes +; of the 13,312 there were, sixty seven short of the system being unable to build itself. +; +; Now one block at a time goes through OutBlock, which lives in scratch like every other +; buffer here: a #Reserve is written into the file as zeroes and copied at load, so a +; program that carries its own scratch pays for it twice. What bounds the output is the +; contiguous run the disk can find for it. +; +; OutAt is the cursor, OutBlock which block of the file the window holds, OutHeld whether +; it holds one at all, and OutDirty whether anything has been put in it since it arrived. OutAt: 0x00 0x00 OutBlock: diff --git a/Programs/CosmOS/Assembler/scratch.asm b/Programs/CosmOS/Assembler/scratch.asm index 6e8bbd7..efe25eb 100644 --- a/Programs/CosmOS/Assembler/scratch.asm +++ b/Programs/CosmOS/Assembler/scratch.asm @@ -12,9 +12,14 @@ ; ; 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 +; below 0x1FFF, 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. +; ; 0x4000 6144 the label index, 1536 entries of four ; 0x5800 16384 the label names, packed end to end ; 0x9800 256 one block of the output file, on its way to the disk @@ -30,9 +35,12 @@ ; and the map stayed where it was, leaving sixteen kilobytes between the two that nothing ; touched. ; -; Starting at 0x4000 takes that back. The assembler's data is 4,114 bytes from 0x2000, so -; there is still nearly four kilobytes of slack in front of this - and room for its data to -; double before the two would meet. +; Starting at 0x4000 takes that back. The assembler's data is a little over four kilobytes +; from 0x2000, so there is still nearly four kilobytes of slack in front of this - and room +; for its 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 diff --git a/Tests/docs.sh b/Tests/docs.sh index e0180ad..efa74ab 100755 --- a/Tests/docs.sh +++ b/Tests/docs.sh @@ -539,6 +539,47 @@ else: "cosmos.asm says the system keeps below 0x%s in %s Memory and the CosmOS" " README says 0x%04X" % (stated[kind].upper(), kind, limits[kind] - 1)) +# ---- The assembler's scratch map sits above what it says it sits above ---- +# +# scratch.asm is a MAP rather than a set of declarations: the buffers are not reserved, +# they are addresses written in a comment, because reserving them would put 22K of zeroes +# in the file and the assembler could not load itself. Nothing enforces a word of it. +# +# So it carries two claims about the machine around it, and both have gone stale once. It +# said the system keeps below 0x1000 for a while after the system's half of Data Memory +# was doubled - twelve lines above the paragraph explaining the doubling. And the map +# starts at 0x4000 on the grounds that the assembler's own data ends well before there, +# which was measured on the day and is not measured again by anything. +scratch = open("Programs/CosmOS/Assembler/scratch.asm").read() +floor = re.search(r"the system keeps\s*;?\s*below 0x([0-9A-Fa-f]{4})", scratch) +if not floor: + problems.append("scratch.asm no longer says what the system keeps below") +elif "Data" in limits and int(floor.group(1), 16) + 1 != limits["Data"]: + problems.append( + "the assembler's scratch map says the system keeps below 0x%s and the CosmOS" + " README says 0x%04X" % (floor.group(1).upper(), limits["Data"] - 1)) + +first = re.search(r"^;\s+0x([0-9A-Fa-f]{4})\s+\d+\s+the label index", scratch, re.M) +if not first: + problems.append("scratch.asm no longer states where its buffers begin") +else: + built = subprocess.run(["./Assembler", "-I", "Programs/CosmOS/Source", + "-I", "Programs/CosmOS/Assembler", + "Programs/CosmOS/Assembler/Asm.asm", "-o", os.devnull], + capture_output=True, text=True) + # A loadable program reports "Data: N bytes at 0xAAAA"; a boot image says it another + # way. The assembler is the former, and the address matters as much as the size. + said = re.search(r"Data:\s*(\d+) bytes at 0x([0-9A-Fa-f]{4})", built.stdout) + if not said: + problems.append("could not measure the native assembler's data") + else: + ends = int(said.group(2), 16) + int(said.group(1)) + if ends > int(first.group(1), 16): + problems.append( + "the native assembler's data reaches 0x%04X and its scratch map begins at" + " 0x%s - the buffers are on top of the variables" + % (ends - 1, first.group(1).upper())) + if problems: print("The manuals and the code disagree:") for p in problems: