feat(v4): the ROM assembles the system's .f18 to the nucleus, word for word

capsules/v4/sys: the nucleus's fourteen sources as .f18 blobs (made once by
v4/tools/v4tof18.py: header becomes the ROM's directives, every other token
and line kept), the memory map as map-<width>.f18 (mkmap sys, from one
table in host_map.h that host_load reads too), and end.f18, the switch-on
state mkimage.c set in C, the image record, and start (IDLE).

test_host_rom_nucleus.c: the ROM, fed those blobs through the console,
builds RAM identical word for word to mkimage.c's, outside its own state
and the image record, and starts at (IDLE), at both widths.  The cost:
60.7 million instructions, 1.5 s on the C model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 12:27:50 -04:00
co-authored by Claude Opus 5.5
parent 084c520a54
commit 1bf19d6224
22 changed files with 4058 additions and 117 deletions
+125 -115
View File
@@ -114,7 +114,10 @@
#define ROM_PI (BUF0_W - 122) /* working cells */
#define ROM_RS (BUF0_W - 121)
#define ROM_RN (BUF0_W - 120)
/* FREE, plain memory: BUF0_W - 22 .. - 21; - 119 .. - 113; BUF0_W - 144 .. - 141 (what a flush makes zero after
/* THE IMAGE RECORD: where the system's source says, with `store`, the addresses a host needs (v4/image.h): where the
* node waits for a message, its fault table, and KEY's code. */
#define ROM_IMG (BUF0_W - 119) /* idle, fault table, KEY, the word after KEY: 4 cells */
/* FREE, plain memory: BUF0_W - 22 .. - 21; - 115 .. - 113; BUF0_W - 144 .. - 141 (what a flush makes zero after
* a full output buffer); and OUT_W - 144 .. OUT_W - 65. They and
* the cells above held the messages waiting, the refusals owed and what went with them (MESH.md 7a, 7b), which a
* node no longer keeps. */
@@ -261,6 +264,124 @@ static unsigned host_branch_slots(void)
* assemble the `count` files named. Returns 1 if all assembled; otherwise
* prints which did not and why. The caller may assemble more text and must
* call v4_text_finish. */
/* THE CONSTANTS the system's source is assembled with: names for the addresses and numbers of this map. One
* list, read by host_load (here) and by tools/mkmap.c, which writes it as the system's map blob for the ROM. */
#define HOST_CONSTANTS(X) \
X("N-1", V4_CELL_BITS - 1) \
X("NODE-ERROR", NODE_ERROR) \
X("CONSOLE-TX", CONSOLE_TX) \
X("CONSOLE-RX", CONSOLE_RX) \
X("CONSOLE-STATUS", CONSOLE_ST) \
X("BASE", BASE) \
X("TIB", TIB) \
X(">IN", TO_IN) \
X("SPAN", SPAN) \
X("WBUF", WBUF) \
X("(P)", PVARS) \
X("DP", DP) \
X("(LATEST)", LATEST) \
X("DBASE", DICT_W * 4) \
X("DLIMIT", DICT_END_W * 4) \
X("PAD", PAD) \
X("(D)", DVARS) \
X("(CG)", CGVARS) \
X("CG-BSLOTS", (v4_cell)host_branch_slots()) \
X("STATE", STATE) \
X("(C)", CVARS) \
X("(CFP)", CFP) \
X("(Q)", QVARS) \
X("(F)", FVARS) \
X("(S)", SVARS) \
X("(W)", WVARS) \
X("(X)", XVARS) \
X("(BOOT)", BOOT_CELLS) \
X("(LOG-LEVEL)", LOG_LEVEL) \
X("(ACL-HOOK)", ACL_HOOK) \
X("SCR", SCR) \
X("BLK", BLK) \
X("(SRC)", SRC) \
X("(SRC-HOOK)", SRC_HOOK) \
X("(LINE-STATUS)", LINE_STATUS) \
X("(PORT)", PORT) \
X("(ME)", ME) \
X("(CONSOLE)", CONSOLE) \
X("(ROUTE#)", ROUTE_COUNT) \
X("(ROUTE-DEFAULT)", ROUTE_DEFAULT) \
X("(LOST)", LOST) \
X("(PRINT-TO)", PRINT_TO) \
X("(PRINT-PORT)", PRINT_PORT) \
X("(DONE-PORT)", DONE_PORT) \
X("(ROUTES)", ROUTES) \
X("-PORTS", -(v4_cell)V4_PORTS) \
X("(NEAR)", NEAR) \
X("(AWAIT-FROM)", AWAIT_FROM) \
X("(WIRE)", WIRE) \
X("(WIRE-A)", WIRE_A) \
X("(WIRE-B)", WIRE_B) \
X("(WIRE-DO)", WIRE_DO) \
X("(WIRE-HOW)", WIRE_HOW) \
X("(WIRE-HAVE)", WIRE_HAVE) \
X("(S-HAVE)", S_HAVE) \
X("(S-MASK)", S_MASK) \
X("(S-WIRE)", S_WIRE) \
X("(S-ON)", S_ON) \
X("(KEEP)", KEEP) \
X("(DEFER)", DEFER) \
X("(D-MASK)", D_MASK) \
X("(IN)", IN_HDR) \
X("(ONE)", ONE) \
X("(OUT-HDR)", OUT_HDR) \
X("(W-NEED)", W_NEED) \
X("(W-PORT)", W_PORT) \
X("(P-WAY)", P_WAY) \
X("(P-NEED)", P_NEED) \
X("(H-PORT)", H_PORT) \
X("(H-NEED)", H_NEED) \
X("(H-MASK)", H_MASK) \
X("(A-SELF)", A_SELF) \
X("(SEND^)", SEND_PTR) \
X("(OUT-TEXT)", OUT_TEXT) \
X("(SEND-TEXT)", SEND_TEXT) \
X("(QUIET)", QUIET) \
X("(REFUSED)", REFUSED) \
X("(OUT^)", OUT_PTR) \
X("(REPLY)", REPLY) \
X("(MSG)", MSG) \
X("(OUT)", OUT_W) \
X("(WORD-DEFINED)", WORD_DEFINED) \
X("(WORD-FORGOTTEN)", WORD_FORGOTTEN) \
X("BLOCK#", V4_REQ_BLOCK) /* the kernel's block requests (v4/blocks.h) */ \
X("BUFFER#", V4_REQ_BUFFER) \
X("UPDATE#", V4_REQ_UPDATE) \
X("SAVE-BUFFERS#", V4_REQ_SAVE_BUFFERS) \
X("EMPTY-BUFFERS#", V4_REQ_EMPTY_BUFFERS) \
X("(Q/)", QBASE) /* 5 cells */ \
X("(QE)", QBASE + 5) /* 8 */ \
X("(QR)", QBASE + 13) /* 5 */ \
X("(QL)", QBASE + 18) /* 7 */ \
X("(QT)", QBASE + 25) /* 6 */ \
X("(QP)", QBASE + 31) /* 4 */ \
X("(DP)", QBASE + 35) /* 4 */ \
X("ADDR-DIGITS", V4_CELL_BITS / 4) \
X("MSB", (v4_cell)V4_MSB) \
X("MAXHI", (v4_cell)(V4_MSB - 1u)) \
X("HIMASK", (v4_cell)(((v4_ucell)1 << (V4_CELL_BITS - 16)) - 1u)) \
X("2N+15", 2 * V4_CELL_BITS + 15) \
X("N-18", V4_CELL_BITS - 18) \
X("N-17", V4_CELL_BITS - 17) \
X("MAX-INT", (v4_cell)(V4_MSB - 1u)) \
X("HLD", HLD) \
X("FENCE", FENCE) \
X("CONTEXT", CONTEXT) \
X("CURRENT", CURRENT) \
X("VOC-LINK", VOC_LINK) \
X("HEND", HEND) \
X("-HFLOOR", -(HEND - 62)) \
X("DSTACK-DEPTH", DSTACK_REG) \
X("RSTACK-DEPTH", RSTACK_REG) \
X("CFBASE", CFS_W) \
X("CFEND", CFS_W + CFS_CELLS)
static int host_load(v4_text *tx, v4_node *n, const char *const *files, unsigned count)
{
char path[512];
@@ -269,121 +390,10 @@ static int host_load(v4_text *tx, v4_node *n, const char *const *files, unsigned
v4_node_reset(n);
HOST_MESSAGES_EMPTY(n); /* nothing has been printed and no message waits (core.v4) */
v4_text_begin(tx, n, 16);
v4_text_constant(tx, "N-1", V4_CELL_BITS - 1);
v4_text_constant(tx, "NODE-ERROR", NODE_ERROR);
v4_text_constant(tx, "CONSOLE-TX", CONSOLE_TX);
v4_text_constant(tx, "CONSOLE-RX", CONSOLE_RX);
v4_text_constant(tx, "CONSOLE-STATUS", CONSOLE_ST);
v4_text_constant(tx, "BASE", BASE);
v4_text_constant(tx, "TIB", TIB);
v4_text_constant(tx, ">IN", TO_IN);
v4_text_constant(tx, "SPAN", SPAN);
v4_text_constant(tx, "WBUF", WBUF);
v4_text_constant(tx, "(P)", PVARS);
v4_text_constant(tx, "DP", DP);
v4_text_constant(tx, "(LATEST)", LATEST);
v4_text_constant(tx, "DBASE", DICT_W * 4);
v4_text_constant(tx, "DLIMIT", DICT_END_W * 4);
v4_text_constant(tx, "PAD", PAD);
v4_text_constant(tx, "(D)", DVARS);
v4_text_constant(tx, "(CG)", CGVARS);
v4_text_constant(tx, "CG-BSLOTS", (v4_cell)host_branch_slots());
v4_text_constant(tx, "STATE", STATE);
v4_text_constant(tx, "(C)", CVARS);
v4_text_constant(tx, "(CFP)", CFP);
v4_text_constant(tx, "(Q)", QVARS);
v4_text_constant(tx, "(F)", FVARS);
v4_text_constant(tx, "(S)", SVARS);
v4_text_constant(tx, "(W)", WVARS);
v4_text_constant(tx, "(X)", XVARS);
v4_text_constant(tx, "(BOOT)", BOOT_CELLS);
v4_text_constant(tx, "(LOG-LEVEL)", LOG_LEVEL);
v4_text_constant(tx, "(ACL-HOOK)", ACL_HOOK);
v4_text_constant(tx, "SCR", SCR);
v4_text_constant(tx, "BLK", BLK);
v4_text_constant(tx, "(SRC)", SRC);
v4_text_constant(tx, "(SRC-HOOK)", SRC_HOOK);
v4_text_constant(tx, "(LINE-STATUS)", LINE_STATUS);
v4_text_constant(tx, "(PORT)", PORT);
v4_text_constant(tx, "(ME)", ME);
v4_text_constant(tx, "(CONSOLE)", CONSOLE);
v4_text_constant(tx, "(ROUTE#)", ROUTE_COUNT);
v4_text_constant(tx, "(ROUTE-DEFAULT)", ROUTE_DEFAULT);
v4_text_constant(tx, "(LOST)", LOST);
v4_text_constant(tx, "(PRINT-TO)", PRINT_TO);
v4_text_constant(tx, "(PRINT-PORT)", PRINT_PORT);
v4_text_constant(tx, "(DONE-PORT)", DONE_PORT);
v4_text_constant(tx, "(ROUTES)", ROUTES);
v4_text_constant(tx, "-PORTS", -(v4_cell)V4_PORTS);
v4_text_constant(tx, "(NEAR)", NEAR);
v4_text_constant(tx, "(AWAIT-FROM)", AWAIT_FROM);
v4_text_constant(tx, "(WIRE)", WIRE);
v4_text_constant(tx, "(WIRE-A)", WIRE_A);
v4_text_constant(tx, "(WIRE-B)", WIRE_B);
v4_text_constant(tx, "(WIRE-DO)", WIRE_DO);
v4_text_constant(tx, "(WIRE-HOW)", WIRE_HOW);
v4_text_constant(tx, "(WIRE-HAVE)", WIRE_HAVE);
v4_text_constant(tx, "(S-HAVE)", S_HAVE);
v4_text_constant(tx, "(S-MASK)", S_MASK);
v4_text_constant(tx, "(S-WIRE)", S_WIRE);
v4_text_constant(tx, "(S-ON)", S_ON);
v4_text_constant(tx, "(KEEP)", KEEP);
v4_text_constant(tx, "(DEFER)", DEFER);
v4_text_constant(tx, "(D-MASK)", D_MASK);
v4_text_constant(tx, "(IN)", IN_HDR);
v4_text_constant(tx, "(ONE)", ONE);
v4_text_constant(tx, "(OUT-HDR)", OUT_HDR);
v4_text_constant(tx, "(W-NEED)", W_NEED);
v4_text_constant(tx, "(W-PORT)", W_PORT);
v4_text_constant(tx, "(P-WAY)", P_WAY);
v4_text_constant(tx, "(P-NEED)", P_NEED);
v4_text_constant(tx, "(H-PORT)", H_PORT);
v4_text_constant(tx, "(H-NEED)", H_NEED);
v4_text_constant(tx, "(H-MASK)", H_MASK);
v4_text_constant(tx, "(A-SELF)", A_SELF);
v4_text_constant(tx, "(SEND^)", SEND_PTR);
v4_text_constant(tx, "(OUT-TEXT)", OUT_TEXT);
v4_text_constant(tx, "(SEND-TEXT)", SEND_TEXT);
v4_text_constant(tx, "(QUIET)", QUIET);
v4_text_constant(tx, "(REFUSED)", REFUSED);
v4_text_constant(tx, "(OUT^)", OUT_PTR);
v4_text_constant(tx, "(REPLY)", REPLY);
v4_text_constant(tx, "(MSG)", MSG);
v4_text_constant(tx, "(OUT)", OUT_W);
v4_text_constant(tx, "(WORD-DEFINED)", WORD_DEFINED);
v4_text_constant(tx, "(WORD-FORGOTTEN)", WORD_FORGOTTEN);
v4_text_constant(tx, "BLOCK#", V4_REQ_BLOCK); /* the kernel's block requests (v4/blocks.h) */
v4_text_constant(tx, "BUFFER#", V4_REQ_BUFFER);
v4_text_constant(tx, "UPDATE#", V4_REQ_UPDATE);
v4_text_constant(tx, "SAVE-BUFFERS#", V4_REQ_SAVE_BUFFERS);
v4_text_constant(tx, "EMPTY-BUFFERS#", V4_REQ_EMPTY_BUFFERS);
v4_text_constant(tx, "(Q/)", QBASE); /* 5 cells */
v4_text_constant(tx, "(QE)", QBASE + 5); /* 8 */
v4_text_constant(tx, "(QR)", QBASE + 13); /* 5 */
v4_text_constant(tx, "(QL)", QBASE + 18); /* 7 */
v4_text_constant(tx, "(QT)", QBASE + 25); /* 6 */
v4_text_constant(tx, "(QP)", QBASE + 31); /* 4 */
v4_text_constant(tx, "(DP)", QBASE + 35); /* 4 */
v4_text_constant(tx, "ADDR-DIGITS", V4_CELL_BITS / 4);
v4_text_constant(tx, "MSB", (v4_cell)V4_MSB);
v4_text_constant(tx, "MAXHI", (v4_cell)(V4_MSB - 1u));
v4_text_constant(tx, "HIMASK", (v4_cell)(((v4_ucell)1 << (V4_CELL_BITS - 16)) - 1u));
v4_text_constant(tx, "2N+15", 2 * V4_CELL_BITS + 15);
v4_text_constant(tx, "N-18", V4_CELL_BITS - 18);
v4_text_constant(tx, "N-17", V4_CELL_BITS - 17);
v4_text_constant(tx, "MAX-INT", (v4_cell)(V4_MSB - 1u));
v4_text_constant(tx, "HLD", HLD);
v4_text_constant(tx, "FENCE", FENCE);
v4_text_constant(tx, "CONTEXT", CONTEXT);
v4_text_constant(tx, "CURRENT", CURRENT);
v4_text_constant(tx, "VOC-LINK", VOC_LINK);
v4_text_constant(tx, "HEND", HEND);
v4_text_constant(tx, "-HFLOOR", -(HEND - 62));
v4_text_constant(tx, "DSTACK-DEPTH", DSTACK_REG);
v4_text_constant(tx, "RSTACK-DEPTH", RSTACK_REG);
#define HOST_CONSTANT(name, value) v4_text_constant(tx, name, (v4_cell)(value));
HOST_CONSTANTS(HOST_CONSTANT)
#undef HOST_CONSTANT
v4_node_stack_regs_attach(n, DSTACK_REG, RSTACK_REG);
v4_text_constant(tx, "CFBASE", CFS_W);
v4_text_constant(tx, "CFEND", CFS_W + CFS_CELLS);
for (i = 0; i < count; i++) {
snprintf(path, sizeof path, "%s/%s", V4_CAPSULE_DIR, files[i]);
if (!v4_text_assemble_file(tx, path)) {