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>
78 lines
2.5 KiB
C
78 lines
2.5 KiB
C
/* hosted.c -- StarForth v4 as a Linux program: the nucleus image on the
|
|
* golden model, its capsules loaded as the system comes up (v4/include/v4/
|
|
* boot.h, the same boot the bare-metal kernel runs), the console on stdin
|
|
* and stdout.
|
|
*
|
|
* It runs until its input ends. Blocks are kept in memory and are gone
|
|
* when it stops.
|
|
*/
|
|
#include "v4/boot.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define BLOCKS 64u
|
|
|
|
static v4_node n;
|
|
static v4_exec_state es;
|
|
static v4_heat h;
|
|
static unsigned char disk[BLOCKS * V4_BLOCK_BYTES];
|
|
|
|
static void console_out(const char *text, unsigned len)
|
|
{
|
|
(void)fwrite(text, 1, len, stdout);
|
|
}
|
|
|
|
/* a character for a line that reads the keyboard */
|
|
static int console_key(void)
|
|
{
|
|
int c;
|
|
fflush(stdout);
|
|
c = getchar();
|
|
return c == EOF ? V4_BOOT_KEY_END : c;
|
|
}
|
|
|
|
/* THE KERNEL'S WORDS, for a node that is a Linux program: the words that
|
|
* are C in hosted v3 because only the host can do them. */
|
|
static const char *const kernel_words[] = { "BYE" };
|
|
static int leaving;
|
|
|
|
static void serve(v4_node *node, unsigned request)
|
|
{
|
|
(void)node;
|
|
if (request == 1) { /* BYE ( -- ): as hosted v3, say so and leave */
|
|
fputs("Goodbye!\n", stdout);
|
|
leaving = 1;
|
|
}
|
|
}
|
|
|
|
/* The prompt is the host's, as it is the kernel's REPL's for a v3 VM: read a
|
|
* line, hand it to the node, say how it ended. */
|
|
int main(void)
|
|
{
|
|
static char line[1026];
|
|
v4_boot boot;
|
|
|
|
boot.n = &n; boot.es = &es; boot.h = &h; boot.im = &v4_capsule_image;
|
|
boot.out = console_out; boot.key = console_key;
|
|
boot.words = kernel_words; boot.word_count = sizeof kernel_words / sizeof kernel_words[0]; boot.serve = serve;
|
|
if (!v4_boot_run(&boot, disk, BLOCKS)) { fflush(stdout); return 1; }
|
|
|
|
for (;;) {
|
|
size_t len;
|
|
int how;
|
|
|
|
fputs("ok> ", stdout);
|
|
fflush(stdout);
|
|
if (!fgets(line, sizeof line, stdin)) { putchar('\n'); return 0; }
|
|
len = strlen(line);
|
|
if (len && line[len - 1] == '\n') len--;
|
|
how = v4_boot_line(&boot, line, (unsigned)len);
|
|
if (how == V4_TEXT_COMPLETED) fputs(" ok\n", stdout);
|
|
if (leaving) { fflush(stdout); return 0; }
|
|
else if (how == V4_TEXT_ERROR) fputs(" ERROR\n", stdout);
|
|
else if (how == V4_BOOT_LINE_TOO_LONG) fputs("Line too long\n ERROR\n", stdout);
|
|
else if (how == V4_BOOT_LINE_NO_INPUT) { putchar('\n'); return 0; }
|
|
else if (how == V4_BOOT_LINE_STOPPED) { fflush(stdout); fprintf(stderr, "starforth4: the node stopped on a fault\n"); return 1; }
|
|
}
|
|
}
|