feat(v4): mkrom -- the ROM built off the node; it reads tokens
The ROM's source is F18 code in capsules/v4/rom, assembled off the node by v4/tools/mkrom.c with the memory map's constants from v4/tools/mkmap.c (MACHINE.md 2). main.f18 is the entry table payloads call through (2.1); in.f18 reads the console and splits it into tokens exactly as text.c does, the token held packed as a counted string. The ROM's state is a reserved area of the map (host_map.h ROM_*). text.c gains the constant directive, so the off-node assembler and the ROM speak one language. The map also names (NUMBER)'s state, for the next task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
32753f5479
commit
0f82d8c22a
@@ -0,0 +1,105 @@
|
||||
\ 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
|
||||
\ 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 `)`.
|
||||
\
|
||||
\ State, in the ROM's area of the memory map (MACHINE.md 2.1):
|
||||
\ (TOK) the token, as a counted string: its count byte, then its
|
||||
\ characters, four to a cell, low byte first, zero-padded --
|
||||
\ the form `",` lays down and (FIND) compares; 16 cells
|
||||
\ (TOKN) its length
|
||||
\ (PEEK) a character put back, plus one; 0: none
|
||||
\ (LINE) how many new lines have been read
|
||||
\ (EOF) non-zero once EOT has been read
|
||||
\ (FAILED) 0, or the code of the error that stopped the ROM
|
||||
\ (ERRLINE) (LINE) when it failed
|
||||
\ Every routine here uses A.
|
||||
|
||||
\ ( -- c ) wait for a character, then take it
|
||||
: (KEY)
|
||||
W: CONSOLE-STATUS a! @ if Z drop CONSOLE-RX a! @ ;
|
||||
Z: drop jump W
|
||||
|
||||
\ ( -- c ) the character put back, if there is one; else the next
|
||||
: (GETC)
|
||||
(PEEK) a! @ if NONE 0 ! -1 + ;
|
||||
NONE: drop jump (KEY)
|
||||
|
||||
\ ( c -- ) put a character back, to be the next one read
|
||||
: (BACK) 1 + (PEEK) a! ! ;
|
||||
|
||||
\ ( -- ) one more new line
|
||||
: (LF+) (LINE) a! @ 1 + ! ;
|
||||
|
||||
\ ( code -- ) stop with an error, noting the line
|
||||
: (FAIL) (FAILED) a! ! (LINE) a! @ (ERRLINE) a! ! ;
|
||||
|
||||
\ ( c -- ) one more character of the token: byte (TOKN)+1 of (TOK), into
|
||||
\ a cell whose byte there is still zero
|
||||
: (PUT)
|
||||
(TOKN) a! @ 1 +
|
||||
dup 2/ 2/ (TOK) + push
|
||||
3 and
|
||||
S: if SD push 2* 2* 2* 2* 2* 2* 2* 2* pop -1 + jump S
|
||||
SD: drop pop a! @ xor !
|
||||
(TOKN) a! @ 1 + ! ;
|
||||
|
||||
\ ( i -- c ) character i of the token, from 0
|
||||
: (CHAR@)
|
||||
1 + dup 2/ 2/ (TOK) + a! @
|
||||
push 3 and
|
||||
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).
|
||||
: (TOKEN)
|
||||
(EOF) a! @ if GO drop 0 ;
|
||||
GO: drop
|
||||
SKIP: (GETC)
|
||||
dup 4 xor if END
|
||||
drop dup 10 xor if NL
|
||||
drop dup 32 xor if SP
|
||||
drop dup 9 xor if SP
|
||||
drop dup 13 xor if SP
|
||||
drop 0 (TOKN) a! !
|
||||
(TOK) a! 15 FOR 0 !+ NEXT
|
||||
READ: (TOKN) a! @ 63 xor if LONG
|
||||
drop (PUT) (GETC)
|
||||
dup 4 xor if TEND
|
||||
drop dup 10 xor if TEND
|
||||
drop dup 32 xor if TEND
|
||||
drop dup 9 xor if TEND
|
||||
drop dup 13 xor if TEND
|
||||
drop jump READ
|
||||
TEND: drop (BACK)
|
||||
(TOKN) a! @ (TOK) a! @ xor !
|
||||
(TOKN) a! @ 1 xor if ONE
|
||||
drop (TOKN) a! @ ;
|
||||
ONE: drop 0 (CHAR@)
|
||||
dup 92 xor if BSL
|
||||
drop dup 40 xor if PAREN
|
||||
drop drop 1 ;
|
||||
BSL: drop drop
|
||||
B1: (GETC)
|
||||
dup 10 xor if BEND
|
||||
drop dup 4 xor if BEND
|
||||
drop drop jump B1
|
||||
BEND: drop (BACK) jump SKIP
|
||||
PAREN: drop drop
|
||||
P1: (GETC)
|
||||
dup 41 xor if PCLOSE
|
||||
drop dup 10 xor if PNL
|
||||
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 ;
|
||||
NL: drop drop (LF+) jump SKIP
|
||||
SP: drop drop jump SKIP
|
||||
LONG: drop drop ERR-TOO-LONG (FAIL) 0 ;
|
||||
@@ -0,0 +1,11 @@
|
||||
\ main.f18 -- the ROM's entry table.
|
||||
\
|
||||
\ docs/v4.0.0/MACHINE.md 2.1. The ROM is shared code: a payload calls its
|
||||
\ routines through this table and never to an address inside the ROM, so a
|
||||
\ rebuilt ROM breaks no payload. It is at the ROM's base, one jump a word,
|
||||
\ in a fixed order that only ever grows at its end. Entry i is at the ROM's
|
||||
\ base plus i. DATASHEET-F18.md lists each routine's stack effect.
|
||||
|
||||
: (ENTRIES)
|
||||
jump (KEY) \ 0 ( -- c )
|
||||
jump (TOKEN) \ 1 ( -- len )
|
||||
Reference in New Issue
Block a user