feat(v4.0.0): CONSOLE-TX capture register on the single-node model
EMIT is a device service: a character sent to the console node. The mesh and its ports are development step 2 and the memory map is open (D-4), so the single-node model now stands in for the console with one memory-mapped register, so that printing words can be run and their output compared with v3's. v4_node_console_attach(n, addr): after it, a store to word address `addr` appends the low 8 bits of the value to a buffer on the node (V4_CONSOLE_CAP characters, 4096 by default) and does not write memory; a load from `addr` reads the memory word as before. Characters past the capacity are counted in console_dropped and discarded. The hook is in v4_node_store, which all four store opcodes use. It is off by default: v4_node_reset detaches the console (address -1) and empties the capture, so the ISA's behaviour and every existing test are unchanged unless a console is attached. The address is the caller's choice. New test v4/tests/test_console.c, 22 checks per width: direct stores, !b, ! and !+ through the executor printing "Hi!", memory at and around the register untouched, the low byte only, overflow, detach, a console at word 0, and reset. At 32- and 64-bit cells, optimised and ASan+UBSan (`make test`, `make sanitize`); all other v4 tests still pass. Four mutations of the hook each fail. DECOMPOSITION.md section 7 gains the CONSOLE-TX row. No printing word is defined here; EMIT and the words on it are still to do. Test results on the amd64 host only. This is a development check, not acceptance (JUSTIFICATION.md section 16). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7a21f07ad5
commit
7e3932a4ad
@@ -49,6 +49,11 @@
|
||||
* build time, which is why the percentage is a macro and not baked in. */
|
||||
#define V4_MEM_BOUND V4_GUARD_ELEMS(V4_NODE_WORDS)
|
||||
|
||||
/* Characters the console capture holds. Overridable at build time. */
|
||||
#ifndef V4_CONSOLE_CAP
|
||||
#define V4_CONSOLE_CAP 4096u
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
v4_cell p; /* P -- program counter */
|
||||
v4_cell a; /* A -- address register */
|
||||
@@ -60,6 +65,13 @@ typedef struct {
|
||||
v4_cell mem_guard_head[V4_MEM_BOUND];
|
||||
v4_cell mem[V4_NODE_WORDS];
|
||||
v4_cell mem_guard_tail[V4_MEM_BOUND];
|
||||
|
||||
/* CONSOLE-TX capture (DECOMPOSITION.md section 7). See
|
||||
* v4_node_console_attach below. */
|
||||
v4_cell console_tx; /* its word address, or -1: no console */
|
||||
unsigned console_len; /* characters captured */
|
||||
unsigned console_dropped; /* characters that did not fit */
|
||||
unsigned char console[V4_CONSOLE_CAP];
|
||||
} v4_node;
|
||||
|
||||
/* Zero P, A and B, empty the stacks, and clear memory. Installs every
|
||||
@@ -111,4 +123,24 @@ int v4_node_guards_intact(const v4_node *n);
|
||||
v4_cell v4_node_load(const v4_node *n, v4_cell addr);
|
||||
void v4_node_store(v4_node *n, v4_cell addr, v4_cell value);
|
||||
|
||||
/* CONSOLE-TX, the console's transmit register, on the single-node model.
|
||||
*
|
||||
* EMIT is a device service: one character sent to the console node
|
||||
* (DECOMPOSITION.md 5.10). The mesh and its ports are development step 2,
|
||||
* and the memory map is open (D-4), so until then the model stands in for
|
||||
* the console with one memory-mapped register and a capture buffer. That is
|
||||
* enough to run every printing word and compare what it prints with v3.
|
||||
*
|
||||
* After v4_node_console_attach(n, addr), a store to word address `addr`
|
||||
* appends the low 8 bits of the value to n->console instead of writing
|
||||
* memory; n->mem[addr] is never changed by it, and a load from `addr` reads
|
||||
* that memory word as before. All four store opcodes go through
|
||||
* v4_node_store, so all four reach it. Once V4_CONSOLE_CAP characters are
|
||||
* held, further ones are counted in n->console_dropped and discarded.
|
||||
*
|
||||
* A node has no console until one is attached: v4_node_reset detaches it
|
||||
* (console_tx = -1) and empties the capture. Attaching empties it too.
|
||||
* Passing -1 detaches. The address is the caller's choice. */
|
||||
void v4_node_console_attach(v4_node *n, v4_cell addr);
|
||||
|
||||
#endif /* V4_NODE_H */
|
||||
|
||||
Reference in New Issue
Block a user