diff --git a/Programs/CosmOS/Assembler/Asm.asm b/Programs/CosmOS/Assembler/Asm.asm index f4dd838..5c5c4c2 100644 --- a/Programs/CosmOS/Assembler/Asm.asm +++ b/Programs/CosmOS/Assembler/Asm.asm @@ -6,7 +6,8 @@ ; Loading and running are separate commands in this shell, so the file to assemble is the ; argument to run rather than a second name after the program's. ; -; Reads assembly source off the disk and writes a binary back to it, with no host involved +; Reads assembly source off the disk and writes a boot image or a loadable program back to it, +; with no host involved ; anywhere. The output has to be byte for byte what the C assembler produces from the same ; source, which is the only honest test of it and the one the suite runs. ; @@ -2046,7 +2047,7 @@ ImgHold: DropWalk: 0x00 0x00 -; How big a binary this can build. Everything the assembler makes has to fit here at once, +; 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. ImgRoom: @@ -2152,7 +2153,7 @@ BasesText: at zero, on top of whatever is there. Give both a #Base, or neither. " TooBigText: -"the binary would be bigger than this assembler has room to build +"the output would be bigger than this assembler has room to build " NoWriteText: "it would not write " diff --git a/Programs/CosmOS/Assembler/scratch.asm b/Programs/CosmOS/Assembler/scratch.asm index cb555bd..48d4171 100644 --- a/Programs/CosmOS/Assembler/scratch.asm +++ b/Programs/CosmOS/Assembler/scratch.asm @@ -17,7 +17,7 @@ ; ; 0x8000 3072 the label index, 768 entries of four ; 0x8C00 8192 the label names, packed end to end -; 0xAC00 13312 the binary being built +; 0xAC00 13312 the output file 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 diff --git a/README.md b/README.md index 3805537..9a50128 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ SplitBit is an 8 bit computer that does not exist: a CPU with its own instruction set, split Program and Data memories, an interrupt and vector system, a bus that programs can enumerate, a memory controller that can write code into memory, and a disk. This repository is a C implementation of the machine, an assembler for it, a tool for its disks, and the software that runs on it, which now includes an operating system and an assembler written in SplitBit's own assembly language. -**SplitBit assembles SplitBit.** `Programs/CosmOS/Assembler/` runs on the machine, reads source off a SplitBit disk, and writes a binary back to it with no host involved. It builds the operating system it is running under, and it builds itself, both byte for byte identical to what the C assembler produces from the same source. The test suite then boots the CosmOS that CosmOS built and has *that* one assemble CosmOS again, and the second generation is identical to the first, so the machinery has been through itself. After that the host is a convenience rather than a necessity. +**SplitBit assembles SplitBit.** `Programs/CosmOS/Assembler/` runs on the machine, reads source off a SplitBit disk, and writes a boot image or a loadable program back to it with no host involved. It builds the operating system it is running under, and it builds itself, both byte for byte identical to what the C assembler produces from the same source. The test suite then boots the CosmOS that CosmOS built and has *that* one assemble CosmOS again, and the second generation is identical to the first, so the machinery has been through itself. After that the host is a convenience rather than a necessity. ``` > load Asm.sbx @@ -74,7 +74,7 @@ Then `dir` to see what is there, `load Snake.sbx` and `run` to play something, o ## Running Programs: SplitBit ``` -./SplitBit [options] [binary file] +./SplitBit [options] [boot image] ``` | Option | What it does | @@ -96,12 +96,12 @@ If the CPU reads a byte that is not an instruction, it goes to the fault handler | Option | What it does | | --- | --- | -| `-o ` | Write the binary to this path. | +| `-o ` | Write the output to this path. | | `-I ` | Look in this directory for included files. May be given more than once. | -| `-M ` | Write out which source files the binary depends on, as a make rule. | +| `-M ` | Write out which source files the output depends on, as a make rule. | | `-h`, `--help` | Show help and usage information. | -Without `-o` the binary takes the source file's name with a `.bin` extension, in the directory you called the assembler from. Included files are looked for beside the file that includes them, and then along the directories given with `-I`. +Without `-o` the output takes the source file's name with a `.bin` extension, in the directory you called the assembler from. Included files are looked for beside the file that includes them, and then along the directories given with `-I`. ## Managing Disks: SplitDisk @@ -123,7 +123,7 @@ Files are laid down contiguously, so a disk can have free blocks without having ## Building Programs With Make: -The assembler is built to work with make. `-o` puts the binary where the build system wants it, and `-M` writes out which libraries went into it, so that editing a library reassembles everything that includes it. +The assembler is built to work with make. `-o` puts the output where the build system wants it, and `-M` writes out which libraries went into it, so that editing a library reassembles everything that includes it. `Programs/makefile` does this for the programs in this repository: diff --git a/Source/Assembler/Assembler.c b/Source/Assembler/Assembler.c index 730e924..2f13c06 100644 --- a/Source/Assembler/Assembler.c +++ b/Source/Assembler/Assembler.c @@ -91,13 +91,13 @@ void printUsage(const char *programName) { printf("Usage: %s [OPTIONS] \n", programName); printf("\n"); printf("Options:\n"); - printf(" -o Write the binary to this path instead of alongside the source.\n"); + printf(" -o Write the output to this path instead of alongside the source.\n"); printf(" -I Look in this directory for included files. May be given more than once.\n"); - printf(" -M Write the source files this binary depends on, as a make rule.\n"); + printf(" -M Write the source files this output depends on, as a make rule.\n"); printf(" -h, --help Display this help message.\n"); } -// Writes a make rule naming every source file that went into the binary, so that a +// Writes a make rule naming every source file that went into the output, so that a // build system knows to reassemble when any of them changes. The empty rules after it // are so that deleting a library does not leave make with a prerequisite it cannot // build; without them the build stops instead of just reassembling. diff --git a/Source/Assembler/assembly.h b/Source/Assembler/assembly.h index 17d874b..10f99f4 100644 --- a/Source/Assembler/assembly.h +++ b/Source/Assembler/assembly.h @@ -8,13 +8,13 @@ #ifndef ASSEMBLY_H #define ASSEMBLY_H -// ---- The SplitBit binary format ---- +// ---- The SplitBit boot image format ---- // -// A binary starts with a file header, then the Program Segment, then the Data +// A boot image starts with a file header, then the Program Segment, then the Data // Segment. All multi byte numbers are stored most significant byte first. // // Offset Size Field -// 0 4 "SPBT", so a file that is not a SplitBit binary is spotted at once +// 0 4 "SPBT", so a file that is not a boot image is spotted at once // 4 1 Format version // 5 4 Required feature flags // 9 3 "PRG" @@ -27,14 +27,14 @@ // .. 2 Vector Segment length, in bytes // .. K Vector Segment, four bytes per entry // -// The Vector Segment is optional and comes last, so a binary written before it existed +// The Vector Segment is optional and comes last, so an image written before it existed // simply ends after its Data Segment and still loads. Each entry is two bytes saying // where in Program Memory the vector sits, then two bytes saying where its handler is, // most significant byte first. It is a list rather than an image of the table, so a // program with three handlers costs twelve bytes instead of a padded kilobyte. // -// The feature flags are how a binary says it needs something the base machine does -// not provide, so that an emulator which cannot provide it refuses to run the binary +// The feature flags are how a boot image says it needs something the base machine does +// not provide, so that an emulator which cannot provide it refuses to run the image // rather than quietly doing the wrong thing. No features are defined yet; the field // is here so that adding one later does not need another format version. @@ -110,7 +110,7 @@ #define SPLITBIT_HEADER_BYTES (SPLITBIT_MAGIC_LENGTH + 1 + SPLITBIT_FLAGS_LENGTH \ + 2 * (SEGMENT_MARKER_LENGTH + SEGMENT_LENGTH_BYTES)) -// Features this build of the emulator can provide. A binary asking for anything +// Features this build of the emulator can provide. An image asking for anything // outside this set is refused. #define SPLITBIT_FEATURES_SUPPORTED 0x00000000u diff --git a/Source/Assembler/secondPass.c b/Source/Assembler/secondPass.c index a0e2f08..365a775 100644 --- a/Source/Assembler/secondPass.c +++ b/Source/Assembler/secondPass.c @@ -653,7 +653,7 @@ void writeOutputFile(const char *outputFileName, uint8_t *Program, int programCo } // Write the file header: the magic, the format version, and the features this - // binary needs from the machine. An emulator that cannot provide one of those + // boot image needs from the machine. An emulator that cannot provide one of those // features refuses the file rather than running it and going quietly wrong. fwrite(SPLITBIT_MAGIC, sizeof(char), SPLITBIT_MAGIC_LENGTH, outputFile); fputc(SPLITBIT_FORMAT_VERSION, outputFile); @@ -703,7 +703,7 @@ void writeOutputFile(const char *outputFileName, uint8_t *Program, int programCo } // The Vector Segment, only if the program named any. Leaving it out entirely is - // what lets a binary written before vectors existed still load: the reader treats + // what lets an image written before vectors existed still load: the reader treats // the end of the file as an empty table rather than a missing one. int installed = 0; for (int i = 0; i < vectorArrayCount; i++) { @@ -730,7 +730,7 @@ void writeOutputFile(const char *outputFileName, uint8_t *Program, int programCo } fclose(outputFile); - printf("Successfully wrote SplitBit binary to \"%s\".\n", outputFileName); + printf("Successfully wrote SplitBit boot image to \"%s\".\n", outputFileName); printf(GREEN " Program Segment size: %d bytes.\n Data Segment size: %d bytes.\n" RESET, programCount, dataCount); if (installed > 0) { printf(GREEN " Vectors: %d.\n" RESET, installed); diff --git a/Source/DiskTool/sbfs.h b/Source/DiskTool/sbfs.h index b2f7ae0..51c6b51 100644 --- a/Source/DiskTool/sbfs.h +++ b/Source/DiskTool/sbfs.h @@ -8,7 +8,7 @@ // has to change there in the same breath. // // All multi byte numbers are most significant byte first, the same as every other number -// SplitBit stores: addresses, the SPBT binary header, and the vector table. +// SplitBit stores: addresses, the SPBT boot image header, and the vector table. // // Written by Anachronaut diff --git a/Source/Emulator/bootstrap.c b/Source/Emulator/bootstrap.c index 80c927a..5f7305d 100644 --- a/Source/Emulator/bootstrap.c +++ b/Source/Emulator/bootstrap.c @@ -4,7 +4,7 @@ // 10/16/2024 #include "bootstrap.h" -#include "../Assembler/assembly.h" // For the binary format, which both tools share. +#include "../Assembler/assembly.h" // For the boot image format, which both tools share. #include #include @@ -39,14 +39,14 @@ static uint8_t readMarker(FILE *file, const char *expected, int length, char *fo return strncmp(found, expected, length) != 0; } -// Reads the file header: the magic, the format version, and the features the binary +// Reads the file header: the magic, the format version, and the features the boot image // says it needs from the machine. static uint8_t readFileHeader(FILE *file) { char magic[SPLITBIT_MAGIC_LENGTH + 1]; if (readMarker(file, SPLITBIT_MAGIC, SPLITBIT_MAGIC_LENGTH, magic)) { - fprintf(stderr, "Error: This is not a SplitBit binary.\n"); + fprintf(stderr, "Error: This is not a SplitBit boot image.\n"); if (strncmp(magic, "PRG", 3) == 0) { - fprintf(stderr, " It looks like a binary from before the format carried a version.\n Reassemble it and try again.\n"); + fprintf(stderr, " It looks like a boot image from before the format carried a version.\n Reassemble it and try again.\n"); } else { fprintf(stderr, " Expected the file to begin with \"%s\", found \"%s\".\n", SPLITBIT_MAGIC, magic); } @@ -58,7 +58,7 @@ static uint8_t readFileHeader(FILE *file) { return 1; } if (version != SPLITBIT_FORMAT_VERSION) { - fprintf(stderr, "Error: This binary is in format version %u, and this emulator reads version %u.\n", version, SPLITBIT_FORMAT_VERSION); + fprintf(stderr, "Error: This boot image is in format version %u, and this emulator reads version %u.\n", version, SPLITBIT_FORMAT_VERSION); return 1; } @@ -68,7 +68,7 @@ static uint8_t readFileHeader(FILE *file) { } uint32_t missing = required & ~(uint32_t)SPLITBIT_FEATURES_SUPPORTED; if (missing) { - fprintf(stderr, "Error: This binary was built for a machine this emulator cannot provide.\n"); + fprintf(stderr, "Error: This boot image was built for a machine this emulator cannot provide.\n"); fprintf(stderr, " It asks for feature bits 0x%08X, which are not implemented here.\n", missing); return 1; } @@ -135,7 +135,7 @@ static uint8_t readVectorSegment(FILE *file, uint8_t *Program) { return 1; } if (slot < SOFTWARE_VECTOR_BASE) { - fprintf(stderr, "Error: This binary puts a vector at 0x%04X, which is below the vector table.\n", slot); + fprintf(stderr, "Error: This boot image puts a vector at 0x%04X, which is below the vector table.\n", slot); return 1; } Program[slot] = (handler >> 8) & 0xFF; diff --git a/Source/Emulator/cpu.c b/Source/Emulator/cpu.c index 65fd2d5..702e712 100644 --- a/Source/Emulator/cpu.c +++ b/Source/Emulator/cpu.c @@ -10,7 +10,7 @@ uint16_t shiftRegister; // Reads one entry out of a vector table. Most significant byte first, matching the -// branch instructions and the binary format. +// branch instructions and both file formats. static uint16_t readVector(const uint8_t *programMemory, uint16_t base, uint8_t index) { uint16_t address = base + (uint16_t)index * VECTOR_ENTRY_BYTES; return ((uint16_t)programMemory[address] << 8) | (uint16_t)programMemory[address + 1]; diff --git a/Source/Emulator/emulator.c b/Source/Emulator/emulator.c index 09b1ca8..10adeb8 100644 --- a/Source/Emulator/emulator.c +++ b/Source/Emulator/emulator.c @@ -79,7 +79,7 @@ int main (int argc, char *argv[]) { programFile = argv[optind]; optind++; } else { - fprintf(stderr, "Error: No binary file specified.\n"); + fprintf(stderr, "Error: No boot image specified.\n"); printHelp(argv[0]); return 1; } diff --git a/Source/Emulator/utility.c b/Source/Emulator/utility.c index 97f1367..7ad3f05 100644 --- a/Source/Emulator/utility.c +++ b/Source/Emulator/utility.c @@ -11,7 +11,7 @@ #include "../Assembler/assembly.h" void printHelp(const char *programName) { - printf("Usage: %s [OPTIONS] \n", programName); + printf("Usage: %s [OPTIONS] \n", programName); printf("\n"); printf("Options:\n"); printf(" -d, --debug Enable debug mode.\n"); diff --git a/SplitBit Assembler Manual.md b/SplitBit Assembler Manual.md index 153f012..f4fca3e 100644 --- a/SplitBit Assembler Manual.md +++ b/SplitBit Assembler Manual.md @@ -417,16 +417,16 @@ Assembler [options] | Option | Meaning | | -- | -- | -| -o, --output \ | Write the binary to this path. Without it, the binary is named after the source file, with a .bin extension, in the directory the assembler was run from. | +| -o, --output \ | Write the output to this path. Without it, the output is named after the source file, with a .bin extension, in the directory the assembler was run from. | | -I, --include \ | Look in this directory for included files. May be given more than once, and the directories are searched in the order given. | -| -M, --depend \ | Write out which source files went into the binary, as a make rule. | +| -M, --depend \ | Write out which source files went into the output, as a make rule. | | -h, --help | Print the options and stop. | -The assembler stops at the first error, says which file and line it was in, and exits without writing a binary. +The assembler stops at the first error, says which file and line it was in, and exits without writing anything. ## Building With Make: -The -o and -M options are there so that the assembler fits into a build system. -o puts the binary wherever the build wants it, and -M writes down which libraries went into it, so that editing a library reassembles every program that includes it. +The -o and -M options are there so that the assembler fits into a build system. -o puts the output wherever the build wants it, and -M writes down which libraries went into it, so that editing a library reassembles every program that includes it. ``` $(BUILD)/%.bin: %.asm @@ -589,7 +589,7 @@ wrote hello.bin: program 17, data 14, labels 2 Loading and running are separate commands in CosmOS, so the source file is the argument to `run`. -**Its output must be byte for byte what the host assembler produces from the same source**, and `Tests/native.sh` checks exactly that: it assembles `Programs/Examples/hello.asm` both ways and compares the files, then runs the one the machine built. This is the discipline SplitDisk and `sbfs.asm` already work under - two implementations of one written specification, each one checking the other. "It ran" is not good enough for an assembler, because a binary with a label one byte out runs right up until it jumps into the middle of an instruction. +**Its output must be byte for byte what the host assembler produces from the same source**, and `Tests/native.sh` checks exactly that: it assembles `Programs/Examples/hello.asm` both ways and compares the files, then runs the one the machine built. This is the discipline SplitDisk and `sbfs.asm` already work under - two implementations of one written specification, each one checking the other. "It ran" is not good enough for an assembler, because a file with a label one byte out runs right up until it jumps into the middle of an instruction. ### How It Differs Inside: @@ -649,7 +649,7 @@ wrote Asm.sbx: program 7533, data 4099, labels 555 Both come out **byte for byte identical** to what the host assembler builds from the same source. `make run-cosmos` puts every source file on the disk, so this can be done rather than read about. -**The check that matters most is the third one.** A binary that matches could still have been built by 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, which means the machinery has been through itself. +**The check that matters most is the third one.** A file that matches could still have been built by 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, which means the machinery has been through itself. After that the host is a convenience rather than a necessity.