fix(v4): the final review's six minors in the ROM boot

- Text after start is refused, as text.c refuses it: before it jumps, the
  ROM reads on to the end of the source; blanks, comments and the ends of
  blobs may follow, a token is ERR-AFTER (26), "text after start".
- A token too long where a name, a target or a value is wanted is "name
  too long", as text.c says: (MISSING) reports "missing" only when no error
  came first.  `", keeps "missing", which is text.c's word for both.
- text.c's "address out of range" names the address, not the value.
- The system's source files are one list, v4/sys_files.h: boot.c, the
  harness and the nucleus test are made from it.
- The ROM's error codes and words are one list, v4/rom_errors.h: boot.c's
  messages, host_map.h's ROM_ERR_* and mkmap's ERR-* are made from it.
- node.h says what v4_node_store does with a ROM address (nothing, as for
  any address outside RAM, D-14); test_host_rom_range pins it.

ROM: 2095 words, rom_hash 0x06d0dcb7a0cb41a1.  dict_hash unchanged,
0xe5a57f3eb72ff94a.  make -C v4 test test-32 hosted-check pass.  QEMU:
amd64, aarch64, riscv64 to ok>, POST 538/538, POST: PASSED.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 17:10:45 -04:00
co-authored by Claude Opus 5.5
parent ff75e69e91
commit a28b5f2230
18 changed files with 646 additions and 89 deletions
+3 -1
View File
@@ -60,7 +60,9 @@
/* THE ROM (docs/v4.0.0/MACHINE.md section 2, DATASHEET-F18.md section 5).
* A read-only range of V4_ROM_WORDS words at V4_ROM_BASE, just above RAM.
* An instruction fetch, an @p literal and a data fetch there read the ROM; a
* running programme's store there is an address fault. In the model it is
* running programme's store there is an address fault. C code's
* v4_node_store there does nothing and counts no fault, as for any address
* outside RAM (D-14, at v4_node_store below). In the model it is
* attached, as every device is, and v4_node_reset detaches it: the owner
* attaches it again after a reset. The range's size is a build parameter,
* as RAM's is; 0 (the default) is a machine with no ROM. */
+43
View File
@@ -0,0 +1,43 @@
/* rom_errors.h -- the ROM's error codes and what they mean.
*
* The ROM (capsules/v4/rom) stops at (ROM-FAILED) with one of these codes in
* (FAILED); the loader, which owns the console, prints its words
* (v4/system/boot.c). This is the one list: the map's constants ERR-* the
* ROM is assembled with (v4/tools/mkmap.c, through v4/tests/host_map.h's
* ROM_ERR_*) and the boot's messages are both made from it. The codes run
* 1, 2, 3 ... in order; a new one goes at the end.
*
* X(NAME, CODE, WORDS)
*/
#ifndef V4_ROM_ERRORS_H
#define V4_ROM_ERRORS_H
#define V4_ROM_ERRORS(X) \
X(TOO_LONG, 1, "name too long") /* a token longer than 63 characters */ \
X(COMMENT, 2, "comment not closed") /* a ( with no ) before the end of its blob */ \
X(BAD_NAME, 3, "cannot be used as a name") /* an opcode, a reserved word, a label, a number or &... */ \
X(DEFINED, 4, "already defined") \
X(NAMES, 5, "too many names") /* the symbol table is full */ \
X(FIT, 6, "does not fit: memory is full, or a branch cannot reach") \
X(OPCODE, 7, "not an opcode the packer takes there") \
X(IN_MACRO, 8, "not allowed in a macro") \
X(MACRO, 9, "macro without endmacro, or endmacro without macro") \
X(LABEL_DUP, 10, "label already defined in this word") \
X(LABELS, 11, "too many labels in one word") \
X(FOR, 12, "FOR nested too deep, NEXT or UNEXT without FOR, or FOR without NEXT") \
X(UNEXT, 13, "FOR ... UNEXT must fit one instruction word and hold no literal") \
X(TARGET, 14, "not something to branch to") \
X(UNDEFINED, 15, "never defined") \
X(BIG, 16, "number does not fit a cell") \
X(AMP, 17, "& needs a word that is already defined") \
X(FETCH_P, 18, "write the number, not @p") \
X(MISSING, 19, "a name, a target, a value or a string is missing") \
X(DEEP, 20, "macros nested too deep") \
X(REFS, 21, "too many unresolved branches") \
X(VALUE, 22, "not a value") \
X(NO_START, 23, "the source ended with no start") \
X(START, 24, "start of something not a word") \
X(RANGE, 25, "address out of range") /* store outside RAM */ \
X(AFTER, 26, "text after start")
#endif
+17
View File
@@ -0,0 +1,17 @@
/* sys_files.h -- the system's source, in the order the ROM reads it.
*
* capsules/v4/sys: the memory map (map-<cell bits>.f18) first, then these,
* then end.f18 -- the state the system is switched on in, and `start`. The
* one list: the boot feeds these blobs (v4/system/boot.c), and the tests
* that build the system read these files (v4/tests/rom_harness.h).
*
* X(FILE): capsules/v4/sys/FILE.f18
*/
#ifndef V4_SYS_FILES_H
#define V4_SYS_FILES_H
#define V4_SYS_FILES(X) \
X(core) X(input) X(dict) X(codegen) X(compile) X(quit) X(forth) \
X(numout) X(words) X(system) X(qmath) X(blocks) X(log) X(acl)
#endif
+4 -4
View File
@@ -450,15 +450,15 @@ static void set_directive(v4_text *t, reader *r)
/* `store ADDR VALUE`: a word of RAM is given VALUE. */
static void store_directive(v4_text *t, reader *r)
{
char tok[V4_TEXT_MAX_TOKEN + 1u];
char at[V4_TEXT_MAX_TOKEN + 1u], tok[V4_TEXT_MAX_TOKEN + 1u];
v4_cell addr, v;
if (r->depth != 1) { fail(t, "not allowed in a macro", "store"); return; }
if (!next_token(t, r, tok)) { if (!t->failed) fail(t, "store without an address", NULL); return; }
if (!value_of(t, tok, &addr)) return;
if (!next_token(t, r, at)) { if (!t->failed) fail(t, "store without an address", NULL); return; }
if (!value_of(t, at, &addr)) return;
if (!next_token(t, r, tok)) { if (!t->failed) fail(t, "store without a value", NULL); return; }
if (!value_of(t, tok, &v)) return;
if (addr < 0 || (v4_ucell)addr >= V4_NODE_WORDS) { fail(t, "address out of range", tok); return; }
if (addr < 0 || (v4_ucell)addr >= V4_NODE_WORDS) { fail(t, "address out of range", at); return; }
v4_node_store(t->as.n, addr, v);
}
+12 -18
View File
@@ -8,6 +8,8 @@
#include "v4/post.h"
#include "v4/blocks.h"
#include "v4/boot.h"
#include "v4/rom_errors.h"
#include "v4/sys_files.h"
#include "v4/message.h"
#include "v4/wire.h"
#include "starkernel/capsule.h"
@@ -430,32 +432,24 @@ extern const unsigned v4_rom_32_words;
#define EOT 4 /* the end of the source: the ROM's (KEY) sees no more */
/* The system's source, in the order the ROM reads it: the memory map, then
* the system, then its end -- the state it is switched on in, and `start`.
* capsules/v4/sys; each blob is a capsule like any other. */
* the system (v4/sys_files.h), then its end -- the state it is switched on
* in, and `start`. capsules/v4/sys; each blob is a capsule like any other. */
#define MAP_NAME_(bits) "v4:sys:map-" #bits ".f18"
#define MAP_NAME__(bits) MAP_NAME_(bits)
static const char *const system_blobs[] = {
#define SYS_BLOB(file) "v4:sys:" #file ".f18",
MAP_NAME__(V4_CELL_BITS),
"v4:sys:core.f18", "v4:sys:input.f18", "v4:sys:dict.f18", "v4:sys:codegen.f18", "v4:sys:compile.f18",
"v4:sys:quit.f18", "v4:sys:forth.f18", "v4:sys:numout.f18", "v4:sys:words.f18", "v4:sys:system.f18",
"v4:sys:qmath.f18", "v4:sys:blocks.f18", "v4:sys:log.f18", "v4:sys:acl.f18",
V4_SYS_FILES(SYS_BLOB)
"v4:sys:end.f18",
#undef SYS_BLOB
};
#define SYSTEM_BLOBS (sizeof system_blobs / sizeof system_blobs[0])
/* What the ROM's error codes mean (v4/tests/host_map.h, ROM_ERR_*): the ROM
* stops with the code, and the loader, which owns the console, says it. */
static const char *const rom_errors[] = {
"", "name too long", "comment not closed", "cannot be used as a name", "already defined",
"too many names", "does not fit: memory is full, or a branch cannot reach", "not an opcode the packer takes there",
"not allowed in a macro", "macro without endmacro, or endmacro without macro",
"label already defined in this word", "too many labels in one word",
"FOR nested too deep, NEXT or UNEXT without FOR, or FOR without NEXT",
"FOR ... UNEXT must fit one instruction word and hold no literal", "not something to branch to",
"never defined", "number does not fit a cell", "& needs a word that is already defined",
"write the number, not @p", "a name, a target, a value or a string is missing", "macros nested too deep",
"too many unresolved branches", "not a value", "the source ended with no start", "start of something not a word", "address out of range",
};
/* What the ROM's error codes mean (v4/rom_errors.h): the ROM stops with the
* code, and the loader, which owns the console, says it. Code c is entry c. */
#define ROM_ERROR_TEXT(name, code, text) text,
static const char *const rom_errors[] = { "", V4_ROM_ERRORS(ROM_ERROR_TEXT) };
#undef ROM_ERROR_TEXT
#define ROM_ERRORS (sizeof rom_errors / sizeof rom_errors[0])
/* FNV-1a over the ROM, a cell at a time, low byte first, as the dictionary
+4 -26
View File
@@ -12,6 +12,7 @@
#ifndef V4_TESTS_HOST_MAP_H
#define V4_TESTS_HOST_MAP_H
#include "v4/rom_errors.h"
#include "v4/blocks.h"
#include "v4/text.h"
#include <stdio.h>
@@ -197,32 +198,9 @@
#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_ERR_RANGE 25 /* "address out of range": store outside RAM */
/* the ROM's error codes: ROM_ERR_TOO_LONG, ROM_ERR_COMMENT ... (v4/rom_errors.h) */
#define ROM_ERR_ENUM_(name, code, text) ROM_ERR_##name = code,
enum { V4_ROM_ERRORS(ROM_ERR_ENUM_) ROM_ERR_END_ };
#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 */
+8 -5
View File
@@ -12,6 +12,7 @@
#include "v4/testcode.h"
#include "host_map.h"
#include "v4/sys_files.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -105,13 +106,15 @@ static void rom_boot(v4_node *n)
}
/* THE SYSTEM, AS THE MACHINE BUILDS IT (MACHINE.md section 6, step 1). The
* system's source, capsules/v4/sys (V4_SYS_DIR): the map, the fourteen and
* system's source, capsules/v4/sys (V4_SYS_DIR): the map, v4/sys_files.h and
* the end, each followed by a new line and V4_ROM_BLOB_END, then EOT -- what v4/system/boot.c
* feeds the console. rom_system_text gives it whole, *len its length;
* rom_build_system has `n`, booted with its ROM, assemble it, and runs it to
* its start: 1 if it started, with *words the instruction words it took. */
static const char *const rom_system_files[] = { "core", "input", "dict", "codegen", "compile", "quit", "forth",
"numout", "words", "system", "qmath", "blocks", "log", "acl" };
#define ROM_SYS_FILE(file) #file,
static const char *const rom_system_files[] = { V4_SYS_FILES(ROM_SYS_FILE) };
#undef ROM_SYS_FILE
#define ROM_SYS_FILES ((unsigned)(sizeof rom_system_files / sizeof rom_system_files[0]))
static char *rom_system_text(size_t *len)
{
@@ -119,12 +122,12 @@ static char *rom_system_text(size_t *len)
char *text = malloc(cap);
unsigned i;
if (!text) return NULL;
for (i = 0; i < 16; i++) {
for (i = 0; i < ROM_SYS_FILES + 2u; i++) {
char path[512];
FILE *f;
long n;
if (i == 0) snprintf(path, sizeof path, "%s/map-%d.f18", V4_SYS_DIR, V4_CELL_BITS);
else if (i <= 14) snprintf(path, sizeof path, "%s/%s.f18", V4_SYS_DIR, rom_system_files[i - 1]);
else if (i <= ROM_SYS_FILES) snprintf(path, sizeof path, "%s/%s.f18", V4_SYS_DIR, rom_system_files[i - 1]);
else snprintf(path, sizeof path, "%s/end.f18", V4_SYS_DIR);
f = fopen(path, "rb");
if (!f) { printf(" cannot read %s\n", path); free(text); return NULL; }
+39 -1
View File
@@ -11,6 +11,7 @@
#include "rom_harness.h"
#include "v4/text.h"
#include "rom_asm_cases.h"
#include "v4/rom_errors.h"
static int failures = 0, checks = 0;
#define CHECK(c,...) do{checks++; if(!(c)){failures++; printf("FAIL %s:%d: ",__FILE__,__LINE__); printf(__VA_ARGS__); printf("\n");}}while(0)
@@ -38,7 +39,7 @@ static v4_cell code_of(const char *m)
{ "write the number", ROM_ERR_FETCH_P }, { "too many unresolved", ROM_ERR_REFS },
{ "not a value", ROM_ERR_VALUE }, { "not a number", ROM_ERR_VALUE },
{ "too many names", ROM_ERR_NAMES }, { "out of name space", ROM_ERR_NAMES },
{ "address out of range", ROM_ERR_RANGE }, { "without", ROM_ERR_MISSING },
{ "address out of range", ROM_ERR_RANGE }, { "text after start", ROM_ERR_AFTER }, { "without", ROM_ERR_MISSING },
};
unsigned i;
for (i = 0; i < sizeof map / sizeof map[0]; i++) if (strstr(m, map[i].s)) return map[i].c;
@@ -246,6 +247,43 @@ int main(void)
snprintf(t, sizeof t, "store %ld 5", (long)V4_NODE_WORDS - 1); same(t);
}
/* a token too long where a name or a value is wanted: "name too long", as
* text.c says, not "missing" -- the first error stands */
{
static const char *const forms[] = { "constant %s 5", "constant K %s", "set %s 5", "set S %s", ": %s",
"store %s 5", "store 300 %s", "#, %s", "jump %s", "if %s", "\", %s" };
static char t[160], long_tok[65];
memset(long_tok, 'X', 64); long_tok[64] = 0;
for (i = 0; i < sizeof forms / sizeof forms[0]; i++) { snprintf(t, sizeof t, forms[i], long_tok); same(t); }
}
/* text after start: refused, as text.c refuses it; blanks, comments and
* the blob's end after it are not text */
CHECK(rom_run(": Z ;\nstart Z\n1\n\x04") == 0 && b.mem[ROM_FAILED] == ROM_ERR_AFTER, "text after start: refused (code %ld)",
(long)b.mem[ROM_FAILED]);
CHECK(rom_run(": Z ;\nstart Z \\ a comment\n( and another )\n\x1c\x04") == 1, "comments and a blob's end after start: started (code %ld)",
(long)b.mem[ROM_FAILED]);
{
v4_node_reset(&a);
v4_text_begin(&tx, &a, ROM_ORIGIN);
CHECK(!v4_text_assemble(&tx, ": Z ;\nstart Z\n1\n") && code_of(v4_text_error(&tx)) == ROM_ERR_AFTER,
"text.c refuses text after start too: %s", v4_text_error(&tx));
}
/* the ROM's error messages, as the boot prints them: one list
* (v4/rom_errors.h), its codes 1, 2, 3 ... in order */
{
static const struct { int code; const char *text; } list[] = {
#define E(name, code, text) { code, text },
V4_ROM_ERRORS(E)
#undef E
};
for (i = 0; i < sizeof list / sizeof list[0]; i++) if (list[i].code != (int)i + 1) break;
CHECK(i == sizeof list / sizeof list[0], "the ROM's error codes run 1, 2, 3 ... : entry %u is %d", i, list[i].code);
CHECK(ROM_ERR_RANGE == 25 && strcmp(list[ROM_ERR_RANGE - 1].text, "address out of range") == 0, "ROM_ERR_RANGE's message");
CHECK(strcmp(list[ROM_ERR_AFTER - 1].text, "text after start") == 0, "ROM_ERR_AFTER's message");
}
printf("test_host_rom_asm: %d checks, %d failures\n", checks, failures);
return failures != 0;
}
+2 -2
View File
@@ -28,9 +28,9 @@ static int build_a(void)
unsigned i;
v4_node_reset(&a);
v4_text_begin(&tx, &a, ROM_ORIGIN);
for (i = 0; i < 16; i++) {
for (i = 0; i < ROM_SYS_FILES + 2u; i++) {
if (i == 0) snprintf(path, sizeof path, "%s/map-%d.f18", V4_SYS_DIR, V4_CELL_BITS);
else if (i <= 14) snprintf(path, sizeof path, "%s/%s.f18", V4_SYS_DIR, rom_system_files[i - 1]);
else if (i <= ROM_SYS_FILES) snprintf(path, sizeof path, "%s/%s.f18", V4_SYS_DIR, rom_system_files[i - 1]);
else snprintf(path, sizeof path, "%s/end.f18", V4_SYS_DIR);
if (!v4_text_assemble_file(&tx, path)) return 0;
}
+2
View File
@@ -46,6 +46,8 @@ int main(void)
v4_node_rom_attach(&n, rom, 16);
CHECK(v4_node_load(&n, V4_ROM_BASE) == rom[0], "the ROM reads");
CHECK(v4_node_load(&n, V4_ROM_BASE + 16) == 0, "past the ROM's words: nothing");
v4_node_store(&n, V4_ROM_BASE, 12345);
CHECK(v4_node_load(&n, V4_ROM_BASE) == rom[0] && n.faults == 0, "C code's store into the ROM does nothing and counts no fault (node.h)");
/* RAM 16: call the ROM's word, then return */
v4_asm_begin(&as, &n, 16);
+1
View File
@@ -540,6 +540,7 @@ int main(void)
CHECK(ok(": T ; constant A 300 store A 5 store A+1 &T") && nb.mem[300] == 5 && nb.mem[301] == ORIGIN,
"store puts a VALUE anywhere in RAM");
CHECK(refused("store -1 5", "address out of range", 1), "store outside RAM is refused");
CHECK(refused("store 99999 5", "address out of range: 99999", 1), "store outside RAM names the address, not the value");
CHECK(refused("store 5", "store without a value", 1), "store needs a value");
CHECK(ok(": A ; : B ; start B") && v4_text_start(&tx) == ORIGIN + 1, "start names the word the system starts at");
CHECK(ok(": A ;") && v4_text_start(&tx) == -1, "no start: -1");
+15 -25
View File
@@ -83,9 +83,21 @@ int main(int argc, char **argv)
constant("(SYMH)", (long)ROM_SYMH);
constant("SYMREC", (long)ROM_SYMREC);
constant("POOLTOP", (long)ROM_POOLTOP);
constant("ERR-BAD-NAME", (long)ROM_ERR_BAD_NAME);
constant("ERR-DEFINED", (long)ROM_ERR_DEFINED);
constant("ERR-NAMES", (long)ROM_ERR_NAMES);
{
/* the ROM's error codes, ERR-TOO-LONG ... (v4/rom_errors.h) */
static const struct { const char *name; long code; } errs[] = {
#define ROM_ERR_CONST_(name, code, text) { #name, code },
V4_ROM_ERRORS(ROM_ERR_CONST_)
#undef ROM_ERR_CONST_
};
unsigned e, c;
for (e = 0; e < sizeof errs / sizeof errs[0]; e++) {
char n[40] = "ERR-";
for (c = 0; errs[e].name[c] && c < sizeof n - 5u; c++) n[4 + c] = errs[e].name[c] == '_' ? '-' : errs[e].name[c];
n[4 + c] = 0;
constant(n, errs[e].code);
}
}
constant("(HERE)", (long)ROM_HERE);
constant("(CUR)", (long)ROM_CUR);
constant("(SLOT)", (long)ROM_SLOT);
@@ -96,8 +108,6 @@ int main(int argc, char **argv)
constant("(RN)", (long)ROM_RN);
constant("RAM-WORDS", (long)V4_NODE_WORDS);
constant("ADDR-TOP", (long)ROM_ADDR_TOP);
constant("ERR-FIT", (long)ROM_ERR_FIT);
constant("ERR-OPCODE", (long)ROM_ERR_OPCODE);
constant("(NREF)", (long)ROM_NREF);
constant("(NLAB)", (long)ROM_NLAB);
constant("(WNP)", (long)ROM_WNP);
@@ -130,24 +140,6 @@ int main(int argc, char **argv)
constant("DICT-END", (long)DICT_END_W);
constant("BUF0", (long)BUF0_W);
constant("TIB-W", (long)TIB_W);
constant("ERR-IN-MACRO", (long)ROM_ERR_IN_MACRO);
constant("ERR-MACRO", (long)ROM_ERR_MACRO);
constant("ERR-LABEL-DUP", (long)ROM_ERR_LABEL_DUP);
constant("ERR-LABELS", (long)ROM_ERR_LABELS);
constant("ERR-FOR", (long)ROM_ERR_FOR);
constant("ERR-UNEXT", (long)ROM_ERR_UNEXT);
constant("ERR-TARGET", (long)ROM_ERR_TARGET);
constant("ERR-UNDEFINED", (long)ROM_ERR_UNDEFINED);
constant("ERR-BIG", (long)ROM_ERR_BIG);
constant("ERR-AMP", (long)ROM_ERR_AMP);
constant("ERR-FETCH-P", (long)ROM_ERR_FETCH_P);
constant("ERR-MISSING", (long)ROM_ERR_MISSING);
constant("ERR-DEEP", (long)ROM_ERR_DEEP);
constant("ERR-REFS", (long)ROM_ERR_REFS);
constant("ERR-VALUE", (long)ROM_ERR_VALUE);
constant("ERR-NO-START", (long)ROM_ERR_NO_START);
constant("ERR-START", (long)ROM_ERR_START);
constant("ERR-RANGE", (long)ROM_ERR_RANGE);
constant("DSTACK-REG", (long)DSTACK_REG);
constant("RSTACK-REG", (long)RSTACK_REG);
/* the cell width's constants (NUMBER) needs, written as signed cells */
@@ -155,7 +147,5 @@ int main(int argc, char **argv)
constant("DEC-LIMIT", (long)(v4_cell)(~(v4_ucell)0 / 10u));
constant("DEC-NLAST", -(long)(~(v4_ucell)0 % 10u) - 1);
constant("HEX-HIGH", (long)(v4_cell)~(~(v4_ucell)0 >> 4));
constant("ERR-TOO-LONG", (long)ROM_ERR_TOO_LONG);
constant("ERR-COMMENT", (long)ROM_ERR_COMMENT);
return 0;
}