Commit Graph
8 Commits
Author SHA1 Message Date
rajamesandClaude Opus 5.5 0e761cb117 refactor(v3): the block subsystem's state is a chain there can be two of; blk_subsys_init takes no VM
The global state becomes struct blk_chain, reached through a current
pointer: blk_chain_default, blk_chain_new, blk_chain_select.  Nothing
that uses the one chain changes.  blk_subsys_init loses its VM argument,
which was stored and never used.  docs/v4.0.0/MESH.md 8.4.

Accepted on the v3 configuration: amd64, aarch64 and riscv64 reach the
zuse prompt, no UNKNOWN WORD, PARITY:M7.1a hash 0x08873e0f44b7cb2a on
all three, as on 2026-10-03.  logs/20261006-202918, -203036, -203230.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:33:32 -04:00
rajamesandClaude Opus 5.5 a041b401ea feat(v4.0.0): a node is sent text as a message and sends back what it prints
MESH.md step 3.  The ports are the transport; the message is what is
transported: to, from, type, heat and TTL, ACL tag, sequence, length, then
text four characters to a word.

- quit.v4: a node with nothing to do is blocked reading "any port"; text
  for it is interpreted; (FINISH) sends what it printed and then how the
  text ended, and it waits again
- core.v4: EMIT keeps what is printed, (FLUSH-OUT) and (HDR) send it to the
  sender on the port the message came on.  EMIT still needs one free data
  cell and no more; it works on the return stack and in A and B
- message.h/.c: the same format for whatever is on a port and is not a node
- boot.c: the boot is the node's console on port 1 and its kernel on port 0
- the prompt tests are a console that speaks messages
- gone: v4_line_begin, v4_line_done, v4_line_status; writing a node's input
  buffer and setting its P from outside; any use of CONSOLE-TX

Verified: make -C v4 test (test_host_quit.c 1283 checks, the full-stack
figures unchanged) and make -C v4 sanitize pass; hosted-check passes on
three ISAs with POST 550 of 550; clean qemu with STARFORTH_V4=1 passes POST
and answers lines typed at each prompt on amd64, aarch64 and riscv64
(logs/20261006-110551, -111621, -111341).  -110837 is an aarch64 run ended
by the test wrapper's limit while still in UEFI firmware; it shows nothing
about v4.

Not done: KEY, EXPECT and QUERY still read the console's input registers;
a message not for this node is let go (step 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 11:19:46 -04:00
rajamesandClaude Opus 5.5 42610e844f feat(v4.0.0): the nucleus is a capsule, sent to a node born empty
MESH.md step 2.  A capsule of F18 code is the words a neighbour writes to a
node's port: for each stretch of memory, "@p a! @p push", the address and
count, "@p !+ unext" and the words; then a jump to the start.  A node born
empty executes that from its port, so it needs nothing in it beforehand.

- capsule.h/.c: v4_capsule_write, any node's memory as such a capsule
- mkimage writes the nucleus so, to capsules/v4/nucleus-64.f18, and the
  addresses a host needs as a C file; the memory image is no longer linked
  into either product
- mkcapsule is unchanged: the nucleus capsule is a built file kept under
  capsules/, as BLOCK_MAP.md is, and is baked, hashed and signed with the
  rest
- boot: the node is born empty (v4_image_born); the nucleus capsule is
  found, its hash and signature checked, and given to the node a word at a
  time as it reads its port; PARITY:V4_NUCLEUS carries its name and hash

Verified: test_fabric.c (59 checks, both widths, and under ASan and UBSan):
a memory with a programme and scattered words arrives word for word in an
empty node and runs.  The nucleus capsule rebuilds byte for byte.
hosted-check passes on three ISAs; clean qemu with STARFORTH_V4=1 on amd64,
aarch64 and riscv64 takes the nucleus in, passes POST (550 of 550) and
answers lines typed at each prompt (logs/20261006-102421, -102706,
-103048).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:33:15 -04:00
rajamesandClaude Opus 5.5 9af442f793 feat(v4.0.0): nodes that talk -- ports, a node born empty, and the fabric
MESH.md step 1, in the engine, which knows nothing of StarForth or of any
kernel.

- node: V4_PORTS ports (8), a build parameter; "any port" and the port the
  last such read came from; a read blocks until the neighbour writes, as a
  write blocks until the neighbour reads; v4_node_born: empty, P at "any
  port"
- exec: a fetch from a port -- @ @b @+ @p, or of an instruction word when P
  is a port -- waits for a word; a node executes what arrives at a port
  without advancing P; a blocked node goes on from the slot it stopped at
- fabric: the nodes there are and the table of how their ports are wired,
  both changed while the nodes run; devices on a port; asleep and awake; a
  step is every unblocked node executing one instruction word, then every
  write with a reader waiting being handed over
- DECOMPOSITION.md section 6: four named ports withdrawn for V4_PORTS
  numbered ones and wiring as data, as ruled

Verified: tests/test_fabric.c, 53 checks at both widths: two nodes exchange
words; an empty node is filled through its port by a device, and by another
node, and runs what it was sent; a word is passed on by a node in between;
a waiting node executes nothing; the wiring is changed while they run; a
node is put to sleep, woken and removed while looping; a node is born while
others run; the fabric is given more room.  make -C v4 test and make -C v4
sanitize pass.  The single-node products are unchanged: hosted-check on
three ISAs, and clean qemu with STARFORTH_V4=1 on amd64, aarch64 and
riscv64 with lines typed at each prompt (logs/20261006-074907, -075150,
-075532).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 07:58:00 -04:00
rajamesandClaude Opus 5.5 8df6c16766 feat(v4.0.0): a node asks its kernel by a blocking write to its port
ENGINE.md step 2, the carrier.  Ruled 2026-10-05 (V3-PARITY.md 1i), on
DECOMPOSITION.md section 6: a write to a port blocks until the neighbour
reads.

- node: v4_node_port_attach, v4_node_port_served; a store to the port keeps
  the value as the request and blocks the node
- exec: a blocked node executes nothing; served, it goes on from the opcode
  after the store, in the same instruction word; a fault meanwhile abandons
  the rest of the word
- compile.v4: n KERNEL-WORD name makes a word whose body writes n to the
  port; its arguments and results are on the data stack
- boot: the kernel's words are made by handing the node text, and requests
  are served between the node's opcodes; one no one serves is error 12
- BYE, the first kernel word: hosted it leaves the program, as hosted v3;
  on the lone node it is v3's cold restart
- ENGINE.md 3a: multiuser, multitasking, preemptive and cooperative, and
  what that asks of the engine

Verified: make -C v4 test passes at both widths, with tests/test_port.c;
hosted-check passes on three ISAs; clean qemu with STARFORTH_V4=1 on amd64,
aarch64 and riscv64 passes POST with the same hashes as hosted, and a
kernel word no one serves and BYE typed at each prompt are answered
(logs/20261005-185506, -185734, -190101; -185234 is an amd64 run in which
those two lines were not typed).

Not done: v3's own C functions serving a node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 19:03:03 -04:00
rajamesandClaude Opus 5.5 01c447f9ab feat(v4.0.0): a node is handed a line -- ENGINE.md step 1
A v4 node no longer reads its own command line or prints a prompt.  Its
host puts a line of text in the node's input buffer and starts it at
(LINE); the node interprets it and stops at (IDLE), leaving in
(LINE-STATUS) how it ended: completed, an error, or QUIT.  The host says
" ok" or " ERROR" and prompts, as the kernel's REPL does for a v3 VM.  A
line may be 1024 characters, a block, as v3's.  Ruled 2026-10-05
(V3-PARITY.md 1b); design ENGINE.md 3.1.

- quit.v4: (REPL), the node's prompt loop, is gone; (LINE) (IDLE) (DONE)
- image.h/.c: v4_line_begin, v4_line_done, v4_line_status; the node is
  idle at switch-on
- boot.c: v4_boot_line, the one loop the hosted binary, the kernel and the
  capsule loader hand a line with; the code that took " ok" and the prompt
  back out of the node's output is gone
- hosted.c, sk_v4.c: the prompt and the line editing are the host's
- test_host_quit.c: the tests are the node's host; two tests of the old
  80-character prompt line now test a whole line, 1024 and 1025 characters

Verified: make -C v4 test passes at both widths; hosted-check passes on
three ISAs; clean qemu with STARFORTH_V4=1 on amd64, aarch64 and riscv64
passes POST (550 of 550) with the same hashes as hosted, and three lines
typed at each bare-metal prompt through the serial port are answered
correctly (logs/20261005-180922, -181152, -181541).

Still the lone node: kernel_main.c starts it before the fleet tables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:17:37 -04:00
rajamesandClaude Opus 5.5 294e69463a feat(v4.0.0): the system boots from a nucleus and loads its capsules
One boot, v4/system/boot.c, for both products: it starts the nucleus image,
finds each capsule in the baked capsule directory, recomputes its hash,
checks its signature, gives its blocks to the node a line at a time, and
prints PARITY:V4_NUCLEUS, PARITY:V4_CAPSULE and PARITY:OK before the prompt.
A line the node does not accept ends the boot with the capsule, block and
line named.  docs/v4.0.0/NUCLEUS.md.

- hosted Linux product for amd64, aarch64 and riscv64 (make -C v4 hosted);
  make -C v4 hosted-check boots all three and requires identical output
- the kernel's v4 entry (STARFORTH_V4=1) calls the same boot
- capsules/v4/forth79.4th, block 6000: no definitions yet
- mkimage builds the nucleus only; no FORTH source is compiled at build time
- capsule_blocks.c: the Block-header parse, free of any VM, for every loader

Verified: make -C v4 test passes; hosted-check passes on the three ISAs with
the same hashes; the kernel compiles with STARFORTH_V4=1 on the three.
Not verified: no bare-metal boot of v4 has been run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:28:30 -04:00
rajamesandJunie a8b70e88d3 Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure
Source tree reorganization:
- Move StarForth v3 engine to v3/ (src/, include/, Makefile)
- Move kernel to kernel/ (src/, include/, linker/, Makefile)
- Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md)
- Move FABRIC-0..4.md to docs/fabric/
- Move ONTOLOGY.md and ROADMAP.md to docs/

Board infrastructure:
- Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/
- Each board has board.mk (ISA, CPU flags, boot recipe) and README.md
- Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET
- make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board
- ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet)
- scripts/mkdiskimage.sh builds disk images for all boards

Docs pipeline:
- docs/book/ with LaTeX master (main.tex) and Makefile
- pandoc converts Markdown to LaTeX at build time
- Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks)
- make docs builds single PDF (754 pages, 0 missing characters)
- make docs TARGET=<board> adds board appendix
- build/docs/<book|board>/meta.tex stamps git commit into PDF

Bug fixes:
- 42 include paths that only worked by accident now use correct relative paths
- clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build)
- Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved
- Doxyfile, .clang-tidy, README.md, Kconfig paths updated

Verified:
- Hosted v3 build passes 1012 tests, 0 failures
- SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE)
- Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes
- make clean TARGET=<board> removes only that board and its ISA objects
- make all builds all boards, hosted v3, and docs in one run

Co-authored-by: Junie <junie@jetbrains.com>
2026-10-01 15:40:09 -04:00