diff --git a/docs/v4.0.0/ENGINE.md b/docs/v4.0.0/ENGINE.md new file mode 100644 index 00000000..274acecd --- /dev/null +++ b/docs/v4.0.0/ENGINE.md @@ -0,0 +1,179 @@ +# StarForth v4.0.0 — The F18 engine in the VM's place + +Design, 2026-10-05. Written from Captain Bob's rulings of that day +(`V3-PARITY.md` sections 1a to 1h, where each is recorded with its words) +and from v3's code. It replaces the lone-node assumptions of `NUCLEUS.md` +sections 5.3 and 7 to 9. + +## 1. The principle + +`JUSTIFICATION.md` section 16: v4 is equivalent to v3 at any point in time; +"the only difference is the machine underneath: the F18-derived engine +instead of the original StarForth VM." + +Ruled 2026-10-05: v4 is exactly like v3 in functional requirements up to +the first FORTH prompt, and that is the stopping point for now. Nothing is +stubbed, simulated or stood in for. + +So v4 is not a new system beside LithosAnanke. It is LithosAnanke with a +different machine executing its FORTH. + +## 2. What stays, and what is replaced + +**Stays, untouched:** everything the kernel does. The Stadium and each +patron's own accounts; sessions; the switcher; kernel-Hermes; the capsule +directory, birth protocol, hashing, signing and parity; the block +subsystem and its devices; identity and Zuse; the HAL console, Hestia, the +console proxies and the kernel's REPL; the heartbeat; the boot order in +`kernel_main.c`. + +**Replaced:** the part of a v3 VM that executes FORTH. + +| v3 | v4 | +|---|---| +| The inner interpreter (`v3/src/vm.c`, `kernel/src/vm/vm_core.c`) | The node: `v4/src`, 32 opcodes | +| The dictionary as a list of C `DictEntry` records | The dictionary in the node's memory (`v4/capsule/dict.v4`) | +| The FORTH-79 words as C functions (`v3/src/word_source`) | The assembled nucleus (`v4/capsule/*.v4`) and colon definitions in `capsules/v4/forth79.4th` | +| The outer interpreter and compiler in C | The same, in the nucleus | + +A v3 VM is also a record the kernel keeps: its identity, its Stadium ID, +its heartbeat state, its place in the registry, its Zuse flags. That +record stays. What changes is what stands behind it. + +## 3. The interface + +The kernel reaches a VM through a small number of things. Each is listed +with what v3 has, what was ruled, and what a node needs. This is the whole +of the work: when a node answers all of these, the kernel's boot runs on +it as it runs on a v3 VM. + +### 3.1 Interpret this text + +*v3:* `vm_interpret(vm, text)`. The kernel's REPL hands over each line it +has read; `capsule_exec_payload` hands over each line of a capsule; +kernel-Hermes hands over a message's payload when the target drains its +queue. The VM runs the text and returns, with its error flag set or not. + +*Ruled:* the kernel hands a node a whole line and takes characters back; +the node's own prompt loop plays no part at that level. A node receives a +message by being handed its text. + +*v4:* the node has an entry that interprets the text in its input buffer +and then stops, saying how the line ended: completed, ended in an error, +or `QUIT`. It prints no prompt and no ` ok`. The buffer takes 1024 +characters, a block, as v3's does. `QUIT` and `ABORT` end the line and +return to whoever handed it over. `KEY`, `EXPECT` and `QUERY` stay +FORTH-79 words that read characters. + +With this one entry v3's capsule loader, REPL and message drain can all +drive a node, and `v4/system/boot.c`'s own loader is not needed. + +### 3.2 A character out + +*v3:* the host service `putc`, then `console_putc`; the fabric adds +`[user@VM]`. + +*v4:* the node's `EMIT` gives the character to its host, which calls the +same service. Present today. + +### 3.3 Asking the kernel + +*v3:* a kernel word is a C function registered in the VM's dictionary: +`BIRTH`, `KILL`, `USE`, the block words, the Stadium and Hermes words, the +framebuffer words. It takes its arguments from the VM's data stack. + +*Ruled:* a node asks for a block by number and the kernel decides the +rest; a node sends a message by asking. + +*v4:* a kernel word is a dictionary entry on the node whose code hands a +request to the kernel, with its arguments on the node's data stack. The +C functions are v3's. **How the request is carried is not designed yet** +and is the first thing step 2 settles. + +### 3.4 The stacks and the dictionary, from the kernel's side + +*v3:* `vm_push`, `vm_pop`, `vm_find_word`, and the fields of a +`DictEntry` (the kernel pins `BIRTH` and `CAPSULE-BIRTH` by setting two of +them). + +*v4:* the same operations on the node's stacks and on entries in the +node's memory. + +### 3.5 A word is being executed + +*v3:* the inner loop, for every word: the ACL's countdown and recheck, +`execution_heat`, `stadium_word_dispatch`, the rolling window, pipelining. + +*Ruled:* the word card stays exactly as v3 — a run-time check, the TTL +adaptive from the word's own count. Every kind of patron keeps its own +accounts; the word's are as v3. Opcodes are counted and left unwired. + +*v4:* the node dispatches a word at the `call` opcode, one place in the +engine. The node does there what v3's loop does. A word that is to be +checked must be called, so the in-line words that can be called become +calls. + +### 3.6 An error + +*v3:* `vm->error`. *v4:* how a line ended (3.1), and the node's error +register for a C function to raise one. + +### 3.7 A tick + +*v3:* the kernel's timer drives `vm_tick` and the heartbeat state in the +VM's record. *v4:* unchanged; that state is the record's, not the +engine's. + +### 3.8 The dictionary hash + +*v3:* `vm_dict_hash_fn`, a hook the birth protocol calls. *v4:* the same +hook, answered from the node's dictionary. + +## 4. What was built on the detour + +| Built 2026-10-05 | What becomes of it | +|---|---| +| `kernel_main.c` calling `sk_v4_run()` before the fleet tables | Goes at step 4. Until then it is how the bare-metal build is kept booting while the interface is built. | +| `v4/system/boot.c`: its own capsule loader and `PARITY:V4_*` lines | Goes at step 4, when v3's birth protocol loads the capsules and prints v3's parity lines. | +| The node's prompt loop, and the code that strips ` ok` from its output | Goes at step 1. | +| `capsules/v4/forth79.4th`, `post79.4th`, `mkpost.py`, the rules | Stay. POST is the gate for every word moved out of the nucleus. | +| `(CATCH)`, `(EMIT-HOOK)`, `NODE-ERROR` by name | Stay; POST uses them. | +| The per-call-target count (`v4/src/heat.c`, `call[]`) | Goes at step 3, when the node does at `call` what v3 does. | +| The hosted Linux product | Stays, on the same interface. Hosted v3 has no fleet and neither has hosted v4. | + +## 5. Steps + +Each ends with all six builds booting and agreeing, and is committed with +its logs. + +1. **Interpret this text (3.1).** The node's line entry; no prompt loop. + The hosts print the prompt and ` ok`, as v3's REPL does. +2. **Asking the kernel, and the stacks from the kernel's side (3.3, + 3.4).** Settle how a request is carried. Kernel words callable from a + node. +3. **A word is being executed (3.5).** The hook at `call`; the ACL's + countdown and recheck; the word's count; `stadium_word_dispatch`. + In-line words become calls. The per-call-target count goes. +4. **In place.** Under `STARFORTH_V4` the kernel's own boot brings the + node up where it brings a v3 VM up, after the fleet tables; the + kernel's REPL drives it; blocks come from the block subsystem. + `sk_v4_run()` and `boot.c` go. +5. **Hera as v3 has her.** `init.4th` runs on the node; v3's whole POST; + v3's parity lines. +6. **The fleet.** Hestia and Artemis; message delivery; the switcher. +7. **Identity and the prompt.** Zuse; `[zuse@Hera] ok>`. + +Moving words from the assembled nucleus to `forth79.4th` goes on beside +these, a group at a time, with POST after each. + +## 6. Open, and where each must be settled + +| Open | Before | +|---|---| +| How a node's request to the kernel is carried | Step 2 | +| How the node tells a dictionary entry from a bare address at `call` | Step 3 | +| `EXECUTE`, which enters a word by a return | Step 3 | +| `>R R> R@ I J LEAVE`, which cannot be called | Step 3 | +| The node's safe moment for message delivery and switching | Step 6 | +| `PAD 42 OVER !`, a byte address given to `!` (D-1) | Step 5 | +| Which word patrons' accounts the hosted product keeps, having no Stadium | Step 3 |