/* 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/text.h" #include #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: (B) 6 cells, then SCR BLK (SRC) (SRC-HOOK) and the device's four */ #define SCR (BVARS + 6) #define BLK (BVARS + 7) #define SRC (BVARS + 8) #define SRC_HOOK (BVARS + 9) #define STORAGE_REG (BVARS + 10) #define ACL_HOOK (BUF0_W - 6) /* the xt of the access control recheck word, or 0 */ #define EMIT_HOOK (BUF0_W - 7) /* the xt of a word EMIT gives its character to, or 0: the console */ #define CATCH (BUF0_W - 8) /* non-zero: a line's error is recorded here, -1, and the line ends " ok" */ #define LINE_STATUS (BUF0_W - 9) /* how the last line ended: 0 QUIT, 1 completed, 2 an error */ #define PORT (BUF0_W - 10) /* the node's port: a write to it blocks until its neighbour, the kernel, has served it */ #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 - 2 * 256) /* the two block buffers, 256 cells each */ #define BUF1_W (BUF0_W + 256) #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)14336) #endif /* 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. */ 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); v4_text_begin(tx, n, 16); v4_text_constant(tx, "N-1", V4_CELL_BITS - 1); v4_text_constant(tx, "NODE-ERROR", NODE_ERROR); v4_text_constant(tx, "CONSOLE-TX", CONSOLE_TX); v4_text_constant(tx, "CONSOLE-RX", CONSOLE_RX); v4_text_constant(tx, "CONSOLE-STATUS", CONSOLE_ST); v4_text_constant(tx, "BASE", BASE); v4_text_constant(tx, "TIB", TIB); v4_text_constant(tx, ">IN", TO_IN); v4_text_constant(tx, "SPAN", SPAN); v4_text_constant(tx, "WBUF", WBUF); v4_text_constant(tx, "(P)", PVARS); v4_text_constant(tx, "DP", DP); v4_text_constant(tx, "(LATEST)", LATEST); v4_text_constant(tx, "DBASE", DICT_W * 4); v4_text_constant(tx, "DLIMIT", DICT_END_W * 4); v4_text_constant(tx, "PAD", PAD); v4_text_constant(tx, "(D)", DVARS); v4_text_constant(tx, "(CG)", CGVARS); v4_text_constant(tx, "CG-BSLOTS", (v4_cell)host_branch_slots()); v4_text_constant(tx, "STATE", STATE); v4_text_constant(tx, "(C)", CVARS); v4_text_constant(tx, "(CFP)", CFP); v4_text_constant(tx, "(Q)", QVARS); v4_text_constant(tx, "(F)", FVARS); v4_text_constant(tx, "(S)", SVARS); v4_text_constant(tx, "(W)", WVARS); v4_text_constant(tx, "(X)", XVARS); v4_text_constant(tx, "(B)", BVARS); v4_text_constant(tx, "(BOOT)", BOOT_CELLS); v4_text_constant(tx, "(LOG-LEVEL)", LOG_LEVEL); v4_text_constant(tx, "(ACL-HOOK)", ACL_HOOK); v4_text_constant(tx, "SCR", SCR); v4_text_constant(tx, "BLK", BLK); v4_text_constant(tx, "(SRC)", SRC); v4_text_constant(tx, "(SRC-HOOK)", SRC_HOOK); v4_text_constant(tx, "(EMIT-HOOK)", EMIT_HOOK); v4_text_constant(tx, "(CATCH)", CATCH); v4_text_constant(tx, "(LINE-STATUS)", LINE_STATUS); v4_text_constant(tx, "(PORT)", PORT); v4_text_constant(tx, "(WORD-DEFINED)", WORD_DEFINED); v4_text_constant(tx, "(WORD-FORGOTTEN)", WORD_FORGOTTEN); v4_text_constant(tx, "BLOCK-NUMBER", STORAGE_REG); v4_text_constant(tx, "BLOCK-ADDRESS", STORAGE_REG + 1); v4_text_constant(tx, "BLOCK-COMMAND", STORAGE_REG + 2); v4_text_constant(tx, "BLOCK-STATUS", STORAGE_REG + 3); v4_text_constant(tx, "BUF0", BUF0_W); v4_text_constant(tx, "BUF1", BUF1_W); v4_text_constant(tx, "(Q/)", QBASE); /* 5 cells */ v4_text_constant(tx, "(QE)", QBASE + 5); /* 8 */ v4_text_constant(tx, "(QR)", QBASE + 13); /* 5 */ v4_text_constant(tx, "(QL)", QBASE + 18); /* 7 */ v4_text_constant(tx, "(QT)", QBASE + 25); /* 6 */ v4_text_constant(tx, "(QP)", QBASE + 31); /* 4 */ v4_text_constant(tx, "(DP)", QBASE + 35); /* 4 */ v4_text_constant(tx, "ADDR-DIGITS", V4_CELL_BITS / 4); v4_text_constant(tx, "MSB", (v4_cell)V4_MSB); v4_text_constant(tx, "MAXHI", (v4_cell)(V4_MSB - 1u)); v4_text_constant(tx, "HIMASK", (v4_cell)(((v4_ucell)1 << (V4_CELL_BITS - 16)) - 1u)); v4_text_constant(tx, "2N+15", 2 * V4_CELL_BITS + 15); v4_text_constant(tx, "N-18", V4_CELL_BITS - 18); v4_text_constant(tx, "N-17", V4_CELL_BITS - 17); v4_text_constant(tx, "MAX-INT", (v4_cell)(V4_MSB - 1u)); v4_text_constant(tx, "HLD", HLD); v4_text_constant(tx, "FENCE", FENCE); v4_text_constant(tx, "CONTEXT", CONTEXT); v4_text_constant(tx, "CURRENT", CURRENT); v4_text_constant(tx, "VOC-LINK", VOC_LINK); v4_text_constant(tx, "HEND", HEND); v4_text_constant(tx, "-HFLOOR", -(HEND - 62)); v4_text_constant(tx, "DSTACK-DEPTH", DSTACK_REG); v4_text_constant(tx, "RSTACK-DEPTH", RSTACK_REG); v4_node_stack_regs_attach(n, DSTACK_REG, RSTACK_REG); v4_text_constant(tx, "CFBASE", CFS_W); v4_text_constant(tx, "CFEND", CFS_W + CFS_CELLS); 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 */