fix(v4): the final review's four defects in the ROM boot
- The boot left the source's last new line in the console input, and the first KEY after the boot read it. What the ROM has not read when it starts the system is taken back (boot.c, rom_harness.h). hosted-check: KEY after the boot reads the key typed. - A comment or macro left open at the end of a blob ran on into the next, and the ROM accepted source text.c refuses. The loader ends each blob with FS (V4_ROM_BLOB_END) after its new line; the ROM ends a blob there as text.c ends a file: an open comment or macro is an error, and the word being assembled ends. test_host_rom_asm: seven blob pairs against text.c. - store to an address outside RAM faulted the ROM with no message. It is now refused, as text.c refuses it: ERR-RANGE, "address out of range". - The kernel build did not regenerate capsules/v4/sys/map-<w>.f18 before packing the capsule directory; it now does. ROM: 2084 words, rom_hash 0x4c458c6e48b35456. 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:
co-authored by
Claude Opus 5.5
parent
a73580e949
commit
ff75e69e91
@@ -90,12 +90,17 @@
|
||||
D: drop ;
|
||||
MISS: drop ERR-MISSING jump (FAIL)
|
||||
|
||||
\ store ADDR VALUE: ADDR must be in RAM, as text.c requires
|
||||
: (H-STORE)
|
||||
(IN-MACRO?) if OK drop ;
|
||||
OK: drop
|
||||
(NEXT-VALUE) if BADV drop (T1) a! !
|
||||
(NEXT-VALUE) if BADV drop
|
||||
(T1) a! @ b! !b ;
|
||||
(T1) a! @ -if LO
|
||||
drop drop ERR-RANGE jump (FAIL)
|
||||
LO: RAM-WORDS inv 1 + + -if HI
|
||||
drop (T1) a! @ b! !b ;
|
||||
HI: drop drop ERR-RANGE jump (FAIL)
|
||||
BADV: drop drop ;
|
||||
|
||||
\ ( -- ) clear the tables the ROM uses only while it assembles: the symbol
|
||||
|
||||
+11
-4
@@ -1,8 +1,10 @@
|
||||
\ in.f18 -- the ROM's input: characters from the console, and tokens.
|
||||
\
|
||||
\ The text the ROM assembles arrives at the console's receive registers,
|
||||
\ a character at a time. The end of it is EOT (4), which the loader sends
|
||||
\ after the last blob. A token is what v4/src/text.c's next_token makes
|
||||
\ a character at a time. Each blob of it ends with a new line and FS (28,
|
||||
\ V4_ROM_BLOB_END), where a file ends for text.c: a comment still open there
|
||||
\ is an error, and (TOKEN) gives 0 there as at the end. The end of all of
|
||||
\ it is EOT (4), which the loader sends after the last blob. A token is what v4/src/text.c's next_token makes
|
||||
\ of the same text: blanks are space, tab, CR and LF; a token is at most 63
|
||||
\ characters; `\` as a whole token skips to the end of the line, and `(` as a
|
||||
\ whole token to the next `)`.
|
||||
@@ -56,13 +58,14 @@
|
||||
S: if SD -1 + pop 2/ 2/ 2/ 2/ 2/ 2/ 2/ 2/ push jump S
|
||||
SD: drop pop 255 and ;
|
||||
|
||||
\ ( -- len ) the next token into (TOK), its length into (TOKN). 0: the end,
|
||||
\ or an error, which is in (FAILED).
|
||||
\ ( -- len ) the next token into (TOK), its length into (TOKN). 0: the end
|
||||
\ of a blob, the end of all ((EOF) set), or an error, which is in (FAILED).
|
||||
: (TOKEN)
|
||||
(EOF) a! @ if GO drop 0 ;
|
||||
GO: drop
|
||||
SKIP: (GETC)
|
||||
dup 4 xor if END
|
||||
drop dup 28 xor if BLOB
|
||||
drop dup 10 xor if NL
|
||||
drop dup 32 xor if SP
|
||||
drop dup 9 xor if SP
|
||||
@@ -72,6 +75,7 @@
|
||||
READ: (TOKN) a! @ 63 xor if LONG
|
||||
drop (PUT) (GETC)
|
||||
dup 4 xor if TEND
|
||||
drop dup 28 xor if TEND
|
||||
drop dup 10 xor if TEND
|
||||
drop dup 32 xor if TEND
|
||||
drop dup 9 xor if TEND
|
||||
@@ -90,6 +94,7 @@
|
||||
BSL: drop drop
|
||||
B1: (GETC)
|
||||
dup 10 xor if BEND
|
||||
drop dup 28 xor if BEND
|
||||
drop dup 4 xor if BEND
|
||||
drop drop jump B1
|
||||
BEND: drop (BACK) jump SKIP
|
||||
@@ -97,12 +102,14 @@
|
||||
P1: (GETC)
|
||||
dup 41 xor if PCLOSE
|
||||
drop dup 10 xor if PNL
|
||||
drop dup 28 xor if PEOF
|
||||
drop dup 4 xor if PEOF
|
||||
drop drop jump P1
|
||||
PNL: drop drop (LF+) jump P1
|
||||
PCLOSE: drop drop jump SKIP
|
||||
PEOF: drop drop ERR-COMMENT (FAIL) 0 ;
|
||||
END: drop drop 1 (EOF) a! ! 0 ;
|
||||
BLOB: drop drop 0 ;
|
||||
NL: drop drop (LF+) jump SKIP
|
||||
SP: drop drop jump SKIP
|
||||
LONG: drop drop ERR-TOO-LONG (FAIL) 0 ;
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
0 (FAILED) a! ! 0 (ERRLINE) a! ! 0 (LINE) a! ! 0 (EOF) a! !
|
||||
0 (PEEK) a! ! 0 (RAW) a! ! ;
|
||||
|
||||
\ the ROM: assemble the system's source from the console until its start
|
||||
\ runs it; on an error, stop at (ROM-FAILED) with the error's code in
|
||||
\ the ROM: assemble the system's source from the console, blob by blob,
|
||||
\ until its start runs it; on an error, stop at (ROM-FAILED) with the error's code in
|
||||
\ (FAILED) and its line in (ERRLINE), for the loader to report
|
||||
: (ROM)
|
||||
(INIT)
|
||||
@@ -40,7 +40,11 @@
|
||||
L0: drop jump L
|
||||
END: drop
|
||||
(FAILED) a! @ if NS drop jump (ROM-FAILED)
|
||||
NS: drop ERR-NO-START (FAIL) jump (ROM-FAILED)
|
||||
NS: drop (EOF) a! @ if BLOB drop ERR-NO-START (FAIL) jump (ROM-FAILED)
|
||||
\ the end of a blob: the word being assembled ends, as at the end of a
|
||||
\ file for text.c
|
||||
BLOB: drop (END-WORD)
|
||||
(FAILED) a! @ if L0 drop jump (ROM-FAILED)
|
||||
|
||||
: (ROM-FAILED)
|
||||
H: jump H
|
||||
|
||||
@@ -797,6 +797,13 @@ $(V4_ROM_C) $(V4_MAP_C): FORCE
|
||||
@cmp -s v4/build/rom-64.c $(V4_ROM_C) || cp v4/build/rom-64.c $(V4_ROM_C)
|
||||
@cmp -s v4/build/v4_map_64.c $(V4_MAP_C) || cp v4/build/v4_map_64.c $(V4_MAP_C)
|
||||
|
||||
# The system's memory map, capsules/v4/sys/map-<w>.f18, is generated from
|
||||
# the same description as the ROM and v4_map_image (v4/tests/host_map.h), and
|
||||
# the ROM assembles it from this kernel's capsule directory: it is made
|
||||
# again before the directory is packed, so the three always agree.
|
||||
$(CAPSULES_DIR)/v4/sys/map-64.f18 $(CAPSULES_DIR)/v4/sys/map-32.f18: FORCE
|
||||
@$(MAKE) --no-print-directory -C v4 CC=cc sysmap
|
||||
|
||||
$(LOADER_OBJ_DIR)/v4engine/v4_rom.o: $(V4_ROM_C) | $(LOADER_OBJ_DIR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "CC (loader) $<"
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;042;160t[2J[001;001H[2J[001;001H[8;056;240t[2J[001;001HBdsDxe: loading Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
BdsDxe: starting Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
RAW SERIAL UP
|
||||
[CKPT 002] Serial (COM1) initialized
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
EBS...
|
||||
EBS OK
|
||||
Calling kernel_main (monolithic)...
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 amd64
|
||||
Architecture: amd64
|
||||
Build: Oct 15 2026 16:25:17
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at port 0x00000000000003f8 (COM1, probed)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 135
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 966 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248685
|
||||
Free pages : 247162
|
||||
Used pages : 1523
|
||||
Total MB : 971
|
||||
Free MB : 965
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
APIC: IA32_APIC_BASE MSR=0x00000000fee00900
|
||||
APIC: stale-ISR drain: 0 EOI(s) issued
|
||||
APIC: initialized (xAPIC MMIO, TPR=0, SIVR=0x1FF, EOI-clear)
|
||||
APIC: init done
|
||||
|
||||
I/O APIC: init...
|
||||
I/O APIC: base=0xfec00000, gsi_base=0, overrides=5
|
||||
override: source=00 gsi=2 flags=0x0000
|
||||
override: source=05 gsi=5 flags=0x000d
|
||||
override: source=09 gsi=9 flags=0x000d
|
||||
override: source=0a gsi=10 flags=0x000d
|
||||
override: source=0b gsi=11 flags=0x000d
|
||||
i8042: keyboard ACKed enable-scanning
|
||||
i8042: IRQ1 enabled in controller config byte
|
||||
I/O APIC: keyboard IRQ1 routed (masked)
|
||||
|
||||
Timer: init...
|
||||
Timer: init start
|
||||
Timer: PM_TMR_BLK discovered from FADT at port 1544
|
||||
Timer: VM mode detected (hypervisor present).
|
||||
Timer: HPET calibration disabled (VM-exit MMIO would poison timing).
|
||||
Timer: WARNING: invariant TSC not present under hypervisor.
|
||||
Timer: continuing in RELATIVE mode (no determinism guarantees).
|
||||
Timer: RDTSCP not present; using RDTSC (less serialized).
|
||||
Timer: CPUID frequency unavailable; trying PM Timer...
|
||||
Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=2099887244 Hz
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 24641536
|
||||
Heap end addr: 561512448
|
||||
|
||||
Heartbeat: init...
|
||||
APIC Timer: calibrating...
|
||||
APIC Timer: apic_hz=1006329721, tick_hz=100, initial_count=10063297
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0xaa70e1dee90f9000
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0x5282537f9cc6d053
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x0278d4bcbd206dba
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x01297cd8e8018acd
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0x7117595eb17ace99
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2084 rom_hash=0x4c458c6e48b35456 instructions=62044241
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x6b56e15226ee3719
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xe5a57f3eb72ff94a
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 79903299] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok>
|
||||
@@ -0,0 +1,126 @@
|
||||
UEFI firmware (version 2025.11-3ubuntu7.3 built at 15:40:26 on Sep 23 2026)
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;031;100t[2J[001;001HBdsDxe: failed to load Boot0002 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x2,0x0): Not Found
|
||||
BdsDxe: failed to load Boot0003 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-1" from PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0): Not Found
|
||||
BdsDxe: loading Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
BdsDxe: starting Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Collecting boot information...
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 aarch64
|
||||
Architecture: aarch64
|
||||
Build: Oct 15 2026 16:28:11
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a PL011 at 0x0000000009000000 (no devicetree: QEMU's)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 108
|
||||
Total memory: 4093 MB
|
||||
Usable memory: 4054 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 1039291
|
||||
Free pages : 1037880
|
||||
Used pages : 1411
|
||||
Total MB : 4059
|
||||
Free MB : 4054
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
AArch64: running at EL1
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PSCI: no DTB -- using HVC (QEMU virt-machine default)
|
||||
GICv2: no DTB GIC node -- using QEMU virt-machine defaults
|
||||
GICv2: distributor+CPU interface enabled, PPI 30
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: AArch64 generic timer initialised.
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 2147483608
|
||||
Free bytes: 2147483608
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 1207959552
|
||||
Heap end addr: 3355443200
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0xaa70e1dee90f9000
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0x5282537f9cc6d053
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x0278d4bcbd206dba
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x01297cd8e8018acd
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0x7117595eb17ace99
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2084 rom_hash=0x4c458c6e48b35456 instructions=62044241
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x6b56e15226ee3719
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xe5a57f3eb72ff94a
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 1400955] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok>
|
||||
@@ -0,0 +1,196 @@
|
||||
|
||||
OpenSBI v1.8
|
||||
____ _____ ____ _____
|
||||
/ __ \ / ____| _ \_ _|
|
||||
| | | |_ __ ___ _ __ | (___ | |_) || |
|
||||
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
|
||||
| |__| | |_) | __/ | | |____) | |_) || |_
|
||||
\____/| .__/ \___|_| |_|_____/|____/_____|
|
||||
| |
|
||||
|_|
|
||||
|
||||
Platform Name : riscv-virtio,qemu
|
||||
Platform Features : medeleg
|
||||
Platform HART Count : 1
|
||||
Platform HART Protection : pmp
|
||||
Platform IPI Device : aclint-mswi
|
||||
Platform Timer Device : aclint-mtimer @ 10000000Hz
|
||||
Platform Console Device : uart8250
|
||||
Platform HSM Device : ---
|
||||
Platform PMU Device : ---
|
||||
Platform Reboot Device : syscon-reboot
|
||||
Platform Shutdown Device : syscon-poweroff
|
||||
Platform Suspend Device : ---
|
||||
Platform CPPC Device : ---
|
||||
Firmware Base : 0x80000000
|
||||
Firmware Size : 321 KB
|
||||
Firmware RW Offset : 0x40000
|
||||
Firmware RW Size : 65 KB
|
||||
Firmware Heap Offset : 0x47000
|
||||
Firmware Heap Size : 37 KB (total), 0 KB (reserved), 12 KB (used), 23 KB (free)
|
||||
Firmware Scratch Size : 4096 B (total), 1464 B (used), 2632 B (free)
|
||||
Runtime SBI Version : 3.0
|
||||
Standard SBI Extensions : ipi,pmu,srst,sse,hsm,rfnc,fwft,time,base,legacy,dbcn,dbtr
|
||||
Experimental SBI Extensions : none
|
||||
|
||||
Domain0 Name : root
|
||||
Domain0 Boot HART : 0
|
||||
Domain0 HARTs : 0*
|
||||
Domain0 Region00 : 0x0000000080040000-0x000000008005ffff M: (F,R,W) S/U: ()
|
||||
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (F,R,X) S/U: ()
|
||||
Domain0 Region02 : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region03 : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region04 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
|
||||
Domain0 Region05 : 0x000000000c400000-0x000000000c5fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region06 : 0x000000000c000000-0x000000000c3fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region07 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
|
||||
Domain0 Next Address : 0x0000000020000000
|
||||
Domain0 Next Arg1 : 0x00000000bfe00000
|
||||
Domain0 Next Mode : S-mode
|
||||
Domain0 SysReset : yes
|
||||
Domain0 SysSuspend : yes
|
||||
|
||||
Boot HART ID : 0
|
||||
Boot HART Domain : root
|
||||
Boot HART Priv Version : v1.12
|
||||
Boot HART Base ISA : rv64imafdch
|
||||
Boot HART ISA Extensions : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu
|
||||
Boot HART PMP Count : 16
|
||||
Boot HART PMP Granularity : 2 bits
|
||||
Boot HART PMP Address Bits : 54
|
||||
Boot HART MHPM Info : 16 (0x0007fff8)
|
||||
Boot HART Debug Triggers : 2 triggers
|
||||
Boot HART MIDELEG : 0x0000000000001666
|
||||
Boot HART MEDELEG : 0x0000000000f4b509
|
||||
[2J[004D[=3h[2J[009D[2J[004D[8;031;100t[2J[016DRISC-V EDK2 firmware version 2025.11-3ubuntu7.3
|
||||
Press ESCAPE within 5 seconds for boot options ERROR: C40000002:V03051002 I0 6D33944A-EC75-4855-A54D-809C75241F6C 83FFF850
|
||||
BdsDxe: failed to load Boot0001 "UEFI Misc Device" fr
|
||||
om PciRoot(0x0)/Pci(0x1,0x0): Not Found
|
||||
[2J[001;001H[=3h[2J[009DStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
Calling kernel_main (monolithic)...
|
||||
riscv64 item 4.3.5a: satp state at kernel entry (before switch)
|
||||
satp.MODE = 0x000000000000000a
|
||||
satp.PPN = 0x00000000000bf868
|
||||
__kernel_start = 0x00000000bdc340aa
|
||||
riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 riscv64
|
||||
Architecture: riscv64
|
||||
Build: Oct 15 2026 16:32:14
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at 0x0000000010000000 (no devicetree: QEMU's)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 100
|
||||
Total memory: 1020 MB
|
||||
Usable memory: 974 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 250212
|
||||
Free pages : 249560
|
||||
Used pages : 652
|
||||
Total MB : 977
|
||||
Free MB : 974
|
||||
Used MB : 2
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PLIC: no DTB PLIC node -- using QEMU virt-machine default (base=0x0c000000)
|
||||
PLIC: init (S-mode context 1, threshold=0)
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: RISC-V time CSR @ 10000000 Hz (FALLBACK, no devicetree)
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 2214588416
|
||||
Heap end addr: 2751459328
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0xaa70e1dee90f9000
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0x5282537f9cc6d053
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x0278d4bcbd206dba
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x01297cd8e8018acd
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0x7117595eb17ace99
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2084 rom_hash=0x4c458c6e48b35456 instructions=62044241
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x6b56e15226ee3719
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xe5a57f3eb72ff94a
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 25281543] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok>
|
||||
@@ -232,6 +232,8 @@ hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt) $(BINDIR)/star
|
||||
@grep -q '^ok> 0 12 ok$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: COLD lost the capsule's words"; cat $(BINDIR)/cold-amd64.txt; exit 1; }
|
||||
@grep -q '^ok> Protected word$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: a capsule word could be forgotten"; exit 1; }
|
||||
@grep -q '^ok> Goodbye!$$' $(BINDIR)/cold-amd64.txt || { echo "hosted-check: COLD lost BYE"; exit 1; }
|
||||
@printf 'KEY .\nA\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/key-amd64.txt
|
||||
@grep -q '^ok> 65 ok$$' $(BINDIR)/key-amd64.txt || { echo "hosted-check: the first KEY after the boot did not read the key typed: the ROM's source left something in the console's input"; tail -3 $(BINDIR)/key-amd64.txt; exit 1; }
|
||||
@printf 'RS1\nT{\nWORDS\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/after-post-amd64.txt
|
||||
@grep -q "^ok> UNKNOWN WORD: 'RS1'$$" $(BINDIR)/after-post-amd64.txt || { echo "hosted-check: a word a POST case defined is still there"; exit 1; }
|
||||
@grep -q "^ok> UNKNOWN WORD: 'T{'$$" $(BINDIR)/after-post-amd64.txt || { echo "hosted-check: POST's harness is on the node"; exit 1; }
|
||||
|
||||
@@ -69,6 +69,12 @@
|
||||
#endif
|
||||
#define V4_ROM_BASE ((v4_cell)V4_NODE_WORDS)
|
||||
|
||||
/* What the ROM reads at the end of each blob of the source it is fed (ASCII
|
||||
* FS, the file separator), after the blob's new line: the end of a file, as
|
||||
* text.c ends one -- a comment or macro still open there is an error, and the
|
||||
* word being assembled ends. The end of the whole source is EOT (4). */
|
||||
#define V4_ROM_BLOB_END 28
|
||||
|
||||
/* 5% safety boundary at each end of node memory, per guard.h. Note the
|
||||
* arithmetic: at 1024 words that is 52 words either side, 5.2% of memory
|
||||
* spent on a boundary. That is the cost of the convention on a resource that
|
||||
|
||||
+11
-5
@@ -454,7 +454,7 @@ static const char *const rom_errors[] = {
|
||||
"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",
|
||||
"too many unresolved branches", "not a value", "the source ended with no start", "start of something not a word", "address out of range",
|
||||
};
|
||||
#define ROM_ERRORS (sizeof rom_errors / sizeof rom_errors[0])
|
||||
|
||||
@@ -474,8 +474,11 @@ static uint64_t rom_hash(void)
|
||||
|
||||
/* The machine starts in its ROM, and the boot is its console: it feeds the
|
||||
* system's source to the console a blob at a time, each found and checked
|
||||
* as any capsule is, with a new line after each, and then EOT, until the
|
||||
* ROM has assembled the system and started it. Then the node is where the
|
||||
* as any capsule is, with a new line and V4_ROM_BLOB_END after each (where
|
||||
* the ROM ends a blob as text.c ends a file), and then EOT, until the ROM
|
||||
* has assembled the system and started it. What the ROM had not read of
|
||||
* the source when it started the system is the source's, not the system's
|
||||
* console input, and is taken back. Then the node is where the
|
||||
* system waits for a message, and its host reads from the image record
|
||||
* what only the system knows (v4_image_from_node). If the ROM stops on an
|
||||
* error, the blob and line are said, and what the error is. */
|
||||
@@ -483,7 +486,7 @@ static int load_system(const v4_boot *b)
|
||||
{
|
||||
static const uint8_t *payload[SYSTEM_BLOBS];
|
||||
static uint32_t length[SYSTEM_BLOBS], first_line[SYSTEM_BLOBS];
|
||||
static const char newline = '\n', eot = EOT;
|
||||
static const char blob_end[2] = { '\n', V4_ROM_BLOB_END }, eot = EOT;
|
||||
v4_node *n = b->n;
|
||||
uint64_t steps = 0;
|
||||
uint32_t lines = 0, at = 0;
|
||||
@@ -513,7 +516,8 @@ static int load_system(const v4_boot *b)
|
||||
if (blob < SYSTEM_BLOBS && at < length[blob]) {
|
||||
at += v4_node_console_feed(n, payload[blob] + at, length[blob] - at);
|
||||
} else if (blob < SYSTEM_BLOBS) {
|
||||
if (v4_node_console_feed(n, &newline, 1)) { blob++; at = 0; }
|
||||
at += v4_node_console_feed(n, blob_end + (at - length[blob]), length[blob] + 2u - at);
|
||||
if (at == length[blob] + 2u) { blob++; at = 0; }
|
||||
} else if (v4_node_console_feed(n, &eot, 1)) {
|
||||
fed_all = 1;
|
||||
}
|
||||
@@ -534,6 +538,8 @@ static int load_system(const v4_boot *b)
|
||||
}
|
||||
}
|
||||
|
||||
n->input_pos = n->input_len = 0;
|
||||
|
||||
say(b, "PARITY:V4_ROM words="); say_dec(b, BOOT_ROM_WORDS);
|
||||
say(b, " rom_hash="); say_hex(b, rom_hash());
|
||||
say(b, " instructions="); say_dec(b, (uint32_t)b->es->anticlock);
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
#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 */
|
||||
#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 */
|
||||
|
||||
@@ -106,7 +106,7 @@ 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
|
||||
* the end, each followed by a new line, then EOT -- what v4/system/boot.c
|
||||
* 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. */
|
||||
@@ -129,12 +129,13 @@ static char *rom_system_text(size_t *len)
|
||||
f = fopen(path, "rb");
|
||||
if (!f) { printf(" cannot read %s\n", path); free(text); return NULL; }
|
||||
fseek(f, 0, SEEK_END); n = ftell(f); fseek(f, 0, SEEK_SET);
|
||||
if (n < 0 || total + (size_t)n + 2 > cap || fread(text + total, 1, (size_t)n, f) != (size_t)n) {
|
||||
if (n < 0 || total + (size_t)n + 3 > cap || fread(text + total, 1, (size_t)n, f) != (size_t)n) {
|
||||
fclose(f); free(text); return NULL;
|
||||
}
|
||||
fclose(f);
|
||||
total += (size_t)n;
|
||||
text[total++] = '\n'; /* a blob that does not end with a new line still ends a token */
|
||||
text[total++] = V4_ROM_BLOB_END; /* and the blob ends, as a file ends for text.c */
|
||||
}
|
||||
text[total++] = 4; /* EOT */
|
||||
*len = total;
|
||||
@@ -157,6 +158,7 @@ static int rom_build_system(v4_node *n, long *words)
|
||||
if (w % 1000 == 0 && n->mem[ROM_FAILED] != 0) break;
|
||||
}
|
||||
free(text);
|
||||
n->input_pos = n->input_len = 0; /* what was not read is the source's: boot.c takes it back */
|
||||
if (words) *words = w;
|
||||
return n->p < V4_ROM_BASE && n->mem[ROM_FAILED] == 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,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 },
|
||||
{ "without", ROM_ERR_MISSING },
|
||||
{ "address out of range", ROM_ERR_RANGE }, { "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;
|
||||
@@ -117,6 +117,45 @@ static void same(const char *text)
|
||||
}
|
||||
|
||||
|
||||
/* text.c on each blob as a file of its own, as the host tests and text.c
|
||||
* read the system; the ROM on the same blobs as the boot feeds them, each
|
||||
* followed by a new line and V4_ROM_BLOB_END (Review Focus 1: a blob that
|
||||
* ends mid-comment, mid-macro or mid-word). */
|
||||
static void same_blobs(const char *const *blobs, unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
int okA = 1, rb;
|
||||
v4_cell w, hereA;
|
||||
|
||||
v4_node_reset(&a);
|
||||
v4_text_begin(&tx, &a, ROM_ORIGIN);
|
||||
for (i = 0; i < count && okA; i++) okA = v4_text_assemble(&tx, blobs[i]);
|
||||
okA = okA && v4_text_assemble(&tx, ": ZZEND ;") && v4_text_finish(&tx);
|
||||
in[0] = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
size_t l = strlen(in);
|
||||
snprintf(in + l, sizeof in - l, "%s\n%c", blobs[i], (char)V4_ROM_BLOB_END);
|
||||
}
|
||||
strcat(in, ": ZZEND ;\nstart ZZEND\n\x04");
|
||||
rb = rom_run(in);
|
||||
if (okA) {
|
||||
hereA = v4_text_here(&tx);
|
||||
CHECK(rb == 1, "[%s | %s] text.c accepts; the ROM %s (code %ld)", blobs[0], blobs[count - 1],
|
||||
rb == 0 ? "refused" : "did not finish", (long)b.mem[ROM_FAILED]);
|
||||
if (rb != 1) return;
|
||||
CHECK(b.p == v4_text_word(&tx, "ZZEND"), "[%s | %s] the ROM started at ZZEND", blobs[0], blobs[count - 1]);
|
||||
for (w = ROM_ORIGIN; w < hereA; w++) if (a.mem[w] != b.mem[w]) break;
|
||||
CHECK(w == hereA, "[%s | %s] word %ld differs", blobs[0], blobs[count - 1], (long)w);
|
||||
} else {
|
||||
const char *m = v4_text_error(&tx);
|
||||
CHECK(rb == 0, "[%s | %s] text.c refuses (%s); the ROM %s", blobs[0], blobs[count - 1], m,
|
||||
rb == 1 ? "accepted" : "did not finish");
|
||||
if (rb != 0) return;
|
||||
CHECK(b.mem[ROM_FAILED] == code_of(m), "[%s | %s] text.c: %s; ROM code %ld, want %ld", blobs[0], blobs[count - 1], m,
|
||||
(long)b.mem[ROM_FAILED], (long)code_of(m));
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned i;
|
||||
@@ -186,6 +225,27 @@ int main(void)
|
||||
for (i = 0; i < 260u; i++) if (b.mem[TIB_W + (v4_cell)i] != 0) break;
|
||||
CHECK(i == 260u, "the text input buffer is cleared: cell %u is not", i);
|
||||
|
||||
/* blobs: each ends as a file ends for text.c (Review Focus 1) */
|
||||
{
|
||||
static const char *const comment[] = { ": A ;\n( a comment left open", ": B 1 ; )" };
|
||||
static const char *const macro[] = { "macro M 1", "endmacro : A M ;" };
|
||||
static const char *const nfor[] = { ": A 3 FOR", "NEXT ;" };
|
||||
static const char *const label[] = { ": A L1: 1", "jump L1 ;" };
|
||||
static const char *const bsl[] = { ": A ;\n\\ a comment with no new line", ": B A ;" };
|
||||
static const char *const word[] = { ": A 1", "2 ;" };
|
||||
static const char *const closed[] = { "( closed ) : A ;", ": B A ;" };
|
||||
same_blobs(comment, 2); same_blobs(macro, 2); same_blobs(nfor, 2); same_blobs(label, 2);
|
||||
same_blobs(bsl, 2); same_blobs(word, 2); same_blobs(closed, 2);
|
||||
}
|
||||
|
||||
/* store outside RAM: refused with an error, as text.c refuses it, not a fault */
|
||||
{
|
||||
static char t[80];
|
||||
same("store -1 5");
|
||||
snprintf(t, sizeof t, "store %ld 5", (long)V4_NODE_WORDS); same(t);
|
||||
snprintf(t, sizeof t, "store %ld 5", (long)V4_NODE_WORDS - 1); same(t);
|
||||
}
|
||||
|
||||
printf("test_host_rom_asm: %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ int main(int argc, char **argv)
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user