Files
LithosAnanke/v4/include/v4/image.h
T
rajamesandClaude Opus 5.5 9bfd5071d2 feat(v4.0.0): the block words are the kernel's -- v3's way in full
Ruled 2026-10-07.  BLOCK, BUFFER, UPDATE, SAVE-BUFFERS and EMPTY-BUFFERS
are each one kernel request on port 0, by block number only.  The node
has a window of four slots in its memory, as a v3 VM has; the kernel
copies blocks into it, keeps the record of which block is in which slot,
and decides when a block is written (v4/system/blocks.c).  The node keeps
no record and gives the kernel no address, so a request cannot overwrite
the node's code.  When a block is written stays FORTH-79's: UPDATE marks
it.  When the chain of devices changes the slots are let go, as in v3.

The window is 512 cells more than the two buffers were; the dictionary
space ends that much lower, at 13824.

MESH.md 8.5 had said, from the review, that a v3 VM's BLOCK is the
kernel's buffer.  It is not, and the section now says what was reported,
what v3 does, and what was ruled.

make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and
riscv64 boot, POST 538 of 538, the same hashes on all six:
logs/20261007-092835, -093112, -093456.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:37:30 -04:00

89 lines
3.8 KiB
C

/* image.h -- the StarForth nucleus, as its host knows it: where things are
* in a node that has taken it in, and how a line is handed to that node.
*
* The nucleus is text (capsule/ *.v4). tools/mkimage.c assembles it on the
* build machine and writes two things:
*
* - the nucleus as a capsule of F18 code (capsule.h), which is put into
* an empty node through its port. It is a capsule like any other: in
* the capsule directory, with a name, a hash and a signature
* (capsules/v4/nucleus-<width>.f18). docs/v4.0.0/MESH.md section 5.
* - this description of it, a C file: the addresses a host needs.
*
* A node that has taken the nucleus in is sent text as messages and sends
* back what it prints (v4/include/v4/message.h); nothing here hands it a
* line.
*
* A description is for one cell width, one node size and one pair of stack
* sizes; v4_image_born refuses one the engine was not built for.
*/
#ifndef V4_IMAGE_H
#define V4_IMAGE_H
#include "v4/exec.h"
typedef struct {
/* what the image was built for */
unsigned cell_bits, node_words, data_ring, ret_ring;
/* Where the nucleus waits for a message (v4/capsule/quit.v4, (IDLE)):
* the node's P is there, blocked reading its ports, when it has nothing
* to do. */
v4_cell idle;
v4_cell fault_table; /* (FAULTS): where a fault goes */
v4_cell port; /* word address of the node's port (node.h) */
/* KEY's code: a node whose P is in key_start .. key_end - 1 with no
* character pending is waiting for one */
v4_cell key_start, key_end;
/* the memory-mapped registers (DECOMPOSITION.md section 7; D-4 leaves
* the map to the loader, and this is the map the image was built with) */
v4_cell console_tx, console_rx, console_status;
v4_cell dstack_reg, rstack_reg;
v4_cell node_error;
/* the dictionary's two variables: DP holds HERE, a byte address, and
* LATEST the newest word of FORTH. What lies below HERE, and LATEST,
* is what the dictionary hash covers (v4/include/v4/boot.h). */
v4_cell dp, latest;
/* What COLD returns the system to and FORGET will not go below: two
* cells, DP and LATEST as they were when the system was complete, and
* the variable FENCE. The image has them as the nucleus alone; a system
* that loads capsules when it boots sets them again when it has
* (v4_image_seal). */
v4_cell boot_cells, fence;
/* the block window: the word address of the slots the kernel copies
* blocks into (v4/blocks.h) */
v4_cell block_window;
} v4_image;
/* The description of the nucleus built from v4/capsule (the generated file
* defines it). */
extern const v4_image v4_capsule_image;
/* The system is complete: what is in the dictionary now is what COLD comes
* back to, and FORGET will not go below it. */
void v4_image_seal(v4_node *n, const v4_image *im);
/* The dictionary hash of a node started from `im`: FNV-1a over its memory
* below HERE, a cell at a time, low byte first, and then LATEST. It does
* not depend on the machine: every build of one commit, with one cell
* width, gives the same hash for the same dictionary. */
uint64_t v4_image_dict_hash(const v4_node *n, const v4_image *im);
/* A node newly born (node.h), with the registers the nucleus expects of the
* node it runs on. Its memory is empty and it is blocked
* reading its ports: the nucleus is yet to be sent to it. Returns 1, or 0
* if the description is not for this build of the engine (nothing is then
* done). */
int v4_image_born(v4_node *n, v4_exec_state *es, v4_heat *h, const v4_image *im);
/* 1 if the node is waiting for a character: it is inside KEY and none is
* pending. */
int v4_image_waiting(const v4_node *n, const v4_image *im);
#endif /* V4_IMAGE_H */