docs(v4): the mesh ROM's design, MACHINE.md 2.2

Shared math in a small ROM for mesh nodes: UM*, UM/MOD, D+, DNEGATE,
Q.* and Q./ as entries 0-5 of both ROMs, from one source; the host
ROM's assembler entries follow, and its start moves from 12 to 18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 18:58:59 -04:00
co-authored by Claude Opus 5.5
parent 39744473f3
commit a6da45df53
+72
View File
@@ -83,6 +83,78 @@ What this asks of the ROM:
Direction (Captain Bob, 2026-10-15): much more GA144-ish. Take what serves from colorForth's Direction (Captain Bob, 2026-10-15): much more GA144-ish. Take what serves from colorForth's
wiring, drop its odd concepts, add our own. That is what v4 becomes, on the way to v5 and later. wiring, drop its odd concepts, add our own. That is what v4 becomes, on the way to v5 and later.
### 2.2 The mesh ROM (designed 2026-10-15)
**Status: designed, for review. Not built.**
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
nodes receive compiled code"). A mesh node carries a small ROM of shared math, as a GA144 node's
ROM carries multiply and divide steps (Captain Bob, 2026-10-15).
A mesh node needs no ROM to take code in. At reset it blocks on its ports and executes what
arrives (`MESH.md` 4.2 and 5). The mesh ROM does not change that. It has no start entry.
**One math source.** `capsules/v4/rom/math.f18` holds six routines and their private helpers.
They are moved out of the system's `.f18` (`core.f18`, `numout.f18`, `qmath.f18`) unchanged in
behaviour. It has no names, no headers and no FORTH (rule 7.1). Its errors are raised as now:
`Q./` by zero leaves D-11's result and stores 11 into NODE-ERROR. `Q./`'s five scratch cells
stay at `(Q/)`, an address fixed in the memory map, which is the reserved RAM of section 2.1.
**Two ROMs, one entry order.** Both ROMs begin with the same six entries, written once and used
by both tables so that the two orders cannot drift apart:
| Entry | Routine | Host ROM | Mesh ROM |
|---|---|---|---|
| 0 | `UM*` ( u1 u2 -- ulo uhi ) | yes | yes |
| 1 | `UM/MOD` ( ulo uhi ud -- urem uquot ) | yes | yes |
| 2 | `D+` ( d1 d2 -- d3 ) | yes | yes |
| 3 | `DNEGATE` ( d -- -d ) | yes | yes |
| 4 | `Q.*` ( a b -- c ) | yes | yes |
| 5 | `Q./` ( a b -- q ) | yes | yes |
| 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.
- 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
address as a constant (`ROM-UM*` and so on) for the system's source.
- 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.
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
must still be the same on every ISA.
**Births.** A node Hera has born carries the mesh ROM: the fabric's owner attaches it when the
node is made (`v4_node_rom_attach`). The host's assembled system that Hera streams to it then
runs its math in the mesh ROM. Today only the test host makes nodes (`test_host_unit.c`); the
products have no births yet.
**Tests.** Each is written to fail first.
- Each of the six entries, on both ROMs, gives the results today's words give on the same
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
answers.
- Then the whole suite at both widths, POST 538 of 538, and the three QEMU boots, as
`.claude/CLAUDE.md` says.
**Documents.** `DATASHEET-F18.md` lists the entries with each one's stack effect and the
registers it uses (A, B), as section 2.1 asks, and its section 13 item 3 says the mesh ROM is
built.
**Not part of this.**
- A real 1024-word mesh node's memory map, where the ROM's base is not the host's (D-4,
deferred). Until then a mesh node is the host's size, and both ROMs share one base.
- Births in the products, and the name `v4:nucleus-64.f18` that `hera.4th` opens, which only
the test host serves. That is the next correction.
## 3. The boot ## 3. The boot
1. **The machine.** The engine is reset and runs the ROM. 1. **The machine.** The engine is reset and runs the ROM.