capsules/v4/sys: the nucleus's fourteen sources as .f18 blobs (made once by v4/tools/v4tof18.py: header becomes the ROM's directives, every other token and line kept), the memory map as map-<width>.f18 (mkmap sys, from one table in host_map.h that host_load reads too), and end.f18, the switch-on state mkimage.c set in C, the image record, and start (IDLE). test_host_rom_nucleus.c: the ROM, fed those blobs through the console, builds RAM identical word for word to mkimage.c's, outside its own state and the image record, and starts at (IDLE), at both widths. The cost: 60.7 million instructions, 1.5 s on the C model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
414 lines
24 KiB
C
414 lines
24 KiB
C
/* host_map.h -- the memory map the host-node tests give the compiler capsule,
|
|
* and the loader that assembles it.
|
|
*
|
|
* The node's memory map is open (DECOMPOSITION.md D-4), so the tests choose
|
|
* one. Every test_host_*.c uses this one, so that the capsule's variables
|
|
* and buffers are in the same place in all of them:
|
|
*
|
|
* 16 .. the capsule's code, assembled from capsule/ *.v4
|
|
* DICT_W .. DICT_END_W dictionary space for what is defined at run time
|
|
* top of memory buffers, then variables, as below
|
|
*/
|
|
#ifndef V4_TESTS_HOST_MAP_H
|
|
#define V4_TESTS_HOST_MAP_H
|
|
|
|
#include "v4/blocks.h"
|
|
#include "v4/text.h"
|
|
#include <stdio.h>
|
|
|
|
#define TOP ((v4_cell)V4_NODE_WORDS)
|
|
|
|
/* registers and single variables */
|
|
#define NODE_ERROR (TOP - 2)
|
|
#define CONSOLE_TX (TOP - 4)
|
|
#define CONSOLE_RX (TOP - 6)
|
|
#define CONSOLE_ST (TOP - 7)
|
|
#define BASE (TOP - 8)
|
|
#define TO_IN (TOP - 9)
|
|
#define SPAN (TOP - 10)
|
|
#define DP (TOP - 11)
|
|
#define LATEST (TOP - 12)
|
|
#define STATE (TOP - 13)
|
|
#define CFP (TOP - 14) /* the control-flow stack's pointer */
|
|
#define DSTACK_REG (TOP - 15) /* DSTACK-DEPTH (D-16) */
|
|
#define RSTACK_REG (TOP - 16) /* RSTACK-DEPTH */
|
|
|
|
/* each capsule file's scratch cells */
|
|
#define PVARS (TOP - 24) /* (P): input.v4, 8 cells */
|
|
#define DVARS (TOP - 32) /* (D): dict.v4, 5 cells */
|
|
#define CGVARS (TOP - 48) /* (CG): codegen.v4, 14 cells */
|
|
#define CVARS (TOP - 62) /* (C): compile.v4, 10 cells */
|
|
#define FVARS (TOP - 105) /* (F): forth.v4, 7 cells */
|
|
#define SVARS (TOP - 540 - (v4_cell)V4_DATA_DEPTH) /* (S): where PICK and ROLL set stack values aside, one cell for each cell of the stack */
|
|
#define WVARS (TOP - 99) /* (W): numout.v4, 3 cells */
|
|
#define CONTEXT (TOP - 64) /* the vocabulary names are looked up in */
|
|
#define CURRENT (TOP - 63) /* the vocabulary new words go into */
|
|
#define VOC_LINK (TOP - 50) /* the newest vocabulary */
|
|
#define FENCE (TOP - 26) /* FORGET's lower limit */
|
|
#define HLD (TOP - 25) /* where the pictured number has got to */
|
|
|
|
/* buffers (word addresses; a byte address is four times this) */
|
|
#define CFS_W (TOP - 96) /* the control-flow stack, 32 cells */
|
|
#define CFS_CELLS 32
|
|
#define WBUF_W (TOP - 170) /* WORD's buffer: 65 cells = 260 bytes */
|
|
#define WBUF_CELLS 65
|
|
#define TIB_W (TOP - 440) /* the text input buffer: 260 cells = 1040 bytes; a line is at most 1024 */
|
|
#define PAD_W (TOP - 470) /* PAD: 21 cells = 84 bytes */
|
|
#define SBUF_W (TOP - 540) /* 64 cells for the tests' own strings */
|
|
#define HBUF_W (SVARS - 16) /* the hold buffer: 16 cells = 64 bytes */
|
|
#define HEND ((HBUF_W + 16) * 4)
|
|
#define XVARS (HBUF_W - 4) /* (X): words.v4, 4 cells */
|
|
#define QBASE (XVARS - 40) /* the Q words' and DUMP's scratch cells, 39 in all */
|
|
#define BVARS (QBASE - 16) /* blocks.v4: 6 cells not used now, then SCR BLK (SRC) (SRC-HOOK) */
|
|
#define SCR (BVARS + 6)
|
|
#define BLK (BVARS + 7)
|
|
#define SRC (BVARS + 8)
|
|
#define SRC_HOOK (BVARS + 9)
|
|
#define QUIET (BUF0_W - 10) /* 1 while the node does something that is no text's doing: an error then is not told (quit.v4, (RAISED)) */
|
|
#define REFUSED (BUF0_W - 7) /* how many of this node's messages it has been told were refused */
|
|
#define ACL_HOOK (BUF0_W - 6) /* the xt of the access control recheck word, or 0 */
|
|
#define LINE_STATUS (BUF0_W - 9) /* how the last line ended: 0 QUIT, 1 completed, 2 an error */
|
|
#define PORT (BUF0_W - 140) /* the node's ports (node.h): V4_PORTS of them, then "any port", "which port" and the rest as far as V4_PORT_HAVE. Port 0 is where its requests go. */
|
|
#define CONSOLE (BUF0_W - 16) /* the node what this one prints is sent to; 0: whoever sent the text being served */
|
|
#define ROUTE_COUNT (BUF0_W - 17) /* how many entries the table of ways holds */
|
|
#define ROUTE_DEFAULT (BUF0_W - 18) /* the port address for a node not in the table, or 0: there is none */
|
|
#define LOST (BUF0_W - 19) /* how many messages have been let go for want of a way */
|
|
#define PRINT_TO (BUF0_W - 20) /* where what the text being served prints is to go: the node, */
|
|
#define PRINT_PORT (BUF0_W - 33) /* and the port, by its number, that leads there */
|
|
#define DONE_PORT (BUF0_W - 34) /* the port, by its number, that leads back to whoever sent the text being served */
|
|
/* WHOLE MESSAGES (MESH.md 7d.4; core.v4). A node keeps no message but the one it is doing: these are what it
|
|
* builds one in and looks at one with, and where it has got to in going through its wires. */
|
|
#define WIRE (PORT + (v4_cell)V4_PORT_WIRE) /* the six addresses after the ports (node.h): the wire an operation is about, */
|
|
#define WIRE_A (PORT + (v4_cell)V4_PORT_A) /* what it needs, */
|
|
#define WIRE_B (PORT + (v4_cell)V4_PORT_B)
|
|
#define WIRE_DO (PORT + (v4_cell)V4_PORT_DO) /* the operation, */
|
|
#define WIRE_HOW (PORT + (v4_cell)V4_PORT_HOW) /* how it went, */
|
|
#define WIRE_HAVE (PORT + (v4_cell)V4_PORT_HAVE) /* and which wires have a message */
|
|
#define S_HAVE (BUF0_W - 35) /* which wires had a message when the node last asked, */
|
|
#define S_MASK (BUF0_W - 36) /* those of them still to be gone through, */
|
|
#define S_WIRE (BUF0_W - 37) /* the one being gone through, */
|
|
#define S_ON (BUF0_W - 38) /* and whether its mark has been put at its first message */
|
|
#define KEEP (BUF0_W - 40) /* the port the answer to the text being done goes by, on whose wire 8 cells are kept for it; -1: none */
|
|
#define DEFER (BUF0_W - 41) /* a port whose wire had no room for the answer to text that waits to be begun; -1: none */
|
|
#define D_MASK (BUF0_W - 8) /* and a bit for each such port: text whose answer goes by one is not begun on this pass */
|
|
#define IN_HDR (BUF0_W - 56) /* the seven words of the message a wire's mark is at */
|
|
#define ONE (BUF0_W - 49) /* the one word of text of a NACK, a GONE or an answer, coming or going */
|
|
#define OUT_HDR (BUF0_W - 112) /* the seven words of a message this node is putting on a wire */
|
|
#define W_NEED (BUF0_W - 105) /* the wait for room: how many cells, */
|
|
#define W_PORT (BUF0_W - 104) /* and on which port's wire */
|
|
#define P_WAY (BUF0_W - 103) /* the port a message being passed on goes by, */
|
|
#define P_NEED (BUF0_W - 100) /* and the cells it needs there */
|
|
#define H_PORT (BUF0_W - 99) /* the port of the first message left on its wire for want of room on this pass; -1: none */
|
|
#define H_NEED (BUF0_W - 98) /* the cells it needs there */
|
|
#define H_MASK (BUF0_W - 97) /* and a bit for each port something was left for */
|
|
#define A_SELF (BUF0_W - 102) /* 1: a message of this node's own, for the node it waits on, came back and was let go here */
|
|
#define SEND_PTR (BUF0_W - 101) /* where the next word of a text being made ready to send goes */
|
|
#define OUT_TEXT (OUT_W - 64) /* what was printed, four characters to a cell, as it goes on the wire: 64 cells */
|
|
#define SEND_TEXT (OUT_W - 400) /* the text of a message SEND is putting, four characters to a cell: 256 cells */
|
|
/* The ROM's slot packer (MACHINE.md 2.1), in what was free: BUF0_W - 32 .. - 23 and - 122 .. - 120. */
|
|
#define ROM_HERE (BUF0_W - 32) /* the next word address code goes to */
|
|
#define ROM_CUR (BUF0_W - 31) /* the instruction word being built */
|
|
#define ROM_SLOT (BUF0_W - 30) /* its next free slot, 0 .. 6 */
|
|
#define ROM_NLIT (BUF0_W - 29) /* how many literals it owes */
|
|
#define ROM_LITS (BUF0_W - 28) /* the literals, 6 cells */
|
|
#define ROM_PI (BUF0_W - 122) /* working cells */
|
|
#define ROM_RS (BUF0_W - 121)
|
|
#define ROM_RN (BUF0_W - 120)
|
|
/* THE IMAGE RECORD: where the system's source says, with `store`, the addresses a host needs (v4/image.h): where the
|
|
* node waits for a message, its fault table, and KEY's code. */
|
|
#define ROM_IMG (BUF0_W - 119) /* idle, fault table, KEY, the word after KEY: 4 cells */
|
|
/* FREE, plain memory: BUF0_W - 22 .. - 21; - 115 .. - 113; BUF0_W - 144 .. - 141 (what a flush makes zero after
|
|
* a full output buffer); and OUT_W - 144 .. OUT_W - 65. They and
|
|
* the cells above held the messages waiting, the refusals owed and what went with them (MESH.md 7a, 7b), which a
|
|
* node no longer keeps. */
|
|
#define AWAIT_FROM (BUF0_W - 39) /* the node whose word of how text ended is waited for */
|
|
#define NEAR (BUF0_W - 64) /* for each port, the number of the node on the other end; 0: not told */
|
|
#define ROUTES (BUF0_W - 96) /* the table of ways: 16 entries of a node and the port address that leads to it */
|
|
#define ROUTE_MAX 16
|
|
#define ME (BUF0_W - 13) /* this node's number: a message is for it when its first word is this */
|
|
#define OUT_PTR (BUF0_W - 14) /* where the next character printed goes: a cell of the output buffer */
|
|
#define REPLY (BUF0_W - 15) /* the port, by its number, the text being served came on */
|
|
#define MSG (BUF0_W - 48) /* the header of the message being served, 7 cells */
|
|
#define OUT_W (BUF0_W - 400) /* the output buffer: 256 cells, a character to a cell */
|
|
#define OUT_CELLS 256
|
|
/* THE ROM'S STATE (docs/v4.0.0/MACHINE.md 2.1): a reserved area that belongs to the ROM's routines, which payloads
|
|
* call at run time; it is never cleared after the boot. OUT_W - 144 .. OUT_W - 65, which was free. */
|
|
#define ROM_TOK (OUT_W - 144) /* the token being read, as a counted string: 16 cells */
|
|
#define ROM_TOKN (OUT_W - 80) /* how many characters it has */
|
|
#define ROM_PEEK (OUT_W - 79) /* a character put back, plus one; 0: none */
|
|
#define ROM_LINE (OUT_W - 78) /* how many new lines have been read */
|
|
#define ROM_EOF (OUT_W - 77) /* non-zero once EOT has been read: the input has ended */
|
|
#define ROM_FAILED (OUT_W - 76) /* 0, or the code of the error that stopped the ROM */
|
|
#define ROM_ERRLINE (OUT_W - 75) /* ROM_LINE when it failed */
|
|
#define ROM_NBASE (OUT_W - 74) /* (NUMBER): the base, 10 or 16 */
|
|
#define ROM_NNEG (OUT_W - 73) /* 1 after a leading - */
|
|
#define ROM_NI (OUT_W - 72) /* the next character of the token */
|
|
#define ROM_NU (OUT_W - 71) /* the value so far, unsigned */
|
|
#define ROM_NBIG (OUT_W - 70) /* 1 once it has not fitted a cell */
|
|
#define ROM_RECN (OUT_W - 128) /* (DEFINE): cells of symbol records used */
|
|
#define ROM_POOLN (OUT_W - 127) /* cells of the name pool used */
|
|
#define ROM_REC (OUT_W - 126) /* (FIND): the record being looked at */
|
|
#define ROM_CNT (OUT_W - 125) /* (DEFINE): cells in the token's name */
|
|
#define ROM_PTR (OUT_W - 124) /* (SAME?), (DEFINE): where in a name */
|
|
#define ROM_I (OUT_W - 123) /* where in the token */
|
|
#define ROM_WI (OUT_W - 122) /* (WALK): which entry of a table */
|
|
#define ROM_NREF (OUT_W - 121) /* word.f18: how many branches wait for a target */
|
|
#define ROM_NLAB (OUT_W - 120) /* how many labels the word being assembled has */
|
|
#define ROM_WNP (OUT_W - 119) /* cells of the word's name area used */
|
|
#define ROM_NFOR (OUT_W - 118) /* how many FORs are open */
|
|
#define ROM_FORS (OUT_W - 117) /* where each began, 8 cells */
|
|
#define ROM_RDEPTH (OUT_W - 109) /* how many macros are being expanded */
|
|
#define ROM_RPTRS (OUT_W - 108) /* where each is reading, 8 cells */
|
|
#define ROM_T1 (OUT_W - 100) /* working cells */
|
|
#define ROM_T2 (OUT_W - 99)
|
|
#define ROM_T3 (OUT_W - 98)
|
|
#define ROM_T4 (OUT_W - 97)
|
|
#define ROM_CFROM (OUT_W - 96)
|
|
#define ROM_CTO (OUT_W - 95)
|
|
#define ROM_CN (OUT_W - 94)
|
|
#define ROM_RAW (OUT_W - 93) /* in.f18: 1 while a token is read raw, ( and \ being names */
|
|
#define ROM_T5 (OUT_W - 92)
|
|
#define ROM_T6 (OUT_W - 91)
|
|
#define ROM_MLEN (OUT_W - 90) /* the length of the token saved in ROM_MTEMP */
|
|
#define ROM_ORIGIN 16 /* where the system's code begins */
|
|
/* The ROM's other tables, used only while it assembles (cleared at `start`): in the block window, the branches
|
|
* waiting -- four cells each: the word, the line, a symbol record (or, while local, a name), 1 if local -- the
|
|
* labels of the word being assembled -- a name and an address -- and their names; in the text input buffer, a
|
|
* saved token, a character to a cell, a macro's name and its body being collected. */
|
|
#define ROM_REFS BUF0_W /* 128 entries */
|
|
#define ROM_REFS_MAX 128
|
|
#define ROM_LABELS (BUF0_W + 512) /* 64 entries */
|
|
#define ROM_WNAMES (BUF0_W + 640) /* 384 cells */
|
|
#define ROM_WN_SIZE 384
|
|
#define ROM_TSAVE TIB_W /* 16 cells */
|
|
#define ROM_MTEMP (TIB_W + 16) /* 64 cells */
|
|
#define ROM_MBODY (TIB_W + 80) /* 180 cells */
|
|
#define ROM_MBODY_SIZE 180
|
|
/* THE ROM'S SYMBOL TABLE, used only while it assembles, in dictionary space (cleared at `start`): 256 hash heads,
|
|
* then records growing up -- link, name, kind, value -- and names, as counted strings, growing down from the top. */
|
|
#define ROM_SYMH DICT_W
|
|
#define ROM_SYMREC (DICT_W + 256)
|
|
#define ROM_POOLTOP DICT_END_W
|
|
#define ROM_REC_LINK 0
|
|
#define ROM_REC_NAME 1
|
|
#define ROM_REC_KIND 2
|
|
#define ROM_REC_VALUE 3
|
|
#define ROM_KIND_WORD 1
|
|
#define ROM_KIND_CONST 2
|
|
#define ROM_KIND_MACRO 3
|
|
#define ROM_KIND_SET 4
|
|
/* the ROM's error codes */
|
|
#define ROM_ERR_TOO_LONG 1 /* a token longer than 63 characters: "name too long" */
|
|
#define ROM_ERR_COMMENT 2 /* a ( with no ) before the end: "comment not closed" */
|
|
#define ROM_ERR_BAD_NAME 3 /* an opcode, a reserved word, a label, a number or &...: "cannot be used as a name" */
|
|
#define ROM_ERR_DEFINED 4 /* "already defined" */
|
|
#define ROM_ERR_NAMES 5 /* the symbol table is full: "too many names" */
|
|
#define ROM_ERR_FIT 6 /* memory is full, or a branch cannot reach: "does not fit" */
|
|
#define ROM_ERR_OPCODE 7 /* not an opcode the packer takes there */
|
|
#define ROM_ERR_IN_MACRO 8 /* "not allowed in a macro" */
|
|
#define ROM_ERR_MACRO 9 /* "macro without endmacro", "endmacro without macro" */
|
|
#define ROM_ERR_LABEL_DUP 10 /* "label already defined in this word" */
|
|
#define ROM_ERR_LABELS 11 /* "too many labels in one word" */
|
|
#define ROM_ERR_FOR 12 /* FOR nested too deep, NEXT or UNEXT without FOR, FOR without NEXT */
|
|
#define ROM_ERR_UNEXT 13 /* "FOR ... UNEXT must fit one instruction word and hold no literal" */
|
|
#define ROM_ERR_TARGET 14 /* "not something to branch to" */
|
|
#define ROM_ERR_UNDEFINED 15 /* "never defined" */
|
|
#define ROM_ERR_BIG 16 /* "number does not fit a cell" */
|
|
#define ROM_ERR_AMP 17 /* "& needs a word that is already defined" */
|
|
#define ROM_ERR_FETCH_P 18 /* "write the number, not @p" */
|
|
#define ROM_ERR_MISSING 19 /* a name, a target, a value or a string missing at the end */
|
|
#define ROM_ERR_DEEP 20 /* "macros nested too deep" */
|
|
#define ROM_ERR_REFS 21 /* "too many unresolved branches" */
|
|
#define ROM_ERR_VALUE 22 /* "not a value", "not a number" */
|
|
#define ROM_ERR_NO_START 23 /* the input ended with no start */
|
|
#define ROM_ERR_START 24 /* start: not a word */
|
|
#define ROM_ADDR_TOP ((v4_cell)(V4_NODE_WORDS + V4_ROM_WORDS - 1u)) /* the top of the address space */
|
|
#define WORD_DEFINED (BUF0_W - 11) /* the xt of the word that is told of each new entry, or 0 */
|
|
#define WORD_FORGOTTEN (BUF0_W - 12) /* the xt of the word that is told when entries go, or 0 */
|
|
#define LOG_LEVEL (BUF0_W - 5) /* the level at or below which a message is printed */
|
|
#define BOOT_CELLS (BVARS + 14) /* (BOOT): DP and LATEST as the loader left them, 2 cells */
|
|
#define BUF0_W (BVARS - (v4_cell)(V4_BLOCK_SLOTS * V4_BLOCK_CELLS)) /* the block window: the kernel's slots, 256 cells each (v4/blocks.h) */
|
|
/* The ports and the addresses after them, through V4_PORT_HAVE (node.h, MESH.md 7d.3), are not memory and must be where
|
|
* no variable is: after the output buffer, which ends at BUF0_W - 144, and before OUT_HDR, the first variable above it.
|
|
* With 8 ports that is 18 addresses, BUF0_W - 140 to BUF0_W - 123. (They were once among the variables, and what was
|
|
* stored to the variables was stored to ports.) */
|
|
typedef char host_map_ports_fit[(PORT >= OUT_W + OUT_CELLS && PORT + (v4_cell)V4_PORT_HAVE < OUT_HDR) ? 1 : -1];
|
|
/* Nothing printed: a node's variable for it, as at switch-on. */
|
|
#define HOST_MESSAGES_EMPTY(n) do { (n)->mem[OUT_PTR] = OUT_W; } while (0)
|
|
#define QVARS (BUF0_W - 4) /* (Q): quit.v4, system.v4 and blocks.v4, 4 cells */
|
|
#define WBUF (WBUF_W * 4)
|
|
#define TIB (TIB_W * 4)
|
|
#define PAD (PAD_W * 4)
|
|
#define SBUF (SBUF_W * 4)
|
|
|
|
/* dictionary space */
|
|
#ifndef DICT_W
|
|
#define DICT_W ((v4_cell)8192)
|
|
#endif
|
|
#ifndef DICT_END_W
|
|
#define DICT_END_W ((v4_cell)13824) /* 512 cells lower than it was: the block window is four slots now */
|
|
#endif
|
|
/* the texts made ready for the wire are above the dictionary */
|
|
typedef char host_map_texts_fit[(SEND_TEXT >= DICT_END_W && SEND_TEXT + 256 <= OUT_TEXT && OUT_TEXT + 64 == OUT_W) ? 1 : -1];
|
|
|
|
/* How many slots, from slot 0, a branch may sit in on a node this size: those
|
|
* whose address field reaches every word of it. */
|
|
static unsigned host_branch_slots(void)
|
|
{
|
|
unsigned k, slots = 0;
|
|
for (k = 0; k < 4; k++) if ((v4_ucell)v4_iword_slot_mask(k) >= (v4_ucell)(V4_NODE_WORDS - 1u)) slots = k + 1;
|
|
return slots;
|
|
}
|
|
|
|
/* Reset `n`, give the assembler every constant the capsule files ask for, and
|
|
* assemble the `count` files named. Returns 1 if all assembled; otherwise
|
|
* prints which did not and why. The caller may assemble more text and must
|
|
* call v4_text_finish. */
|
|
/* THE CONSTANTS the system's source is assembled with: names for the addresses and numbers of this map. One
|
|
* list, read by host_load (here) and by tools/mkmap.c, which writes it as the system's map blob for the ROM. */
|
|
#define HOST_CONSTANTS(X) \
|
|
X("N-1", V4_CELL_BITS - 1) \
|
|
X("NODE-ERROR", NODE_ERROR) \
|
|
X("CONSOLE-TX", CONSOLE_TX) \
|
|
X("CONSOLE-RX", CONSOLE_RX) \
|
|
X("CONSOLE-STATUS", CONSOLE_ST) \
|
|
X("BASE", BASE) \
|
|
X("TIB", TIB) \
|
|
X(">IN", TO_IN) \
|
|
X("SPAN", SPAN) \
|
|
X("WBUF", WBUF) \
|
|
X("(P)", PVARS) \
|
|
X("DP", DP) \
|
|
X("(LATEST)", LATEST) \
|
|
X("DBASE", DICT_W * 4) \
|
|
X("DLIMIT", DICT_END_W * 4) \
|
|
X("PAD", PAD) \
|
|
X("(D)", DVARS) \
|
|
X("(CG)", CGVARS) \
|
|
X("CG-BSLOTS", (v4_cell)host_branch_slots()) \
|
|
X("STATE", STATE) \
|
|
X("(C)", CVARS) \
|
|
X("(CFP)", CFP) \
|
|
X("(Q)", QVARS) \
|
|
X("(F)", FVARS) \
|
|
X("(S)", SVARS) \
|
|
X("(W)", WVARS) \
|
|
X("(X)", XVARS) \
|
|
X("(BOOT)", BOOT_CELLS) \
|
|
X("(LOG-LEVEL)", LOG_LEVEL) \
|
|
X("(ACL-HOOK)", ACL_HOOK) \
|
|
X("SCR", SCR) \
|
|
X("BLK", BLK) \
|
|
X("(SRC)", SRC) \
|
|
X("(SRC-HOOK)", SRC_HOOK) \
|
|
X("(LINE-STATUS)", LINE_STATUS) \
|
|
X("(PORT)", PORT) \
|
|
X("(ME)", ME) \
|
|
X("(CONSOLE)", CONSOLE) \
|
|
X("(ROUTE#)", ROUTE_COUNT) \
|
|
X("(ROUTE-DEFAULT)", ROUTE_DEFAULT) \
|
|
X("(LOST)", LOST) \
|
|
X("(PRINT-TO)", PRINT_TO) \
|
|
X("(PRINT-PORT)", PRINT_PORT) \
|
|
X("(DONE-PORT)", DONE_PORT) \
|
|
X("(ROUTES)", ROUTES) \
|
|
X("-PORTS", -(v4_cell)V4_PORTS) \
|
|
X("(NEAR)", NEAR) \
|
|
X("(AWAIT-FROM)", AWAIT_FROM) \
|
|
X("(WIRE)", WIRE) \
|
|
X("(WIRE-A)", WIRE_A) \
|
|
X("(WIRE-B)", WIRE_B) \
|
|
X("(WIRE-DO)", WIRE_DO) \
|
|
X("(WIRE-HOW)", WIRE_HOW) \
|
|
X("(WIRE-HAVE)", WIRE_HAVE) \
|
|
X("(S-HAVE)", S_HAVE) \
|
|
X("(S-MASK)", S_MASK) \
|
|
X("(S-WIRE)", S_WIRE) \
|
|
X("(S-ON)", S_ON) \
|
|
X("(KEEP)", KEEP) \
|
|
X("(DEFER)", DEFER) \
|
|
X("(D-MASK)", D_MASK) \
|
|
X("(IN)", IN_HDR) \
|
|
X("(ONE)", ONE) \
|
|
X("(OUT-HDR)", OUT_HDR) \
|
|
X("(W-NEED)", W_NEED) \
|
|
X("(W-PORT)", W_PORT) \
|
|
X("(P-WAY)", P_WAY) \
|
|
X("(P-NEED)", P_NEED) \
|
|
X("(H-PORT)", H_PORT) \
|
|
X("(H-NEED)", H_NEED) \
|
|
X("(H-MASK)", H_MASK) \
|
|
X("(A-SELF)", A_SELF) \
|
|
X("(SEND^)", SEND_PTR) \
|
|
X("(OUT-TEXT)", OUT_TEXT) \
|
|
X("(SEND-TEXT)", SEND_TEXT) \
|
|
X("(QUIET)", QUIET) \
|
|
X("(REFUSED)", REFUSED) \
|
|
X("(OUT^)", OUT_PTR) \
|
|
X("(REPLY)", REPLY) \
|
|
X("(MSG)", MSG) \
|
|
X("(OUT)", OUT_W) \
|
|
X("(WORD-DEFINED)", WORD_DEFINED) \
|
|
X("(WORD-FORGOTTEN)", WORD_FORGOTTEN) \
|
|
X("BLOCK#", V4_REQ_BLOCK) /* the kernel's block requests (v4/blocks.h) */ \
|
|
X("BUFFER#", V4_REQ_BUFFER) \
|
|
X("UPDATE#", V4_REQ_UPDATE) \
|
|
X("SAVE-BUFFERS#", V4_REQ_SAVE_BUFFERS) \
|
|
X("EMPTY-BUFFERS#", V4_REQ_EMPTY_BUFFERS) \
|
|
X("(Q/)", QBASE) /* 5 cells */ \
|
|
X("(QE)", QBASE + 5) /* 8 */ \
|
|
X("(QR)", QBASE + 13) /* 5 */ \
|
|
X("(QL)", QBASE + 18) /* 7 */ \
|
|
X("(QT)", QBASE + 25) /* 6 */ \
|
|
X("(QP)", QBASE + 31) /* 4 */ \
|
|
X("(DP)", QBASE + 35) /* 4 */ \
|
|
X("ADDR-DIGITS", V4_CELL_BITS / 4) \
|
|
X("MSB", (v4_cell)V4_MSB) \
|
|
X("MAXHI", (v4_cell)(V4_MSB - 1u)) \
|
|
X("HIMASK", (v4_cell)(((v4_ucell)1 << (V4_CELL_BITS - 16)) - 1u)) \
|
|
X("2N+15", 2 * V4_CELL_BITS + 15) \
|
|
X("N-18", V4_CELL_BITS - 18) \
|
|
X("N-17", V4_CELL_BITS - 17) \
|
|
X("MAX-INT", (v4_cell)(V4_MSB - 1u)) \
|
|
X("HLD", HLD) \
|
|
X("FENCE", FENCE) \
|
|
X("CONTEXT", CONTEXT) \
|
|
X("CURRENT", CURRENT) \
|
|
X("VOC-LINK", VOC_LINK) \
|
|
X("HEND", HEND) \
|
|
X("-HFLOOR", -(HEND - 62)) \
|
|
X("DSTACK-DEPTH", DSTACK_REG) \
|
|
X("RSTACK-DEPTH", RSTACK_REG) \
|
|
X("CFBASE", CFS_W) \
|
|
X("CFEND", CFS_W + CFS_CELLS)
|
|
|
|
static int host_load(v4_text *tx, v4_node *n, const char *const *files, unsigned count)
|
|
{
|
|
char path[512];
|
|
unsigned i;
|
|
|
|
v4_node_reset(n);
|
|
HOST_MESSAGES_EMPTY(n); /* nothing has been printed and no message waits (core.v4) */
|
|
v4_text_begin(tx, n, 16);
|
|
#define HOST_CONSTANT(name, value) v4_text_constant(tx, name, (v4_cell)(value));
|
|
HOST_CONSTANTS(HOST_CONSTANT)
|
|
#undef HOST_CONSTANT
|
|
v4_node_stack_regs_attach(n, DSTACK_REG, RSTACK_REG);
|
|
for (i = 0; i < count; i++) {
|
|
snprintf(path, sizeof path, "%s/%s", V4_CAPSULE_DIR, files[i]);
|
|
if (!v4_text_assemble_file(tx, path)) {
|
|
printf(" %s does not assemble: %s\n", files[i], v4_text_error(tx));
|
|
return 0;
|
|
}
|
|
}
|
|
/* one vocabulary, FORTH, whose head cell is LATEST */
|
|
n->mem[CONTEXT] = LATEST;
|
|
n->mem[CURRENT] = LATEST;
|
|
n->mem[VOC_LINK] = 0;
|
|
/* and the text interpreted is the terminal's */
|
|
n->mem[SRC] = TIB;
|
|
return 1;
|
|
}
|
|
|
|
#endif /* V4_TESTS_HOST_MAP_H */
|