Two nitpicks from review, and one of them was only half right, which is why
each was checked rather than swept.
THE TEST DEPENDENCIES were nowhere. The README said what building needs and
stopped, so somebody with a C compiler and nothing else would get through
'make' and fall over on 'make test'. It needs bash and Python 3 - two of the
checking scripts are Python, and one of those opens a pseudo-terminal - plus
stty, timeout and the usual text utilities.
"BOTH TOOLS" WAS WRONG IN TWO PLACES OUT OF SIX. 'make sanitize' builds the
default target, which is all three, so the README and the makefile both
undercounted what they rebuild.
The other four are right and were left alone. assembly.h says both tools
have to agree where the vector table begins, and bootstrap.c and cpu.c say
they share the boot image format and the vector layout - in all three cases
that is the emulator and the assembler, and SplitDisk has no opinion about
any of it. The makefile's POSIX comment is the same story: SplitDisk uses
not one POSIX interface, so it names the two that do rather than counting to
three.
Media/ is a home for the screenshot that is coming, with a note saying what
belongs in it and that docs.sh will catch a link to something removed from
it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
Found by a review, all three confirmed by trying them rather than by
reading.
1. THE STRICT BUILD CLAIM WAS FALSE. The README says the sources build clean
under -std=c11 -pedantic with -Wall -Wextra, and they did not: realpath is
an XSI interface, and _POSIX_C_SOURCE=200809L does not reach it, so the
assembler would not compile. The ordinary -Os build never saw it, because
without -std=c11 the compiler's own default declares realpath anyway.
_XOPEN_SOURCE=700 is POSIX.1-2008 plus XSI, and covers every file on its
own. Narrowed by compiling each source with each candidate macro rather
than by adding one and hoping.
And 'make strict' now checks it, as part of 'make test'. The README makes
a claim somebody may check by typing it, so the suite types it. Verified
the check bites by putting the old macro back.
2. THE COSMOS README HAD NOT CAUGHT UP WITH THIS WEEK. It said there were no
breakpoints and proposed writing a spare byte over an instruction - two
commits after SWI osBreak was built, which does it without overwriting
anything and is described correctly further down the same file. Its
Current Scope said there was no native assembler and that self-hosting
was the intended long-term milestone. And the streaming section spoke of
a machine "one day going to assemble itself".
All three now say what is true. Self-hosting is described as done, with
what is left of it named: a linker, and an editor that knows what
assembly is.
3. 'make run-hello' DID NOT WORK, and it is the one command the makefile's
own header advertises. It was a pattern rule against $(BUILD)/%.bin,
which worked while every program sat at the top of Programs/ and broke
the moment they were filed into Examples/ - which I did, four commits ago,
without trying it.
The name is looked up among the programs now, so it is the program's name
rather than its path, and an unknown one lists what there is instead of
saying "No rule to make target".
The same sweep was run across all four documents for other claims this week
invalidated. The remaining "not yet" phrases are about faults that genuinely
are not defined yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
Programs/CosmOS/Assembler/ is an assembler written in SplitBit assembly. It
runs under CosmOS, reads source off a SplitBit disk, and writes a binary back
to it with no host involved anywhere:
> run Asm.sbx hello.asm
wrote hello.bin: program 17, data 14, labels 2
THE ACCEPTANCE TEST IS THE BYTES. Tests/native.sh assembles Programs/hello.asm
both ways and compares the two files byte for byte, then runs the one the
machine built. "It ran" and "the sizes look right" both pass for a binary with
a label one byte out, which is a program that jumps into the middle of an
instruction - so the only honest test is the one SplitDisk and sbfs.asm
already work under: two implementations of one written specification, each
checking the other. The files are identical and the result prints Hello,
World! in 70 cycles.
hello.asm is the target because it is the oldest program in the repository.
The first thing this machine ever ran is now the first thing it assembles for
itself.
TWO PASSES OVER STREAMED SOURCE. The C assembler reads every token of every
file into one array; that cannot port, because cosmos.asm alone is 56,047
bytes against 64K of Data Memory. The native one streams through a 256 byte
window, twice, and keeps only the label table between the passes. Two passes
suffice because every length is known without resolving anything - an
instruction's from its shape, a value's is one, a string's is its characters
and a zero - so the first pass fixes every address and the second never needs
a fixup list. A forward reference stops being a special case and becomes the
reason there are two passes at all.
The parts, each checked before anything was built on it:
source.asm characters out of a file of any size, with a line number
token.asm tokens out of characters, one character of lookahead
classify.asm what a token is, in the C assembler's order, which IS the
language: keyword, instruction, value, string, label
labels.asm names packed in an arena, four bytes of index each
numbers.asm sixteen bit arithmetic, since sbfs.asm's cannot be reached
table.asm the instruction set, generated by the same script the
monitor's copy is, and now BOTH are checked by docs.sh
readTest.asm and tokenTest.asm check the reader and the tokenizer on their
own, recorded as cosmosSource and cosmosTokens. A wrong classification does
not produce a wrong byte somewhere obvious; it produces a right looking
program of the wrong length, so it is worth catching where it happens.
WHAT IT REFUSES: #Include, #Base, #Align, #Reserve and #Vectors are refused
by name rather than ignored. Skipping a directive would produce a file that
looked right and was the wrong length, which is the worst thing an assembler
can do.
Two traps worth recording, both already known to this project and both hit
again: CALL restores A, B and DP0-DP2, so three routines returning an answer
in A had it undone by their own return; and numStep works on DP0, so three
sites that set DP1 left a pointer that never advanced.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW