feat(v4.0.0): block storage, LOAD and LIST (D-19)
- The golden model's host node gets a block storage device: four memory-mapped registers (number, address, command, status), 1024-byte blocks as 256 cells. tests/test_node.c. - capsule/blocks.v4: BLOCK BUFFER UPDATE SAVE-BUFFERS EMPTY-BUFFERS LIST LOAD SCR BLK (FORTH-79) and v3's FLUSH THRU and -->, over two buffers. - The text being interpreted is at the address in (SRC), which QUERY makes the terminal's buffer and LOAD a block's; LOAD saves and restores it, so blocks nest and the rest of LOAD's line runs afterwards. WORD makes sure a loading block is still in a buffer before it reads. - In a block, \ skips to the next 64-character line. - A block number that does not exist, and --> at the terminal, are errors with messages (D-18). - tests/test_host_quit.c: ten transcripts of the v3 binary; nesting three deep on two buffers; what reaches the device and when. v3's LOAD drops the rest of its line, and v3 has no BLK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0fbe1432b7
commit
c8dc14897c
@@ -92,6 +92,11 @@ typedef struct {
|
||||
v4_cell dstack_reg; /* its word address, or -1 */
|
||||
v4_cell rstack_reg; /* its word address, or -1 */
|
||||
|
||||
/* The block storage device (D-19). See v4_node_storage_attach. */
|
||||
v4_cell storage_reg; /* word address of its four registers, or -1 */
|
||||
unsigned char *storage; /* the blocks, 1024 bytes each */
|
||||
unsigned storage_blocks; /* how many */
|
||||
|
||||
/* NODE-ERROR as a trap (D-18). See v4_node_error_attach. */
|
||||
v4_cell error_reg; /* its word address, or -1 */
|
||||
} v4_node;
|
||||
@@ -238,6 +243,32 @@ void v4_node_fault(v4_node *n, unsigned kind, v4_cell addr);
|
||||
* detaches both (-1); the addresses are the caller's choice (D-4). */
|
||||
void v4_node_stack_regs_attach(v4_node *n, v4_cell d, v4_cell r);
|
||||
|
||||
/* THE BLOCK STORAGE DEVICE (DECOMPOSITION.md D-19, 5.11).
|
||||
*
|
||||
* Mass storage is a device service; until the mesh exists the model stands
|
||||
* in for it on the host node with four memory-mapped registers at `reg`:
|
||||
*
|
||||
* reg + 0 BLOCK-NUMBER which block, 0 .. blocks - 1
|
||||
* reg + 1 BLOCK-ADDRESS word address of 256 cells of node memory
|
||||
* reg + 2 BLOCK-COMMAND a store of 1 reads the block into those cells,
|
||||
* a store of 2 writes it from them
|
||||
* reg + 3 BLOCK-STATUS 0 after a command that worked, -1 after one
|
||||
* that did not: no such block, cells that are
|
||||
* not all in memory, or an unknown command
|
||||
*
|
||||
* The first, second and fourth are memory words the device reads and writes;
|
||||
* only a store to the third does anything. A block is 1024 bytes, and a
|
||||
* byte address is four times a word address plus 0 .. 3 (D-1), so a block
|
||||
* is 256 cells, four bytes to a cell, the first byte lowest, whatever the
|
||||
* cell width: a read leaves the rest of each cell zero, and a write takes
|
||||
* the low 32 bits.
|
||||
*
|
||||
* `bytes` is the caller's: `blocks` * 1024 bytes, which the device reads and
|
||||
* writes and never frees. v4_node_reset detaches it (reg -1). */
|
||||
#define V4_BLOCK_BYTES 1024u
|
||||
#define V4_BLOCK_CELLS 256u
|
||||
void v4_node_storage_attach(v4_node *n, v4_cell reg, unsigned char *bytes, unsigned blocks);
|
||||
|
||||
/* NODE-ERROR as a trap (DECOMPOSITION.md D-18, ruled 2026-10-04: every error
|
||||
* is guarded, shown, and returns the node to its prompt).
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user