feat(v4.0.0): a node is sent text as a message and sends back what it prints

MESH.md step 3.  The ports are the transport; the message is what is
transported: to, from, type, heat and TTL, ACL tag, sequence, length, then
text four characters to a word.

- quit.v4: a node with nothing to do is blocked reading "any port"; text
  for it is interpreted; (FINISH) sends what it printed and then how the
  text ended, and it waits again
- core.v4: EMIT keeps what is printed, (FLUSH-OUT) and (HDR) send it to the
  sender on the port the message came on.  EMIT still needs one free data
  cell and no more; it works on the return stack and in A and B
- message.h/.c: the same format for whatever is on a port and is not a node
- boot.c: the boot is the node's console on port 1 and its kernel on port 0
- the prompt tests are a console that speaks messages
- gone: v4_line_begin, v4_line_done, v4_line_status; writing a node's input
  buffer and setting its P from outside; any use of CONSOLE-TX

Verified: make -C v4 test (test_host_quit.c 1283 checks, the full-stack
figures unchanged) and make -C v4 sanitize pass; hosted-check passes on
three ISAs with POST 550 of 550; clean qemu with STARFORTH_V4=1 passes POST
and answers lines typed at each prompt on amd64, aarch64 and riscv64
(logs/20261006-110551, -111621, -111341).  -110837 is an aarch64 run ended
by the test wrapper's limit while still in UEFI firmware; it shows nothing
about v4.

Not done: KEY, EXPECT and QUERY still read the console's input registers;
a message not for this node is let go (step 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-06 11:19:46 -04:00
co-authored by Claude Opus 5.5
parent 42610e844f
commit a041b401ea
24 changed files with 844 additions and 178 deletions
+63
View File
@@ -0,0 +1,63 @@
/* message.h -- a message, as it is written to a port and read from one.
* docs/v4.0.0/MESH.md section 6.
*
* The ports are the transport; the message is what is transported. It is
* v3's Hermes message with what it carries, a word at a time:
*
* word 0 to: the node it is for
* word 1 from: the node that sent it
* word 2 type
* word 3 heat and TTL
* word 4 ACL tag: the sender's identity fingerprint
* word 5 sequence
* word 6 how many characters of text follow, 0 to 1024
* word 7.. the text, four characters to a word, the first lowest
*
* Words 3, 4 and 5 are carried and not yet used: checking them is the
* router's, and awaits rulings (MESH.md section 3).
*
* This is for whatever is on the other end of a node's port and is not a
* node -- a console, a host -- to speak what the nodes speak (v4/capsule/
* core.v4 and quit.v4 are the same thing in the node). Nothing here uses
* the C library.
*/
#ifndef V4_MESSAGE_H
#define V4_MESSAGE_H
#include "v4/cell.h"
#define V4_MSG_HEADER 7u
#define V4_MSG_MAX_CHARS 1024u /* a block */
#define V4_MSG_MAX_WORDS (V4_MSG_HEADER + V4_MSG_MAX_CHARS / 4u)
#define V4_MSG_TEXT 1 /* text to be interpreted */
#define V4_MSG_OUTPUT 2 /* what a node printed */
#define V4_MSG_DONE 3 /* how the text ended: one word, V4_TEXT_* */
/* how text ended */
#define V4_TEXT_QUIT 0 /* QUIT: nothing is to be said */
#define V4_TEXT_COMPLETED 1 /* a console says " ok" */
#define V4_TEXT_ERROR 2 /* the message is printed; a console says " ERROR" */
typedef struct {
v4_cell word[V4_MSG_MAX_WORDS];
unsigned count; /* words in it */
} v4_message;
/* A message of `len` characters, at most V4_MSG_MAX_CHARS. Returns how many
* words it is, or 0 if `len` is too many. */
unsigned v4_message_text(v4_message *m, v4_cell to, v4_cell from, v4_cell type, const char *chars, unsigned len);
/* A message arriving a word at a time. Start with m->count = 0 and give
* each word as it comes: returns 1 when the message is whole, 0 if there is
* more to come. A length that is not 0 to V4_MSG_MAX_CHARS is taken as 0. */
int v4_message_word(v4_message *m, v4_cell word);
/* Its parts. */
#define v4_message_to(m) ((m)->word[0])
#define v4_message_from(m) ((m)->word[1])
#define v4_message_type(m) ((m)->word[2])
unsigned v4_message_length(const v4_message *m); /* characters of text */
char v4_message_char(const v4_message *m, unsigned i); /* the i-th of them */
#endif /* V4_MESSAGE_H */