MACHINE.md 2.2. UM*, UM/MOD, D+, DNEGATE, Q.* and Q./ are entries 0-5 of the host ROM and of a mesh node's ROM, from one source (rom/math.f18) and one entry list (v4/rom_entries.h). The host ROM starts at entry 18. The mesh ROM is 277 words; the host ROM 2372. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
3.7 KiB
C
94 lines
3.7 KiB
C
/* mkrom.c -- build the ROM, off the node, as a bitstream is built.
|
|
*
|
|
* mkrom NAME OUT.c OUT.sym MAP.f18 SOURCE.f18...
|
|
*
|
|
* docs/v4.0.0/MACHINE.md section 2. The ROM is F18 code, written in the
|
|
* text assembler's notation (include/v4/text.h) in capsules/v4/rom, and this
|
|
* is the only thing built off the node. It assembles MAP.f18 (the memory
|
|
* map's constants, from tools/mkmap.c) and then each SOURCE in the order
|
|
* given, at the ROM's base address, and writes:
|
|
* OUT.c the ROM: const v4_cell v4_<NAME>_<width>[] and its length (NAME
|
|
* rom: the host node's ROM; mesh_rom: a mesh node's, MACHINE.md 2.2)
|
|
* OUT.sym every word of it, "NAME ADDRESS" a line, for the tests
|
|
*
|
|
* This tool is built with a node whose RAM reaches over the ROM's range
|
|
* (V4_NODE_WORDS = the host's RAM plus its ROM range, V4_ROM_WORDS = 0), so
|
|
* the assembler can lay the ROM down where it will run; ROM_ORIGIN is the
|
|
* host's RAM size, which is where the ROM starts on the machine. The
|
|
* assembler's branch placement depends only on the top of the address space,
|
|
* which is the same either way.
|
|
*/
|
|
#include "v4/text.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifndef ROM_ORIGIN
|
|
#error "ROM_ORIGIN must be the host node's RAM size"
|
|
#endif
|
|
#ifndef ROM_RANGE
|
|
#error "ROM_RANGE must be the host node's ROM range, in words"
|
|
#endif
|
|
|
|
static v4_node n;
|
|
static v4_text tx;
|
|
|
|
static void die(const char *what, const char *detail)
|
|
{
|
|
fprintf(stderr, "mkrom: %s%s%s\n", what, detail ? ": " : "", detail ? detail : "");
|
|
exit(1);
|
|
}
|
|
|
|
/* a cell as a C constant of the cell's type, with no implementation-defined conversion */
|
|
static void put_cell(FILE *f, v4_cell v)
|
|
{
|
|
#if V4_CELL_BITS == 64
|
|
if (v == (v4_cell)((v4_ucell)1 << 63)) fprintf(f, "(-9223372036854775807LL - 1)");
|
|
else fprintf(f, "%lldLL", (long long)v);
|
|
#else
|
|
if (v == (v4_cell)((v4_ucell)1 << 31)) fprintf(f, "(-2147483647L - 1)");
|
|
else fprintf(f, "%ldL", (long)v);
|
|
#endif
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
FILE *out;
|
|
v4_cell here, a;
|
|
int i;
|
|
unsigned s;
|
|
|
|
if (argc < 6) die("usage: mkrom NAME OUT.c OUT.sym MAP.f18 SOURCE.f18...", NULL);
|
|
if ((v4_ucell)V4_NODE_WORDS != (v4_ucell)ROM_ORIGIN + (v4_ucell)ROM_RANGE)
|
|
die("built with the wrong node size: RAM must reach over the ROM's range", NULL);
|
|
|
|
v4_node_reset(&n);
|
|
v4_text_begin(&tx, &n, ROM_ORIGIN);
|
|
for (i = 4; i < argc; i++)
|
|
if (!v4_text_assemble_file(&tx, argv[i])) die("does not assemble", v4_text_error(&tx));
|
|
if (!v4_text_finish(&tx)) die("not everything is defined", v4_text_error(&tx));
|
|
here = v4_text_here(&tx);
|
|
if (here - (v4_cell)ROM_ORIGIN > (v4_cell)ROM_RANGE) die("the ROM is larger than its range", NULL);
|
|
|
|
out = fopen(argv[2], "w");
|
|
if (!out) die("cannot write", argv[2]);
|
|
fprintf(out, "/* Generated by v4/tools/mkrom.c from capsules/v4/rom -- do not edit. */\n#include \"v4/cell.h\"\n\n");
|
|
fprintf(out, "const v4_cell v4_%s_%d[] = {\n", argv[1], V4_CELL_BITS);
|
|
for (a = ROM_ORIGIN; a < here; a++) {
|
|
fprintf(out, " ");
|
|
put_cell(out, n.mem[a]);
|
|
fprintf(out, ",\n");
|
|
}
|
|
if (here == ROM_ORIGIN) fprintf(out, " 0\n");
|
|
fprintf(out, "};\nconst unsigned v4_%s_%d_words = %ldu;\n", argv[1], V4_CELL_BITS, (long)(here - (v4_cell)ROM_ORIGIN));
|
|
if (fclose(out) != 0) die("cannot write", argv[2]);
|
|
|
|
out = fopen(argv[3], "w");
|
|
if (!out) die("cannot write", argv[3]);
|
|
for (s = 0; s < tx.nsym; s++)
|
|
if (tx.sym[s].kind == 1) fprintf(out, "%s %ld\n", tx.pool + tx.sym[s].name, (long)tx.sym[s].value);
|
|
if (fclose(out) != 0) die("cannot write", argv[3]);
|
|
|
|
fprintf(stderr, "mkrom: %s, %ld words, %d-bit cells -> %s\n", argv[1], (long)(here - (v4_cell)ROM_ORIGIN), V4_CELL_BITS, argv[2]);
|
|
return 0;
|
|
}
|