diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index a682990..f243349 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -223,7 +223,7 @@ HI Typed in as bytes, checked by disassembling it back, and run. It ends with `SWI osExit`, which is how it gives the machine to the shell rather than to nothing. -There are no breakpoints yet, and `g` does not come back. The machinery for both already exists and nothing has used it: SplitBit has 192 undecodable bytes, and an invalid opcode dispatches through the `BadOpcode` vector carrying **the address of the offending byte**. A breakpoint is a spare byte written over an instruction and a handler waiting for it. +`g` does not come back: what it runs has to give the machine to the shell itself, which `SWI osExit` is how a program does. Breakpoints are not the monitor's - they are `SWI osBreak`, written into the program rather than poked over it, and described under Stopping To Look. ### The Editor: @@ -354,7 +354,7 @@ A file of 256 blocks or more is refused by `osFileRead` rather than partly read, ### Reading A File That Will Not Fit: -`osFileRead` hands over a whole file, which settles the question for anything under 64K and settles nothing above it. CosmOS's own source is above it: the sources together are a hundred kilobytes and Data Memory is sixty four. A machine that is one day going to assemble itself has to be able to read a file bigger than its memory. +`osFileRead` hands over a whole file, which settles the question for anything under 64K and settles nothing above it. CosmOS's own source is above it: the sources together are a hundred kilobytes and Data Memory is sixty four. A machine that assembles itself has to be able to read a file bigger than its memory, and this is what that stands on. So there is a second way to ask. `osFileInfo` says how big something is and `osFileBlock` hands over one block of it, and between them a program reads a file of any size through a buffer of 256 bytes. @@ -552,13 +552,16 @@ than merely checking its filesystem code against itself. CosmOS is early software for an experimental computer. It runs one application at a time, has no privilege levels or process isolation, does not relocate applications, and -provides a line assembler but not yet a native assembler for source files, nor a linker. Its present purpose is to make -SplitBit usable from inside the machine: inspect it, manage persistent files, load -programs, provide common services, and return reliably to a command prompt. +has no linker. Its purpose is to make SplitBit usable from inside the machine: inspect +it, manage persistent files, load programs, provide common services, and return reliably +to a command prompt. -The intended long-term milestone is self-hosting: editing SplitBit assembly source under -CosmOS, assembling and linking it natively, and eventually rebuilding CosmOS and its own -development tools on the machine. +**Self-hosting is done.** `Assembler/` reads source off a SplitBit disk and writes a boot +image or a loadable program back to it, byte for byte what the host assembler builds from +the same source. It assembles CosmOS, and it assembles itself, and the CosmOS it built +assembles CosmOS again to the same bytes. What is left of that milestone is a linker, and +editing source under CosmOS comfortably enough to want to: `Edit` is line oriented and +knows nothing about assembly. ## Additional Information: diff --git a/Programs/makefile b/Programs/makefile index 527624e..22450bb 100644 --- a/Programs/makefile +++ b/Programs/makefile @@ -49,8 +49,20 @@ $(BUILD)/%.bin: %.asm $(ASM) $(INCLUDES) -M $(@:.bin=.d) -o $@ $< # Assemble and run a single program, as in 'make run-hello'. -run-%: $(BUILD)/%.bin - $(EMU) $< +# +# THE NAME IS THE PROGRAM'S, NOT ITS PATH. This used to be a pattern rule against +# $(BUILD)/%.bin, which worked while every program sat at the top of this directory and +# stopped working the moment they were filed into Examples/ - 'make run-hello' had nothing +# to match. Somebody trying the one command the header advertises should not be the way +# that is discovered, so the name is now looked up among the programs instead. +run-%: + @target=`echo $(BINARIES) | tr ' ' '\n' | grep -E "(^|/)$*\.bin$$" | head -1`; \ + if [ -z "$$target" ]; then \ + echo "There is no program called '$*'. What there is:"; \ + echo $(PROGRAMS) | tr ' ' '\n' | sed 's|.*/||;s|\.asm$$||;s|^| |'; \ + exit 1; \ + fi; \ + $(MAKE) --no-print-directory "$$target" && $(EMU) "$$target" # ---- CosmOS ---- # diff --git a/makefile b/makefile index 2619574..7b7fe8e 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,14 @@ DEPFLAGS = -MMD -MP # strdup, dirname and getopt. Asking for POSIX.1-2008 by name means the build does # not rely on the compiler happening to default to a mode where those are visible, # and it survives someone overriding CFLAGS, which is why it is kept separate. -POSIXFLAGS = -D_POSIX_C_SOURCE=200809L +# +# _XOPEN_SOURCE=700 IS POSIX.1-2008, plus the XSI extensions. The plain +# _POSIX_C_SOURCE=200809L was here and is not quite enough: realpath is an XSI interface, +# so under -std=c11 -pedantic it went undeclared and the assembler would not compile. The +# ordinary build never noticed, because without -std=c11 the compiler's own default +# already declares it. The README makes a claim about the strict build, so 'make strict' +# below settles it rather than leaving it to be discovered. +POSIXFLAGS = -D_XOPEN_SOURCE=700 # Directories SRC_DIR_EMU = Source/Emulator @@ -70,8 +77,23 @@ $(OBJ_DIR)/%.o: $(SRC_DIR_ASM)/%.c # Pull in the header dependencies written out by the compiler above. -include $(EMU_OBJS:.o=.d) $(ASM_OBJS:.o=.d) $(DSK_OBJS:.o=.d) +# ---- The strict build the README promises ---- +# +# "The sources are ISO C and build clean under -std=c11 -pedantic with -Wall -Wextra." +# That is a claim somebody may check by typing it, so the suite checks it first. It was +# false when this target was written: realpath went undeclared under a feature test macro +# that did not reach far enough, which the ordinary -Os build never saw. +STRICT = -std=c11 -pedantic -Wall -Wextra -Werror $(POSIXFLAGS) + +strict: + @for source in $(SRC_DIR_EMU)/*.c $(SRC_DIR_ASM)/*.c $(SRC_DIR_DSK)/*.c; do \ + $(CC) $(STRICT) -c $$source -o /dev/null || exit 1; \ + done + @echo "The sources build clean under -std=c11 -pedantic." + # Run the test suite against the programs in Programs/ -test: $(EMU_TARGET) $(ASM_TARGET) $(DSK_TARGET) +test: $(EMU_TARGET) $(ASM_TARGET) $(DSK_TARGET) strict + @echo @./Tests/run.sh @echo @./Tests/disk.sh