feat(v4): the machine has a ROM -- read and run, never written

A read-only range of V4_ROM_WORDS words at V4_ROM_BASE, above RAM
(MACHINE.md 2, DATASHEET-F18.md 5).  Instruction fetch, @p and data fetches
read it; a running programme's store there is an address fault.  Attached by
the owner like every device; a reset detaches it.  The host node's range is
4096 words.  text.c places branches by the whole address space.  The
nucleus image is byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 11:25:24 -04:00
co-authored by Claude Opus 5.5
parent 42f8a13914
commit 32753f5479
7 changed files with 165 additions and 11 deletions
+18 -2
View File
@@ -4,6 +4,8 @@
void v4_node_reset(v4_node *n)
{
n->rom = NULL; /* attached again by the owner, as every device is */
n->rom_words = 0;
n->p = 0;
n->a = 0;
n->b = 0;
@@ -66,10 +68,24 @@ int v4_node_guards_intact(const v4_node *n)
&& v4_rstack_guards_intact(&n->rs);
}
int v4_node_addr_readable(const v4_node *n, v4_cell addr)
{
return v4_node_addr_ok(addr)
|| ((v4_ucell)addr - (v4_ucell)V4_ROM_BASE) < (v4_ucell)n->rom_words;
}
void v4_node_rom_attach(v4_node *n, const v4_cell *rom, unsigned words)
{
if (!rom || words > V4_ROM_WORDS) { n->rom = NULL; n->rom_words = 0; return; }
n->rom = rom;
n->rom_words = words;
}
v4_cell v4_node_load(const v4_node *n, v4_cell addr)
{
if (!v4_node_addr_ok(addr)) return 0;
return n->mem[(unsigned)addr];
if (v4_node_addr_ok(addr)) return n->mem[(unsigned)addr];
if (v4_node_addr_readable(n, addr)) return n->rom[(v4_ucell)addr - (v4_ucell)V4_ROM_BASE];
return 0;
}
void v4_node_store(v4_node *n, v4_cell addr, v4_cell value)