ENGINE step 4 Phase 2 (plan docs/v4.0.0/plans/2026-11-13-engine-step4-phase2-word-accounts.md). Rulings, Captain Bob 2026-11-13: "ID field in the header"; "Per heartbeat tick"; the ACL "All of it in Phase 4". - The word ID, at xt-4 before the flags (ENGINE.md 3b). The system's words are numbered as they are assembled, by a new directive, #id, (and #ids, the count), in the C assembler (text.c) and in the machine ROM's (capsules/v4/rom), which counts in the system's own (NEXT-ID). (HEADER) numbers later words; FORGET gives back the IDs it frees, always the newest; COLD resets to (BOOT-ID); (SEAL) records it. All 313 system headers carry the cell. - The kernel's records (v4/mesh.h): (TELL-DEFINED) and (TELL-FORGOTTEN), requests -19/-20 on port 0, which the kernel puts in (WORD-DEFINED)/(WORD-FORGOTTEN) when it seals a node, and reads the system's own words once. A bit per address marks a word's xt (calls into the ROM or headerless code are not words); at call, the bit test and a count. v4_mesh_charge hands the owner the calls since. - The Stadium: stadium_words_charge -- N calls as N of stadium_word_dispatch's dispatches, shared by calls when the reservoir is short; sk_v4.c charges every node's words at the tick beside its opcodes, and stadium_word_forget before an ID is used again. - Tests first: test_text.c, test_host_dict.c, test_host_quit.c (numbering, FORGET, COLD), test_mesh_boot.c (44 checks), kernel/tests/test_stadium_words.c; qemu_session.py: Hera's words admitted after POST. - amd64: Stadium words: promotions=141 after POST, CONSERVED; POST 539/539; word_count=377; dict_hash 0xa854ba15b437d288 (the new cell); the boot 142 s against Phase 1's 153 s. - v4 test, test-32: all pass; v4-checks: 80 programs under the sanitizers, 0 failures; the hosted builds alike. docs/reference/v4-dictionary.tsv: the two new words; FABRIC-3 XLVIII.24. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
176 lines
7.9 KiB
C
176 lines
7.9 KiB
C
/* SPDX-License-Identifier: LicenseRef-Starship-1.0
|
|
* Copyright (c) 2023-2026 Robert A. James
|
|
*/
|
|
/* mkmap.c -- the memory map, as constants the ROM is assembled with.
|
|
*
|
|
* mkmap > rom-map-<width>.f18
|
|
* mkmap sys > capsules/v4/sys/map-<width>.f18
|
|
* mkmap image > v4_map_<width>.c
|
|
*
|
|
* Runs on the build machine, built for the host node (HOST_WORDS and the
|
|
* host stack sizes) at one cell width. It writes, as `constant` lines in
|
|
* the text assembler's notation, the addresses and codes of
|
|
* v4/tests/host_map.h that the ROM's source (capsules/v4/rom) uses: the
|
|
* console's receive registers, the ROM's state area (MACHINE.md 2.1), the
|
|
* math's constants and its shared entries (MACHINE.md 2.2).
|
|
* The map has one source, host_map.h; this is how the ROM reads it.
|
|
*/
|
|
#include "../tests/host_map.h"
|
|
#include "../include/v4/rom_entries.h"
|
|
#include <stdio.h>
|
|
|
|
static void constant(const char *name, long value)
|
|
{
|
|
printf("constant %s %ld\n", name, value);
|
|
}
|
|
|
|
/* `mkmap sys`: the system's map, the blob the ROM reads before the system's
|
|
* source (capsules/v4/sys/map-<width>.f18): every constant host_load gives
|
|
* the nucleus, and the two its end (capsules/v4/sys/end.f18) needs besides. */
|
|
static int system_map(void)
|
|
{
|
|
printf("\\ map-%d.f18 -- the memory map the system's source is assembled with, %d-bit cells.\n", V4_CELL_BITS, V4_CELL_BITS);
|
|
printf("\\ Generated by v4/tools/mkmap.c (mkmap sys) from v4/tests/host_map.h -- do not edit.\n");
|
|
#define SYS_CONSTANT(name, value) constant(name, (long)(v4_cell)(value));
|
|
HOST_CONSTANTS(SYS_CONSTANT)
|
|
#undef SYS_CONSTANT
|
|
#define SYS_ROM_ENTRY(i, routine, forth, effect) constant("ROM-" forth, (long)(V4_ROM_BASE + (v4_cell)(i)));
|
|
V4_ROM_MATH_ENTRIES(SYS_ROM_ENTRY)
|
|
#undef SYS_ROM_ENTRY
|
|
constant("DICT-W", (long)DICT_W);
|
|
constant("(IMG)", (long)ROM_IMG);
|
|
return 0;
|
|
}
|
|
|
|
/* `mkmap image`: the system as its host knows it before it is built
|
|
* (include/v4/image.h, v4_map_image): what the build was for, the map's
|
|
* addresses, and where the image record and the ROM's error are. What only
|
|
* the assembled system knows -- where it waits, its fault table, KEY -- is
|
|
* -1 here; v4_image_from_node reads it from the image record. */
|
|
static int image_description(void)
|
|
{
|
|
printf("/* Generated by v4/tools/mkmap.c (mkmap image) from v4/tests/host_map.h -- do not edit. */\n");
|
|
printf("#include \"v4/image.h\"\n\nconst v4_image v4_map_image = {\n");
|
|
printf(" %uu, %uu, %uu, %uu,\n", (unsigned)V4_CELL_BITS, (unsigned)V4_NODE_WORDS, (unsigned)V4_DATA_RING, (unsigned)V4_RET_RING);
|
|
printf(" -1,\n -1, %ld,\n -1, -1,\n", (long)PORT);
|
|
printf(" %ld, %ld, %ld,\n %ld, %ld,\n %ld,\n %ld, %ld,\n %ld, %ld,\n %ld, %ld,\n %ld, %ld,\n %ld, %ld,\n %ld,\n",
|
|
(long)CONSOLE_TX, (long)CONSOLE_RX, (long)CONSOLE_ST, (long)DSTACK_REG, (long)RSTACK_REG,
|
|
(long)NODE_ERROR, (long)HEAT_REG, (long)ME, (long)DP, (long)LATEST, (long)BOOT_CELLS, (long)FENCE,
|
|
(long)NEXT_ID, (long)BOOT_ID, (long)WORD_DEFINED, (long)WORD_FORGOTTEN, (long)BUF0_W);
|
|
printf(" %ld, %ld, %ld\n};\n", (long)ROM_IMG, (long)ROM_FAILED, (long)ROM_ERRLINE);
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
(void)host_load; /* host_map.h's loader is not this tool's */
|
|
(void)host_branch_slots;
|
|
if (argc == 2 && argv[1][0] == 's') return system_map();
|
|
if (argc == 2 && argv[1][0] == 'i') return image_description();
|
|
printf("\\ Generated by v4/tools/mkmap.c from v4/tests/host_map.h -- do not edit.\n");
|
|
constant("CONSOLE-RX", (long)CONSOLE_RX);
|
|
constant("CONSOLE-STATUS", (long)CONSOLE_ST);
|
|
constant("(TOK)", (long)ROM_TOK);
|
|
constant("(TOKN)", (long)ROM_TOKN);
|
|
constant("(PEEK)", (long)ROM_PEEK);
|
|
constant("(LINE)", (long)ROM_LINE);
|
|
constant("(EOF)", (long)ROM_EOF);
|
|
constant("(FAILED)", (long)ROM_FAILED);
|
|
constant("(ERRLINE)", (long)ROM_ERRLINE);
|
|
constant("(NBASE)", (long)ROM_NBASE);
|
|
constant("(NNEG)", (long)ROM_NNEG);
|
|
constant("(NI)", (long)ROM_NI);
|
|
constant("(NU)", (long)ROM_NU);
|
|
constant("(NBIG)", (long)ROM_NBIG);
|
|
constant("(RECN)", (long)ROM_RECN);
|
|
constant("(POOLN)", (long)ROM_POOLN);
|
|
constant("(REC)", (long)ROM_REC);
|
|
constant("(CNT)", (long)ROM_CNT);
|
|
constant("(PTR)", (long)ROM_PTR);
|
|
constant("(I)", (long)ROM_I);
|
|
constant("(WI)", (long)ROM_WI);
|
|
constant("(SYMH)", (long)ROM_SYMH);
|
|
constant("SYMREC", (long)ROM_SYMREC);
|
|
constant("POOLTOP", (long)ROM_POOLTOP);
|
|
{
|
|
/* the ROM's error codes, ERR-TOO-LONG ... (v4/rom_errors.h) */
|
|
static const struct { const char *name; long code; } errs[] = {
|
|
#define ROM_ERR_CONST_(name, code, text) { #name, code },
|
|
V4_ROM_ERRORS(ROM_ERR_CONST_)
|
|
#undef ROM_ERR_CONST_
|
|
};
|
|
unsigned e, c;
|
|
for (e = 0; e < sizeof errs / sizeof errs[0]; e++) {
|
|
char n[40] = "ERR-";
|
|
for (c = 0; errs[e].name[c] && c < sizeof n - 5u; c++) n[4 + c] = errs[e].name[c] == '_' ? '-' : errs[e].name[c];
|
|
n[4 + c] = 0;
|
|
constant(n, errs[e].code);
|
|
}
|
|
}
|
|
constant("(HERE)", (long)ROM_HERE);
|
|
constant("NEXT-ID-W", (long)NEXT_ID); /* the system's (NEXT-ID): where #id, counts (#189, Phase 2) */
|
|
constant("(CUR)", (long)ROM_CUR);
|
|
constant("(SLOT)", (long)ROM_SLOT);
|
|
constant("(NLIT)", (long)ROM_NLIT);
|
|
constant("(LITS)", (long)ROM_LITS);
|
|
constant("(PI)", (long)ROM_PI);
|
|
constant("(RS)", (long)ROM_RS);
|
|
constant("(RN)", (long)ROM_RN);
|
|
constant("RAM-WORDS", (long)V4_NODE_WORDS);
|
|
constant("ADDR-TOP", (long)ROM_ADDR_TOP);
|
|
constant("(NREF)", (long)ROM_NREF);
|
|
constant("(NLAB)", (long)ROM_NLAB);
|
|
constant("(WNP)", (long)ROM_WNP);
|
|
constant("(NFOR)", (long)ROM_NFOR);
|
|
constant("(FORS)", (long)ROM_FORS);
|
|
constant("(RDEPTH)", (long)ROM_RDEPTH);
|
|
constant("(RPTRS)", (long)ROM_RPTRS);
|
|
constant("(T1)", (long)ROM_T1);
|
|
constant("(T2)", (long)ROM_T2);
|
|
constant("(T3)", (long)ROM_T3);
|
|
constant("(T4)", (long)ROM_T4);
|
|
constant("(CFROM)", (long)ROM_CFROM);
|
|
constant("(CTO)", (long)ROM_CTO);
|
|
constant("(CN)", (long)ROM_CN);
|
|
constant("(RAW)", (long)ROM_RAW);
|
|
constant("(T5)", (long)ROM_T5);
|
|
constant("(T6)", (long)ROM_T6);
|
|
constant("(MLEN)", (long)ROM_MLEN);
|
|
constant("(REFS)", (long)ROM_REFS);
|
|
constant("(LABELS)", (long)ROM_LABELS);
|
|
constant("(WNAMES)", (long)ROM_WNAMES);
|
|
constant("(TSAVE)", (long)ROM_TSAVE);
|
|
constant("(MTEMP)", (long)ROM_MTEMP);
|
|
constant("(MBODY)", (long)ROM_MBODY);
|
|
constant("ORIGIN", (long)ROM_ORIGIN);
|
|
constant("REFS-MAX", (long)ROM_REFS_MAX);
|
|
constant("WN-SIZE", (long)ROM_WN_SIZE);
|
|
constant("MBODY-SIZE", (long)ROM_MBODY_SIZE);
|
|
constant("DICT-W", (long)DICT_W);
|
|
constant("DICT-END", (long)DICT_END_W);
|
|
constant("BUF0", (long)BUF0_W);
|
|
constant("TIB-W", (long)TIB_W);
|
|
constant("DSTACK-REG", (long)DSTACK_REG);
|
|
constant("RSTACK-REG", (long)RSTACK_REG);
|
|
/* the cell width's constants (NUMBER) needs, written as signed cells */
|
|
constant("MSB", (long)(v4_cell)V4_MSB);
|
|
constant("DEC-LIMIT", (long)(v4_cell)(~(v4_ucell)0 / 10u));
|
|
constant("DEC-NLAST", -(long)(~(v4_ucell)0 % 10u) - 1);
|
|
constant("HEX-HIGH", (long)(v4_cell)~(~(v4_ucell)0 >> 4));
|
|
/* the math's constants (capsules/v4/rom/math.f18) */
|
|
constant("N-1", (long)(V4_CELL_BITS - 1));
|
|
constant("NODE-ERROR", (long)NODE_ERROR);
|
|
constant("(Q/)", (long)QBASE);
|
|
constant("MAXHI", (long)(v4_cell)(V4_MSB - 1u));
|
|
constant("2N+15", (long)(2 * V4_CELL_BITS + 15));
|
|
constant("N-18", (long)(V4_CELL_BITS - 18));
|
|
constant("N-17", (long)(V4_CELL_BITS - 17));
|
|
/* the shared entries, the start of both ROMs' tables (v4/rom_entries.h) */
|
|
printf("macro (MATH-ENTRIES)");
|
|
#define MATH_ENTRY_JUMP(i, routine, forth, effect) printf(" jump %s", routine);
|
|
V4_ROM_MATH_ENTRIES(MATH_ENTRY_JUMP)
|
|
#undef MATH_ENTRY_JUMP
|
|
printf(" endmacro\n");
|
|
return 0;
|
|
}
|