M3: programs that bring their own vectors

> load Asm.sbx
    > run Keys.asm
    wrote Keys.sbx: program 558, data 85, labels 52
    > load Keys.sbx
    > run
    keys, by interrupt. q stops.
    ab
    the console has been handed back

The machine assembles a program carrying an interrupt handler, the loader
installs its vector, the console interrupts into it, and the shell takes the
vector back at exit. Byte for byte identical to the C assembler's, and
Tests/native.sh now checks a boot image and four loadable programs on every
run.

WHAT IT TOOK:

  A declaration and an implementation are the SAME ENTRY. services.asm says
  a service is called osPrintString and has number 16; cosmos.asm says
  osPrintString is handled by handlePrintString. The name is met twice and
  the second time fills in the handler, which is what lets one shared file
  serve both the caller and the implementer.

  So the first pass declares and the second implements. That is forced: a
  handler is an address, and no address is known until every label has been
  placed.

  Boot in a loadable program fills the entry field rather than being
  installed - vector zero is where the whole machine starts, and a program
  loaded into a running system has no business saying anything about that.
  A boot image is the one thing that does, so there it is installed like any
  other, behind a "VEC" marker in the SPBT file.

  Device is named by the port, and Device with the five reserved names are
  matched without regard to case, the way mnemonics are: they are part of
  the language rather than names the programmer chose. Devices have no names
  of their own, so they are given one nothing can type.

TWO BUGS, both of a kind worth naming.

The first: "is this a loadable program" was written out as an OR of the two
segment bases in seven places, and the sense wanted is the opposite in most
of them. One of the seven had it backwards and put a version ONE header on a
file carrying vectors, which a loader is right to refuse. It is one flag
now, settled once and tested the same way everywhere.

The second: finding the entry to write a handler into means calling vecFind,
which reads the entry's fields out - including the handler it does not have
yet. An address resolved into VecHandler before the find was overwritten
with zero by the find itself, and the file came out with a vector pointing
at address zero: a slot that looked installed and went nowhere. The
resolved address has a variable of its own now.

Keys.asm and console.asm go on the CosmOS disk, so the whole path can be
watched rather than only tested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-21 11:50:52 -04:00
co-authored by Claude Opus 5
parent 04424a8917
commit 20989c3439
7 changed files with 785 additions and 98 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ SplitBit is a custom 8 bit system designed for hobbyist projects and experimenta
- Loadable Programs: A program that was not booted from carries a header saying where it belongs, and Programs/loader.asm reads one off a disk, puts it there, and runs it.
- An Operating System: CosmOS boots the machine, mounts a disk, lists what is on it, loads a program and runs it, and takes the machine back when it finishes. It comes with a library of programs to run, including a game and a line editor that writes files a person typed.
- System Services: A loaded program reaches the console and the disk through numbered software interrupts rather than carrying a copy of the code that drives them. The numbers are written down in one file that both sides include, so neither ever types one. It took the editor from 4941 bytes to 1983 without changing a line of what it does.
- A Native Assembler: SplitBit assembles SplitBit. Programs/CosmOS/Assembler/ is an assembler written in SplitBit assembly that runs under CosmOS, reads source off a SplitBit disk, and writes a binary back to it with no host involved. It builds boot images and loadable applications, following #Include, #Base, #Reserve and #Align, so a program assembled on the machine can then be loaded and run by it. Its output has to be byte for byte identical to what the C assembler produces from the same source, which is what Tests/native.sh checks.
- A Native Assembler: SplitBit assembles SplitBit. Programs/CosmOS/Assembler/ is an assembler written in SplitBit assembly that runs under CosmOS, reads source off a SplitBit disk, and writes a binary back to it with no host involved. It builds boot images and loadable applications, following every directive the language has - including #Vectors, so a program that brings its own interrupt handlers can be assembled on the machine, loaded by it, and have its vectors installed and taken back again. Its output has to be byte for byte identical to what the C assembler produces from the same source, which is what Tests/native.sh checks.
- Streaming Reads: A file bigger than the machine's memory is read a block at a time, through services that keep nothing open between calls. CosmOS's own source is 104K against 64K of Data Memory, so this is what a self-hosted assembler will stand on.
- Storage: A block device with 256 byte blocks and 16 megabytes of them, backed by an image file on the host. It knows blocks and not files, because a filesystem is meant to be software SplitBit runs.
- Memory Controller: Reads and writes Program Memory, moves blocks between memory banks, reaches memory that devices bring with them, and guards a range against being written by accident. It is how a SplitBit machine loads a program.