docs(v4): the ROMs' shared entries, and the mesh ROM as built

DATASHEET-F18.md lists all 19 entries of the host ROM, the six shared ones
with the registers they use.  MACHINE.md 2.2: built; 277 words, not the
estimated 150-200; the system's words are address, push and ;.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 20:32:23 -04:00
co-authored by Claude Opus 5.5
parent d2df3679ac
commit 924c48cece
2 changed files with 47 additions and 15 deletions
+35 -9
View File
@@ -96,14 +96,40 @@ registers (§10.3).
- **I/O addresses** (§10) sit inside the address space. A fetch from or store to one goes to
the device, not to RAM. The exceptions are NODE-ERROR, which writes RAM and then traps, and
the console receive addresses, where a store goes to RAM.
- **ROM.** Built (2026-10-15; `MACHINE.md` §2): 2049 words of F18 code, `capsules/v4/rom`,
assembled by `v4/tools/mkrom.c`. The machine starts at its entry 12 and assembles the
system's source (`capsules/v4/sys`) from the console. It is a read-only range at
- **ROM.** Built (2026-10-15; `MACHINE.md` §2): 2372 words of F18 code, `capsules/v4/rom`,
assembled by `v4/tools/mkrom.c`. The machine starts at its entry 18 and assembles the
system's source (`capsules/v4/sys`) from the console. A mesh node's ROM (`MACHINE.md` §2.2)
is 277 words: entries 0–5, the shared math, and nothing else. It is a read-only range at
`V4_NODE_WORDS` and above. It can be fetched and executed. A store there is an address fault.
In the model it is attached by the owner, as every device is, and a reset detaches it.
- Its routines are shared code, GA144-style (`MACHINE.md` 2.1). Payloads call them through
the entry table at the ROM's base. Their state lives in a reserved RAM area. This sheet will
list each entry's stack effect and the registers it uses once the ROM is built.
the entry table at the ROM's base. Their state lives in a reserved RAM area. The entries:
| Entry | Routine | Stack | Uses | In |
|---|---|---|---|---|
| 0 | `UM*` | ( u1 u2 -- ulo uhi ) | A | both ROMs |
| 1 | `UM/MOD` | ( ulo uhi ud -- urem uquot ), exact for uhi < ud | A | both ROMs |
| 2 | `D+` | ( d1 d2 -- d3 ) | — | both ROMs |
| 3 | `DNEGATE` | ( d -- -d ) | — | both ROMs |
| 4 | `Q.*` | ( a b -- c ), Q48.16 | A | both ROMs |
| 5 | `Q./` | ( a b -- q ), Q48.16; by zero: D-11's result and error 11 | A, B; `(Q/)`'s 5 cells | both ROMs |
| 6 | `(KEY)` | ( -- c ) | | host ROM |
| 7 | `(TOKEN)` | ( -- len ) | | host ROM |
| 8 | `(NUMBER)` | ( -- n flag ) | | host ROM |
| 9 | `(FIND)` | ( -- rec \| 0 ) | | host ROM |
| 10 | `(DEFINE)` | ( value kind -- ) | | host ROM |
| 11 | `(OPCODE)` | ( -- op \| -1 ) | | host ROM |
| 12 | `(OP)` | ( op -- ) | | host ROM |
| 13 | `(LIT)` | ( v -- ) | | host ROM |
| 14 | `(BRANCH)` | ( op target -- ) | | host ROM |
| 15 | `(BRANCH>)` | ( op -- ref ) | | host ROM |
| 16 | `(RESOLVE)` | ( ref target -- ) | | host ROM |
| 17 | `(LABEL)` | ( -- addr ) | | host ROM |
| 18 | `(ROM)`: where the host machine starts | | | host ROM |
The list is `v4/include/v4/rom_entries.h` for entries 0–5 and `capsules/v4/rom/main.f18`
for the rest. The assembler's routines (6–17) use A and B freely and keep their state in
the ROM's area of the memory map; their registers are not yet listed one by one.
## 6. Instruction word
@@ -309,10 +335,10 @@ These are reported, not hidden:
and it is not to be extended.
2. **Device addresses are attached by the owner, not fixed.** D-4 (the memory map) is deferred.
The FPGA needs fixed addresses.
3. **The ROM** is built and the host node boots from it (2026-10-15). The ROM is the full
assembler, about 2000 words, so it is the host node's. A mesh node's small loader ROM
(the agreed correction, `JUSTIFICATION.md` §9) is not built yet. Until it is, a node that
is born is sent the host's assembled system through its port.
3. **The ROM** is built and the host node boots from it (2026-10-15). A mesh node's ROM is
built too (`MACHINE.md` §2.2): entries 0–5, the shared math, and nothing else. In the test
host a node Hera births carries it. The products have no births yet, so they do not link
it. A node that is born is still sent the host's assembled system through its port.
4. **`stack.h`'s opening comment** still says there is no overflow detection "and there never
will be". D-16 revised that, and the header carries a revision note above it. The code
counts and guards (§4). The comment's first paragraph is out of date.
+12 -6
View File
@@ -9,7 +9,7 @@ section 6 (POST) stands.
(section 2), which assembles the system's `.f18` from the console; the prebuilt nucleus is gone
(`a73580e9`, with the final review's fixes in `ff75e69e` and `a28b5f22`). Steps 3 to 6 are not
built. Hera still sends a node the host's assembled system, not the ROM (step 4, ruled so for
now). The mesh ROM (section 2.2) is designed and not built.
now). The mesh ROM (section 2.2) is built.
## 1. The idea
@@ -89,7 +89,7 @@ wiring, drop its odd concepts, add our own. That is what v4 becomes, on the way
### 2.2 The mesh ROM (designed 2026-10-15)
**Status: designed, for review. Not built.**
**Status: built** (the commits of plan `docs/v4.0.0/plans/2026-10-15-mesh-rom.md`).
Not every node can carry the ROM of section 2. It is an assembler of about 2100 words, so it
belongs to host nodes (`JUSTIFICATION.md` §9: "the compiler lives on the host node ... mesh
@@ -119,7 +119,9 @@ by both tables so that the two orders cannot drift apart:
| 6 to 17 | the assembler's routines, entries 0 to 11 before this change | yes | no |
| 18 | `(ROM)`, where the host machine starts (entry 12 before this change) | yes | no |
- The mesh ROM is the six entries and the math: about 150 to 200 words.
- The mesh ROM is the six entries and the math: 277 words (the design estimated 150 to 200;
at the ROM's addresses a branch often starts a new instruction word, and a literal takes
one of its own). The host ROM grew by the same 277 words, to 2372.
- Within a build both ROMs sit at the same base, `V4_ROM_BASE`. Code the host assembles that
calls entry k therefore runs unchanged on a node carrying either ROM.
- `v4/tools/mkrom.c` builds both ROMs at each cell width. `v4/tools/mkmap.c` gives each entry's
@@ -127,8 +129,12 @@ by both tables so that the two orders cannot drift apart:
- The renumbering costs nothing: until now nothing but the boot and the tests' harness used an
entry number, and both only to start the machine.
**The system calls the ROM.** `UM*`, `UM/MOD`, `D+`, `DNEGATE`, `Q.*` and `Q./` keep their
dictionary entries in the system. Each one's code becomes a single `jump` to its ROM entry.
**The system calls the ROM.** `UM*`, `UM/MOD`, `D+`, `DNEGATE`, `Q.*` and `Q./` stay words of
the system, with the dictionary entries they had (`UM/MOD` never had one: it is a word of the
`.f18` layer, and FORTH-79's `U/MOD` is built on it). Each one's code is its entry's address,
`push` and `;`: the address goes onto the return stack and `;` goes there, which is a jump. A
branch to a constant is not in the assembler's language (`v4/src/text.c`), and the ROM's
assembler must accept the same language.
Every other word (`*`, `/MOD`, `U*`, number output, the other Q48 words) calls them by name, as
now, and is unchanged. `Q.TO-INT` stays an ordinary system word; the ROM keeps its own copy of
that one-line shift rather than making it an entry. `dict_hash` and `rom_hash` change, and each
@@ -144,7 +150,7 @@ products have no births yet.
values: 0, -1, the most negative cell, the largest cell, `UM/MOD` at the edge `uhi < ud`, and
`Q./` by zero (error 11 and D-11's result).
- The mesh ROM holds the six entries and the math, and nothing of the assembler.
- Hera's unit test: a node she has born computes `UM*`, `UM/MOD` and `Q./` and prints the right
- Hera's unit test: a node she has born computes `UM*`, `U/MOD` (on `UM/MOD`) and `Q./` and prints the right
answers.
- Then the whole suite at both widths, POST 538 of 538, and the three QEMU boots, as
`.claude/CLAUDE.md` says.