Say "boot image" where that is what is meant
"Binary" was doing three jobs. It meant an SPBT file that the machine starts from; it meant whatever the assembler happened to produce, which is now either that or a loadable program; and it meant a compiled host tool. A word that means three things means none of them, and the first of the three has a name already - this project has been calling them boot images for a while and the manuals had not caught up. Where it means an SPBT file -> boot image Where it means either output -> output Where it means a host executable -> left alone Where it means base two -> left alone The user facing messages move with it: Error: No boot image specified. Usage: ./SplitBit [OPTIONS] <boot image> Error: This is not a SplitBit boot image. Error: This boot image is in format version 2, and this emulator reads 1. Successfully wrote SplitBit boot image to "hello.bin". The assembler's own help was the interesting case. Its -o writes either format, so "the binary" there was never right - it is "the output" now, and the message that names the format is the one that says which it wrote. No recorded output contained the word, so nothing needed re-blessing. Checked before starting rather than after. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
306b4dce92
commit
b6004bdcde
@@ -91,13 +91,13 @@ void printUsage(const char *programName) {
|
||||
printf("Usage: %s [OPTIONS] <sourcefile>\n", programName);
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -o <file> Write the binary to this path instead of alongside the source.\n");
|
||||
printf(" -o <file> Write the output to this path instead of alongside the source.\n");
|
||||
printf(" -I <dir> Look in this directory for included files. May be given more than once.\n");
|
||||
printf(" -M <file> Write the source files this binary depends on, as a make rule.\n");
|
||||
printf(" -M <file> 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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "../Assembler/assembly.h"
|
||||
|
||||
void printHelp(const char *programName) {
|
||||
printf("Usage: %s [OPTIONS] <binaryfile>\n", programName);
|
||||
printf("Usage: %s [OPTIONS] <boot image>\n", programName);
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -d, --debug Enable debug mode.\n");
|
||||
|
||||
Reference in New Issue
Block a user