diff --git a/capsules/BLOCK_MAP.md b/capsules/BLOCK_MAP.md
index 0154e10a..546abd8e 100644
--- a/capsules/BLOCK_MAP.md
+++ b/capsules/BLOCK_MAP.md
@@ -1,5 +1,5 @@
# Capsule Block Manifest — Auto-generated
-
+
@@ -31,7 +31,6 @@
| `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` | n/a |
| `v4:forth79.4th` | 6000, 6001, 6002 | `0x4055641ee17d176b` | n/a |
| `v4:hera.4th` | 8000, 8001, 8002, 8003, 8004 | `0x526252bfef9b722b` | n/a |
-| `v4:post79.4th` | 7000, 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7011, 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, 7028, 7029, 7030, 7031, 7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, 7053, 7054, 7055, 7056, 7057, 7058, 7059, 7060, 7061, 7062, 7063 | `0xb26d1b974884179d` | n/a |
| `workload-0.4th` | 2200, 2201 | `0x93f86f60aeba8feb` | n/a |
| `workload-1-lite.4th` | 5058, 5059 | `0x44a7a7e3176dcc8d` | n/a |
| `workload-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | n/a |
@@ -372,70 +371,6 @@
| 6000 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok |
| 6001 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok |
| 6002 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok |
-| 7000 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7001 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7002 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7003 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7004 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7005 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7006 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7007 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7008 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7009 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7010 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7011 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7012 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7013 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7014 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7015 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7016 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7017 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7018 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7019 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7020 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7021 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7022 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7023 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7024 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7025 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7026 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7027 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7028 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7029 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7030 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7031 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7032 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7033 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7034 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7035 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7036 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7037 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7038 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7039 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7040 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7041 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7042 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7043 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7044 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7045 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7046 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7047 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7048 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7049 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7050 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7051 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7052 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7053 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7054 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7055 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7056 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7057 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7058 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7059 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7060 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7061 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7062 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
-| 7063 | `v4:post79.4th` | `0xb26d1b974884179d` | ok |
| 8000 | `v4:hera.4th` | `0x526252bfef9b722b` | ok |
| 8001 | `v4:hera.4th` | `0x526252bfef9b722b` | ok |
| 8002 | `v4:hera.4th` | `0x526252bfef9b722b` | ok |
@@ -447,4 +382,4 @@
None.
---
-*39 capsule(s) scanned. Re-run `mkcapsule --manifest
` to refresh.*
+*38 capsule(s) scanned. Re-run `mkcapsule --manifest ` to refresh.*
diff --git a/capsules/v4/nucleus-64.f18 b/capsules/v4/nucleus-64.f18
index b604f3dd..f842ffa8 100644
Binary files a/capsules/v4/nucleus-64.f18 and b/capsules/v4/nucleus-64.f18 differ
diff --git a/capsules/v4/post79.4th b/capsules/v4/post79.4th
deleted file mode 100644
index 882b9225..00000000
--- a/capsules/v4/post79.4th
+++ /dev/null
@@ -1,1796 +0,0 @@
-Block 7000
-( post79.4th -- POST for the FORTH-79 Required Word Set on v4. )
-( Generated by v4/tools/mkpost.py from v3's POST cases: do not )
-( edit. docs/v4.0.0/NUCLEUS.md section 6. )
-VARIABLE T# VARIABLE TPASS VARIABLE TFAIL VARIABLE TOPEN
-VARIABLE TBAD VARIABLE TWANT VARIABLE TLEN VARIABLE TSUM
-VARIABLE TDEP
-CREATE TBUF 64 ALLOT CREATE TSTK 16 ALLOT CREATE TNAME 8 ALLOT
-0 T# ! 0 TPASS ! 0 TFAIL ! 0 TOPEN !
-: TB ( -- baddr ) TBUF 4 * ;
-: TN ( -- baddr ) TNAME 4 * ;
-( T-EMIT is given every character a case prints: the first 255 )
-( are kept, all are counted and summed. )
-: T-EMIT ( c -- )
- 255 AND DUP TSUM @ 31 * + 16777215 AND TSUM !
- TLEN @ 255 < IF TB TLEN @ + C! ELSE DROP THEN 1 TLEN +! ;
-Block 7001
-: T-CLEAR ( i*x -- ) BEGIN DEPTH WHILE DROP REPEAT ;
-: T. ( n -- ) 0 <# #S #> TYPE ;
-( what a failing case printed, and the stack it left )
-: T-SHOW ( -- )
- ." out<" TB TLEN @ 255 MIN TYPE ." > stack<"
- TDEP @ BEGIN DUP WHILE 1- DUP TSTK + @ . REPEAT DROP ." >" ;
-( the verdict on the case that is open, if one is )
-: T-CLOSE ( -- )
- TOPEN @ IF
- (CATCH) @ -1 = TWANT @ = 0= IF 1 TBAD ! THEN
- TBAD @ IF 1 TFAIL +!
- ." POST FAIL: " TN COUNT TYPE T-SHOW CR
- ELSE 1 TPASS +! THEN
- 0 TOPEN ! 0 (CATCH) !
- THEN ;
-Block 7002
-( T{ name begin a case: clean stack, decimal, FORTH )
-: T{ ( i*x -- ) T-CLOSE T-CLEAR
- DECIMAL [COMPILE] FORTH DEFINITIONS
- BL WORD COUNT 31 MIN DUP TN C! TN 1+ SWAP CMOVE
- 1 T# +! 1 TOPEN ! 0 TBAD ! 0 TWANT ! 0 TLEN ! 0 TSUM !
- 0 TDEP ! 1 (CATCH) ! ;
-( T| ... a line of the case, what it prints captured )
-: T| ' T-EMIT (EMIT-HOOK) ! ; IMMEDIATE
-: T-END ( -- ) 0 (EMIT-HOOK) ! DECIMAL ;
-( -> ... the case is over: set its stack aside, top first )
-: -> ( i*x -- ) T-END 0
- BEGIN DEPTH 1 > WHILE
- DUP 16 < IF SWAP OVER TSTK + ! ELSE SWAP DROP 1 TBAD ! THEN
- 1+ REPEAT
- 16 MIN TDEP ! ;
-Block 7003
-( ->ERR the case is over, and must have ended in an error )
-: ->ERR ( i*x -- ) T-END -1 TWANT ! T-CLEAR ;
-( ... }T the stack the case must have left, in order )
-: }T ( i*x -- )
- DEPTH TDEP @ = 0= IF 1 TBAD ! T-CLEAR EXIT THEN
- 0 BEGIN DEPTH 1 > WHILE
- SWAP OVER TSTK + @ = 0= IF 1 TBAD ! THEN 1+ REPEAT DROP ;
-( n }TD only how many values the case must have left )
-: }TD ( n -- ) TDEP @ = 0= IF 1 TBAD ! THEN ;
-( len sum T= what the case must have printed )
-: T= ( len sum -- ) TSUM @ = 0= IF 1 TBAD ! THEN
- TLEN @ = 0= IF 1 TBAD ! THEN ;
-Block 7004
-( the tally; a failure is an error, which ends the boot )
-: T-REPORT ( -- ) T-CLOSE 0 (CATCH) ! DECIMAL
- ." PARITY:V4_POST tests=" T# @ T. ." pass=" TPASS @ T.
- ." fail=" TFAIL @ T. CR
- TFAIL @ IF -1 NODE-ERROR ! THEN ;
-Block 7005
-T{ DUP.basic
-T| 5 DUP . . CR
--> }T 5 16397428 T=
-T{ DUP.zero
-T| 0 DUP . . CR
--> }T 5 11775018 T=
-T{ DUP.negative
-T| -42 DUP . . CR
--> }T 9 15322016 T=
-T{ DUP.max_int
-T| 2147483647 DUP . . CR
--> }T 23 2334858 T=
-T{ DUP.min_int
-T| -2147483648 DUP . . CR
--> }T 25 386046 T=
-Block 7006
-T{ DUP.empty_stack
-T| DUP
-->ERR
-T{ DROP.basic
-T| 5 7 DROP . CR
--> }T 3 51935 T=
-T{ DROP.zero
-T| 42 0 DROP . CR
--> }T 4 1598184 T=
-T{ DROP.negative
-T| 10 -5 DROP . CR
--> }T 4 1506889 T=
-T{ DROP.double_drop
-T| 1 2 3 DROP DROP . CR
--> }T 3 48091 T=
-Block 7007
-T{ DROP.triple_drop
-T| 1 2 3 4 DROP DROP DROP . CR
--> }T 3 48091 T=
-T{ DROP.sequential
-T| 5 DROP 6 DROP 7 . CR
--> }T 3 53857 T=
-T{ DROP.single_item
-T| 99 DROP DEPTH . CR
--> }T 3 47130 T=
-T{ DROP.depth_change
-T| DEPTH 1 2 DROP DEPTH SWAP - . CR
--> 0 }T 3 48091 T=
-T{ DROP.preserve_depth
-T| DEPTH 5 6 DROP DROP DEPTH = . CR
--> }T 3 47130 T=
-Block 7008
-T{ DROP.max_int
-T| 2147483647 DROP DEPTH . CR
--> }T 3 47130 T=
-T{ DROP.min_int
-T| -2147483648 DROP DEPTH . CR
--> }T 3 47130 T=
-T{ DROP.with_dup
-T| 5 DUP DROP . CR
--> }T 3 51935 T=
-T{ DROP.with_swap
-T| 1 2 SWAP DROP . CR
--> }T 3 49052 T=
-T{ DROP.complex
-T| 1 2 3 ROT DROP SWAP DROP . CR
--> }T 3 50013 T=
-Block 7009
-T{ DROP.empty_stack
-T| DROP
-->ERR
-T{ SWAP.basic
-T| 5 7 SWAP . . CR
--> }T 5 16399350 T=
-T{ SWAP.same_values
-T| 42 42 SWAP . . CR
--> }T 7 15838026 T=
-T{ SWAP.zero_nonzero
-T| 0 99 SWAP . . CR
--> }T 6 12996858 T=
-T{ SWAP.negative
-T| -5 10 SWAP . . CR
--> }T 7 12792257 T=
-Block 7010
-T{ SWAP.one_item
-T| 42 SWAP
-->ERR
-T{ SWAP.empty_stack
-T| SWAP
-->ERR
-T{ OVER.basic
-T| 5 7 OVER . . . CR
--> }T 7 6011851 T=
-T{ OVER.zeros
-T| 0 0 OVER . . . CR
--> }T 7 7986234 T=
-T{ OVER.mixed
-T| -1 42 OVER . . . CR
--> }T 10 1455732 T=
-Block 7011
-T{ OVER.one_item
-T| 42 OVER
-->ERR
-T{ OVER.empty_stack
-T| OVER
-->ERR
-T{ ROT.basic
-T| 1 2 3 ROT . . . CR
--> }T 7 9069952 T=
-T{ ROT.zeros
-T| 0 0 0 ROT . . . CR
--> }T 7 7986234 T=
-T{ ROT.mixed
-T| -1 0 1 ROT . . . CR
--> }T 8 201263 T=
-Block 7012
-T{ ROT.two_items
-T| 1 2 ROT
-->ERR
-T{ ROT.one_item
-T| 42 ROT
-->ERR
-T{ ROT.empty_stack
-T| ROT
-->ERR
-T{ DEPTH.empty
-T| DEPTH . CR
--> }T 3 47130 T=
-T{ DEPTH.one_item
-T| 42 DEPTH . CR
--> 42 }T 3 48091 T=
-Block 7013
-T{ DEPTH.multiple
-T| 1 2 3 DEPTH . CR
--> 1 2 3 }T 3 50013 T=
-T{ PICK.pick_0
-T| 1 2 3 0 PICK . CR
-->ERR
-T{ PICK.pick_1
-T| 1 2 3 1 PICK . CR
--> 1 2 3 }T 3 50013 T=
-T{ PICK.pick_2
-T| 1 2 3 2 PICK . CR
--> 1 2 3 }T 3 49052 T=
-T{ ROLL.roll_1
-T| 1 2 3 1 ROLL . . . CR
--> }T 7 4767936 T=
-Block 7014
-T{ ROLL.roll_2
-T| 1 2 3 2 ROLL . . . CR
--> }T 7 7380224 T=
-T{ ?DUP.nonzero
-T| 42 ?DUP . . CR
--> }T 7 15838026 T=
-T{ ?DUP.negative
-T| -5 ?DUP . . CR
--> }T 7 12677898 T=
-T{ ?DUP.zero
-T| 0 ?DUP DEPTH . CR
--> 0 }T 3 48091 T=
-T{ ?DUP.empty_stack
-T| ?DUP
-->ERR
-Block 7015
-T{ >R.basic
-T| : RS1 42 >R R@ . R> . CR ; RS1
--> }T 7 15838026 T=
-T{ >R.zero
-T| : RS2 0 >R R@ . R> . CR ; RS2
--> }T 5 11775018 T=
-T{ >R.negative
-T| : RS3 -123 >R R@ . R> . CR ; RS3
--> }T 11 14101290 T=
-T{ >R.multiple
-T| : RS4 1 2 >R >R R@ . R> . R@ . R> . CR ; RS4
--> }T 9 12265744 T=
-T{ >R.empty_stack
-T| >R
-->ERR
-Block 7016
-T{ R>.basic
-T| : RS5 42 >R R> . CR ; RS5
--> }T 4 1598184 T=
-T{ R>.lifo_order
-T| : RS6 1 2 >R >R R> . R> . CR ; RS6
--> }T 5 12700461 T=
-T{ R>.empty_rstack
-T| R>
-->ERR
-T{ R@.basic
-T| : RS7 42 >R R@ . R> DROP CR ; RS7
--> }T 4 1598184 T=
-T{ R@.non_destructive
-T| : RS8 99 >R R@ R@ = . R> DROP CR ; RS8
--> }T 4 1388686 T=
-Block 7017
-T{ R@.empty_rstack
-T| R@
-->ERR
-T{ !.basic
-T| 42 HERE ! HERE @ . CR
--> }T 4 1598184 T=
-T{ !.zero
-T| 0 HERE ! HERE @ . CR
--> }T 3 47130 T=
-T{ !.negative
-T| -999 HERE ! HERE @ . CR
--> }T 6 529078 T=
-T{ !.overwrite
-T| 111 HERE ! 222 HERE ! HERE @ . CR
--> }T 5 14160220 T=
-Block 7018
-T{ !.max_int
-T| 2147483647 HERE ! HERE @ . CR
--> }T 12 4848918 T=
-T{ !.min_int
-T| -2147483648 HERE ! HERE @ . CR
--> }T 13 5383556 T=
-T{ !.empty_stack
-T| !
-->ERR
-T{ !.one_item
-T| 42 !
-->ERR
-T{ @.after_store
-T| 123 HERE ! HERE @ . CR
--> }T 5 13237660 T=
-Block 7019
-T{ @.multiple_reads
-T| 456 HERE ! HERE @ HERE @ = . CR
--> }T 4 1388686 T=
-T{ @.empty_stack
-T| @
-->ERR
-T{ ,.basic
-T| 42 , HERE 1 - @ . CR
--> }T 4 1598184 T=
-T{ ,.negative
-T| -999 , HERE 1 - @ . CR
--> }T 6 529078 T=
-T{ HERE.basic
-T| HERE HERE = . CR
--> }T 4 1388686 T=
-Block 7020
-T{ HERE.after_comma
-T| HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP /
--> 0 }T 0 0 T=
-T{ ALLOT.basic
-T| HERE 10 ALLOT HERE SWAP - . CR
--> }T 4 1506889 T=
-T{ ALLOT.zero
-T| HERE 0 ALLOT HERE SWAP - . CR
--> }T 3 47130 T=
-T{ ALLOT.negative
-T| HERE -4 ALLOT HERE SWAP - . CR
--> }T 4 1391569 T=
-T{ PAD.basic
-T| PAD PAD = . CR
--> }T 4 1388686 T=
-Block 7021
-T{ PAD.different_from_here
-T| PAD HERE = . CR
--> }T 3 47130 T=
-T{ +!.basic
-T| 10 HERE ! 5 HERE +! HERE @ . CR
--> }T 4 1511694 T=
-T{ +!.by_zero
-T| 42 HERE ! 0 HERE +! HERE @ . CR
--> }T 4 1598184 T=
-T{ +!.negative
-T| 10 HERE ! -3 HERE +! HERE @ . CR
--> }T 3 53857 T=
-T{ +!.accumulate
-T| 0 HERE ! 1 HERE +! 2 HERE +! 3 HERE +! HERE @ . CR
--> }T 3 52896 T=
-Block 7022
-T{ +!.empty_stack
-T| +!
-->ERR
-T{ FILL.zero_n
-T| HERE 0 88 FILL
--> }T 0 0 T=
-T{ FILL.empty_stack
-T| FILL
-->ERR
-T{ MOVE.basic
-T| 65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ .
-T| HERE 17 + @ . CR
--> }T 7 14525291 T=
-T{ MOVE.zero_n
-T| HERE HERE 8 + 0 MOVE
--> }T 0 0 T=
-Block 7023
-T{ MOVE.empty_stack
-T| MOVE
-->ERR
-T{ +.basic
-T| 5 7 + . CR
--> }T 4 1508811 T=
-T{ +.zero_add
-T| 42 0 + . CR
--> }T 4 1598184 T=
-T{ +.negative
-T| -5 3 + . CR
--> }T 4 1389647 T=
-T{ +.both_negative
-T| -5 -3 + . CR
--> }T 4 1395413 T=
-Block 7024
-T{ +.overflow
-T| 2147483647 1 + . CR
--> }T 12 4849879 T=
-T{ +.underflow
-T| -2147483648 -1 + . CR
--> }T 13 5384517 T=
-T{ +.empty_stack
-T| +
-->ERR
-T{ +.one_item
-T| 42 +
-->ERR
-T{ -.basic
-T| 10 3 - . CR
--> }T 3 53857 T=
-Block 7025
-T{ -.zero_sub
-T| 42 0 - . CR
--> }T 4 1598184 T=
-T{ -.from_zero
-T| 0 5 - . CR
--> }T 4 1392530 T=
-T{ -.negative
-T| 5 -3 - . CR
--> }T 3 54818 T=
-T{ -.same_values
-T| 42 42 - . CR
--> }T 3 47130 T=
-T{ -.overflow
-T| -2147483648 1 - . CR
--> }T 13 5384517 T=
-Block 7026
-T{ -.underflow
-T| 2147483647 -1 - . CR
--> }T 12 4849879 T=
-T{ -.empty_stack
-T| -
-->ERR
-T{ -.one_item
-T| 42 -
-->ERR
-T{ *.basic
-T| 6 7 * . CR
--> }T 4 1598184 T=
-T{ *.by_zero
-T| 42 0 * . CR
--> }T 3 47130 T=
-Block 7027
-T{ *.by_one
-T| 42 1 * . CR
--> }T 4 1598184 T=
-T{ *.by_negative
-T| 6 -7 * . CR
--> }T 5 9602197 T=
-T{ *.negative_negative
-T| -6 -7 * . CR
--> }T 4 1598184 T=
-T{ *.large_numbers
-T| 32767 2 * . CR
--> }T 7 273505 T=
-T{ *.overflow
-T| 65536 65536 * . CR
--> }T 12 6984600 T=
-Block 7028
-T{ *.empty_stack
-T| *
-->ERR
-T{ *.one_item
-T| 42 *
-->ERR
-T{ /.basic
-T| 15 3 / . CR
--> }T 3 51935 T=
-T{ /.by_one
-T| 42 1 / . CR
--> }T 4 1598184 T=
-T{ /.negative_dividend
-T| -15 3 / . CR
--> }T 4 1392530 T=
-Block 7029
-T{ /.negative_divisor
-T| 15 -3 / . CR
--> }T 4 1392530 T=
-T{ /.both_negative
-T| -15 -3 / . CR
--> }T 3 51935 T=
-T{ /.truncation
-T| 7 3 / . CR
--> }T 3 49052 T=
-T{ /.by_zero
-T| 42 0 /
-->ERR
-T{ /.empty_stack
-T| /
-->ERR
-Block 7030
-T{ /.one_item
-T| 42 /
-->ERR
-T{ MOD.basic
-T| 17 5 MOD . CR
--> }T 3 49052 T=
-T{ MOD.exact_division
-T| 15 3 MOD . CR
--> }T 3 47130 T=
-T{ MOD.by_one
-T| 42 1 MOD . CR
--> }T 3 47130 T=
-T{ MOD.negative_dividend
-T| -17 5 MOD . CR
--> }T 4 1389647 T=
-Block 7031
-T{ MOD.negative_divisor
-T| 17 -5 MOD . CR
--> }T 3 49052 T=
-T{ MOD.small_by_large
-T| 3 7 MOD . CR
--> }T 3 50013 T=
-T{ MOD.by_zero
-T| 42 0 MOD
-->ERR
-T{ MOD.empty_stack
-T| MOD
-->ERR
-T{ MOD.one_item
-T| 42 MOD
-->ERR
-Block 7032
-T{ /MOD.basic
-T| 17 5 /MOD . . CR
--> }T 5 14547503 T=
-T{ /MOD.exact
-T| 15 3 /MOD . . CR
--> }T 5 16392623 T=
-T{ /MOD.negative
-T| -17 5 /MOD . . CR
--> }T 7 5748361 T=
-T{ /MOD.by_zero
-T| 42 0 /MOD
-->ERR
-T{ /MOD.empty_stack
-T| /MOD
-->ERR
-Block 7033
-T{ /MOD.one_item
-T| 42 /MOD
-->ERR
-T{ ABS.positive
-T| 42 ABS . CR
--> }T 4 1598184 T=
-T{ ABS.negative
-T| -42 ABS . CR
--> }T 4 1598184 T=
-T{ ABS.zero
-T| 0 ABS . CR
--> }T 3 47130 T=
-T{ ABS.min_int
-T| -2147483648 ABS . CR
--> }T 12 4849879 T=
-Block 7034
-T{ ABS.empty_stack
-T| ABS
-->ERR
-T{ NEGATE.positive
-T| 42 NEGATE . CR
--> }T 5 9602197 T=
-T{ NEGATE.negative
-T| -42 NEGATE . CR
--> }T 4 1598184 T=
-T{ NEGATE.zero
-T| 0 NEGATE . CR
--> }T 3 47130 T=
-T{ NEGATE.min_int
-T| -2147483648 NEGATE . CR
--> }T 12 4849879 T=
-Block 7035
-T{ NEGATE.empty_stack
-T| NEGATE
-->ERR
-T{ MIN.basic
-T| 5 3 MIN . CR
--> }T 3 50013 T=
-T{ MIN.equal
-T| 42 42 MIN . CR
--> }T 4 1598184 T=
-T{ MIN.negative
-T| -5 -3 MIN . CR
--> }T 4 1392530 T=
-T{ MIN.mixed
-T| -1 1 MIN . CR
--> }T 4 1388686 T=
-Block 7036
-T{ MIN.one_item
-T| 42 MIN
-->ERR
-T{ MIN.empty_stack
-T| MIN
-->ERR
-T{ MAX.basic
-T| 5 3 MAX . CR
--> }T 3 51935 T=
-T{ MAX.equal
-T| 42 42 MAX . CR
--> }T 4 1598184 T=
-T{ MAX.negative
-T| -5 -3 MAX . CR
--> }T 4 1390608 T=
-Block 7037
-T{ MAX.mixed
-T| -1 1 MAX . CR
--> }T 3 48091 T=
-T{ MAX.one_item
-T| 42 MAX
-->ERR
-T{ MAX.empty_stack
-T| MAX
-->ERR
-T{ 1+.basic
-T| 5 1+ . CR
--> }T 3 52896 T=
-T{ 1+.zero
-T| 0 1+ . CR
--> }T 3 48091 T=
-Block 7038
-T{ 1+.negative
-T| -1 1+ . CR
--> }T 3 47130 T=
-T{ 1+.chain
-T| 3 1+ 1+ 1+ . CR
--> }T 3 52896 T=
-T{ 1+.overflow
-T| 2147483647 1+ . CR
--> }T 12 4849879 T=
-T{ 1+.empty_stack
-T| 1+
-->ERR
-T{ 1-.basic
-T| 5 1- . CR
--> }T 3 50974 T=
-Block 7039
-T{ 1-.to_zero
-T| 1 1- . CR
--> }T 3 47130 T=
-T{ 1-.to_negative
-T| 0 1- . CR
--> }T 4 1388686 T=
-T{ 1-.chain
-T| 6 1- 1- 1- . CR
--> }T 3 50013 T=
-T{ 1-.underflow
-T| -2147483648 1- . CR
--> }T 13 5384517 T=
-T{ 1-.empty_stack
-T| 1-
-->ERR
-Block 7040
-T{ 2+.basic
-T| 5 2+ . CR
--> }T 3 53857 T=
-T{ 2+.zero
-T| 0 2+ . CR
--> }T 3 49052 T=
-T{ 2+.negative
-T| -3 2+ . CR
--> }T 4 1388686 T=
-T{ 2+.empty_stack
-T| 2+
-->ERR
-T{ 2-.basic
-T| 7 2- . CR
--> }T 3 51935 T=
-Block 7041
-T{ 2-.zero
-T| 2 2- . CR
--> }T 3 47130 T=
-T{ 2-.negative
-T| 0 2- . CR
--> }T 4 1389647 T=
-T{ 2-.empty_stack
-T| 2-
-->ERR
-T{ AND.both_true
-T| -1 -1 AND . CR
--> }T 4 1388686 T=
-T{ AND.first_false
-T| 0 -1 AND . CR
--> }T 3 47130 T=
-Block 7042
-T{ AND.second_false
-T| -1 0 AND . CR
--> }T 3 47130 T=
-T{ AND.both_false
-T| 0 0 AND . CR
--> }T 3 47130 T=
-T{ AND.bitwise
-T| 85 51 AND . CR
--> }T 4 1513616 T=
-T{ AND.empty_stack
-T| AND
-->ERR
-T{ AND.one_item
-T| 42 AND
-->ERR
-Block 7043
-T{ OR.both_true
-T| -1 -1 OR . CR
--> }T 4 1388686 T=
-T{ OR.first_false
-T| 0 -1 OR . CR
--> }T 4 1388686 T=
-T{ OR.second_false
-T| -1 0 OR . CR
--> }T 4 1388686 T=
-T{ OR.both_false
-T| 0 0 OR . CR
--> }T 3 47130 T=
-T{ OR.bitwise
-T| 85 51 OR . CR
--> }T 5 13213635 T=
-Block 7044
-T{ OR.empty_stack
-T| OR
-->ERR
-T{ OR.one_item
-T| 42 OR
-->ERR
-T{ XOR.both_true
-T| -1 -1 XOR . CR
--> }T 3 47130 T=
-T{ XOR.first_false
-T| 0 -1 XOR . CR
--> }T 4 1388686 T=
-T{ XOR.second_false
-T| -1 0 XOR . CR
--> }T 4 1388686 T=
-Block 7045
-T{ XOR.both_false
-T| 0 0 XOR . CR
--> }T 3 47130 T=
-T{ XOR.bitwise
-T| 85 51 XOR . CR
--> }T 5 13177117 T=
-T{ XOR.empty_stack
-T| XOR
-->ERR
-T{ XOR.one_item
-T| 42 XOR
-->ERR
-T{ NOT.true
-T| -1 NOT . CR
--> }T 3 47130 T=
-Block 7046
-T{ NOT.false
-T| 0 NOT . CR
--> }T 4 1388686 T=
-T{ NOT.positive
-T| 42 NOT . CR
--> }T 3 47130 T=
-T{ NOT.negative
-T| -42 NOT . CR
--> }T 3 47130 T=
-T{ NOT.empty_stack
-T| NOT
-->ERR
-T{ =.equal
-T| 42 42 = . CR
--> }T 4 1388686 T=
-Block 7047
-T{ =.not_equal
-T| 42 43 = . CR
--> }T 3 47130 T=
-T{ =.zero_equal
-T| 0 0 = . CR
--> }T 4 1388686 T=
-T{ =.negative_equal
-T| -42 -42 = . CR
--> }T 4 1388686 T=
-T{ =.negative_positive
-T| -42 42 = . CR
--> }T 3 47130 T=
-T{ =.empty_stack
-T| =
-->ERR
-Block 7048
-T{ =.one_item
-T| 42 =
-->ERR
-T{ <.less_than
-T| 5 7 < . CR
--> }T 4 1388686 T=
-T{ <.greater_than
-T| 7 5 < . CR
--> }T 3 47130 T=
-T{ <.equal
-T| 5 5 < . CR
--> }T 3 47130 T=
-T{ <.negative_positive
-T| -5 5 < . CR
--> }T 4 1388686 T=
-Block 7049
-T{ <.negative_negative
-T| -7 -5 < . CR
--> }T 4 1388686 T=
-T{ <.empty_stack
-T| <
-->ERR
-T{ <.one_item
-T| 42 <
-->ERR
-T{ >.greater_than
-T| 7 5 > . CR
--> }T 4 1388686 T=
-T{ >.less_than
-T| 5 7 > . CR
--> }T 3 47130 T=
-Block 7050
-T{ >.equal
-T| 5 5 > . CR
--> }T 3 47130 T=
-T{ >.positive_negative
-T| 5 -5 > . CR
--> }T 4 1388686 T=
-T{ >.negative_negative
-T| -5 -7 > . CR
--> }T 4 1388686 T=
-T{ >.empty_stack
-T| >
-->ERR
-T{ >.one_item
-T| 42 >
-->ERR
-Block 7051
-T{ 0=.zero
-T| 0 0= . CR
--> }T 4 1388686 T=
-T{ 0=.positive
-T| 42 0= . CR
--> }T 3 47130 T=
-T{ 0=.negative
-T| -42 0= . CR
--> }T 3 47130 T=
-T{ 0=.empty_stack
-T| 0=
-->ERR
-T{ 0<.negative
-T| -42 0< . CR
--> }T 4 1388686 T=
-Block 7052
-T{ 0<.zero
-T| 0 0< . CR
--> }T 3 47130 T=
-T{ 0<.positive
-T| 42 0< . CR
--> }T 3 47130 T=
-T{ 0<.empty_stack
-T| 0<
-->ERR
-T{ 0>.positive
-T| 42 0> . CR
--> }T 4 1388686 T=
-T{ 0>.zero
-T| 0 0> . CR
--> }T 3 47130 T=
-Block 7053
-T{ 0>.negative
-T| -42 0> . CR
--> }T 3 47130 T=
-T{ 0>.empty_stack
-T| 0>
-->ERR
-T{ U<.less
-T| 3 5 U< . CR
--> }T 4 1388686 T=
-T{ U<.equal
-T| 5 5 U< . CR
--> }T 3 47130 T=
-T{ U<.greater
-T| 7 5 U< . CR
--> }T 3 47130 T=
-Block 7054
-T{ U<.zero_one
-T| 0 1 U< . CR
--> }T 4 1388686 T=
-T{ U<.empty_stack
-T| U<
-->ERR
-T{ */.basic
-T| 6 7 4 */ . CR
--> }T 4 1506889 T=
-T{ */.exact_division
-T| 12 5 3 */ . CR
--> }T 4 1536680 T=
-T{ */.zero_multiply
-T| 0 999 123 */ . CR
--> }T 3 47130 T=
-Block 7055
-T{ */.by_one
-T| 42 5 1 */ . CR
--> }T 5 14128507 T=
-T{ */.truncation
-T| 7 3 2 */ . CR
--> }T 4 1506889 T=
-T{ */.negative_multiply
-T| -6 7 4 */ . CR
--> }T 5 9510902 T=
-T{ */.negative_divisor
-T| 6 7 -4 */ . CR
--> }T 5 9510902 T=
-T{ */.div_by_zero
-T| 6 7 0 */
-->ERR
-Block 7056
-T{ */.empty_stack
-T| */
-->ERR
-T{ */.two_items
-T| 1 2 */
-->ERR
-T{ */MOD.basic
-T| 17 3 5 */MOD . . CR
--> }T 6 5318234 T=
-T{ */MOD.exact_division
-T| 15 4 3 */MOD . . CR
--> }T 6 391992 T=
-T{ */MOD.zero_multiply
-T| 0 999 123 */MOD . . CR
--> }T 5 11775018 T=
-Block 7057
-T{ */MOD.by_one
-T| 42 5 1 */MOD . . CR
--> }T 7 4765003 T=
-T{ */MOD.remainder
-T| 7 8 5 */MOD . . CR
--> }T 6 6241755 T=
-T{ */MOD.negative
-T| -7 3 4 */MOD . . CR
--> }T 7 12674054 T=
-T{ */MOD.div_by_zero
-T| 6 7 0 */MOD
-->ERR
-T{ */MOD.empty_stack
-T| */MOD
-->ERR
-Block 7058
-T{ D+.basic
-T| 100 200 300 400 D+ . . CR
--> }T 9 6378548 T=
-T{ D+.zero_add
-T| 42 99 0 0 D+ . . CR
--> }T 7 6471656 T=
-T{ D+.negative
-T| -100 -200 50 75 D+ . . CR
--> }T 10 13971193 T=
-T{ D+.carry
-T| 2147483647 0 1 0 D+ . . CR
--> }T 14 4234951 T=
-T{ D+.both_negative
-T| -100 -200 -300 -400 D+ . . CR
--> }T 11 5003369 T=
-Block 7059
-T{ D+.three_items
-T| 1 2 3 D+
-->ERR
-T{ D+.empty_stack
-T| D+
-->ERR
-T{ DNEGATE.positive
-T| 100 200 DNEGATE . . CR
--> }T 11 13922440 T=
-T{ DNEGATE.negative
-T| -100 -200 DNEGATE . . CR
--> }T 9 14912460 T=
-T{ DNEGATE.zero
-T| 0 0 DNEGATE . . CR
--> }T 5 11775018 T=
-Block 7060
-T{ DNEGATE.max_positive
-T| 2147483647 0 DNEGATE . . CR
--> }T 16 11447367 T=
-T{ DNEGATE.one_item
-T| 42 DNEGATE
-->ERR
-T{ DNEGATE.empty_stack
-T| DNEGATE
-->ERR
-T{ D<.less_than
-T| 100 200 300 400 D< . CR
--> }T 4 1388686 T=
-T{ D<.greater_than
-T| 300 400 100 200 D< . CR
--> }T 3 47130 T=
-Block 7061
-T{ D<.equal
-T| 100 200 100 200 D< . CR
--> }T 3 47130 T=
-T{ D<.negative_positive
-T| -100 -1 100 0 D< . CR
--> }T 4 1388686 T=
-T{ D<.negative_negative
-T| -300 -1 -100 -1 D< . CR
--> }T 4 1388686 T=
-T{ D<.high_word_diff
-T| 100 200 100 300 D< . CR
--> }T 4 1388686 T=
-T{ D<.three_items
-T| 1 2 3 D<
-->ERR
-Block 7062
-T{ D<.empty_stack
-T| D<
-->ERR
-T{ BASE.decimal
-T| DECIMAL 42 . CR
--> }T 4 1598184 T=
-T{ BASE.hex
-T| HEX FF . CR
--> }T 4 2153642 T=
-T{ BASE.octal
-T| OCTAL 52 . CR
--> }T 4 1627975 T=
-T{ BASE.base_store
-T| 16 BASE ! 255 . CR
--> }T 5 14252476 T=
-Block 7063
-T{ BASE.base_fetch
-T| BASE @ . CR
--> }T 4 1506889 T=
-T{ DECIMAL.from_hex
-T| HEX FF DECIMAL . CR
--> }T 5 14252476 T=
-T{ DECIMAL.from_octal
-T| OCTAL 52 DECIMAL . CR
--> }T 4 1598184 T=
-T{ DECIMAL.state_persist
-T| DECIMAL 42 . CR 42 . CR HEX 42 . CR
--> }T 12 9440440 T=
-T{ <#.basic
-T| DECIMAL 42 S>D <# #S #> TYPE CR
--> }T 3 51532 T=
-Block 7064
-T{ <#.empty
-T| 0 0 <# #> TYPE CR
--> }T 1 10 T=
-T{ <#.negative
-T| -42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR
--> }T 4 1392127 T=
-T{ #.single_digit
-T| 15 0 <# # #> TYPE CR
--> }T 2 1653 T=
-T{ #.multiple
-T| 15 0 <# # # #> TYPE CR
--> }T 3 48742 T=
-T{ #.zero_pad
-T| 5 0 <# # # #> TYPE CR
--> }T 3 47781 T=
-Block 7065
-T{ #S.basic
-T| 42 0 <# #S #> TYPE CR
--> }T 3 51532 T=
-T{ #S.zero
-T| 0 0 <# #S #> TYPE CR
--> }T 2 1498 T=
-T{ #S.large
-T| 1234567890 0 <# #S #> TYPE CR
--> }T 11 7265487 T=
-T{ SIGN.negative
-T| -42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR
--> }T 4 1392127 T=
-T{ SIGN.positive
-T| 42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR
--> }T 3 51532 T=
-Block 7066
-T{ SIGN.zero
-T| 0 DUP ABS 0 <# #S ROT SIGN #> TYPE CR
--> }T 2 1498 T=
-T{ #>.normal
-T| 42 0 <# #S #> TYPE CR
--> }T 3 51532 T=
-T{ #>.empty
-T| 0 0 <# #> TYPE CR
--> }T 1 10 T=
-T{ #>.stack_effect
-T| 42 0 <# #S #> SWAP DROP . CR
--> }T 3 49052 T=
-T{ HOLD.basic
-T| 42 0 <# 46 HOLD #S #> TYPE CR
--> }T 4 1598618 T=
-Block 7067
-T{ HOLD.overflow
-T| <# 257 HOLD #>
-->ERR
-T{ COUNT.basic
-T| 4 PAD C! PAD COUNT . PAD - . CR
--> }T 5 15470063 T=
-T{ COUNT.empty
-T| 0 PAD C! PAD COUNT . PAD - . CR
--> }T 5 11775979 T=
-T{ COUNT.max_length
-T| 255 PAD C! PAD COUNT . PAD - . CR
--> }T 7 6459661 T=
-T{ COUNT.empty_stack
-T| COUNT
-->ERR
-Block 7068
-T{ -TRAILING.basic
-T| HERE S" Test " -TRAILING TYPE CR
--> 1 }TD 6 6975864 T=
-T{ -TRAILING.all_spaces
-T| HERE S" " -TRAILING TYPE CR
--> 1 }TD 1 10 T=
-T{ -TRAILING.no_spaces
-T| HERE S" Test" -TRAILING TYPE CR
--> 1 }TD 5 13589912 T=
-T{ -TRAILING.empty
-T| HERE 0 -TRAILING TYPE CR
--> }T 1 10 T=
-T{ CMOVE.basic
-T| 65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD
-T| 11 + C@ . CR
--> }T 7 14525291 T=
-Block 7069
-T{ CMOVE.empty
-T| HERE HERE 10 + 0 CMOVE
--> }T 0 0 T=
-T{ >IN.initial
-T| >IN @ . CR
--> }T 3 55779 T=
-T{ >IN.advances
-T| : TWIN >IN @ >IN @ - . CR ; TWIN
--> }T 3 47130 T=
-T{ ..positive
-T| 42 . CR
--> }T 4 1598184 T=
-T{ ..negative
-T| -42 . CR
--> }T 5 9602197 T=
-Block 7070
-T{ ..zero
-T| 0 . CR
--> }T 3 47130 T=
-T{ ..max_int
-T| 2147483647 . CR
--> }T 12 4848918 T=
-T{ ..min_int
-T| -2147483648 . CR
--> }T 13 5383556 T=
-T{ ..multiple
-T| 1 2 3 . . . CR
--> }T 7 4767936 T=
-T{ ..empty_stack
-T| .
-->ERR
-Block 7071
-T{ CR.basic
-T| 42 . CR 43 . CR
--> }T 8 16061841 T=
-T{ CR.multiple
-T| CR CR CR
--> }T 3 9930 T=
-T{ CR.no_stack_effect
-T| DEPTH CR DEPTH = . CR
--> }T 4 345040 T=
-T{ CR.after_output
-T| 1 2 3 . . . CR
--> }T 7 4767936 T=
-T{ SPACE.basic
-T| 42 . SPACE 43 . CR
--> }T 8 2824871 T=
-Block 7072
-T{ SPACE.multiple
-T| SPACE SPACE SPACE
--> }T 3 31776 T=
-T{ SPACE.no_stack_effect
-T| DEPTH SPACE DEPTH = . CR
--> }T 4 1000442 T=
-T{ SPACE.with_text
-T| 65 EMIT SPACE 66 EMIT CR
--> }T 4 1969223 T=
-T{ SPACES.zero
-T| 0 SPACES
--> }T 0 0 T=
-T{ SPACES.one
-T| 1 SPACES
--> }T 1 32 T=
-Block 7073
-T{ SPACES.multiple
-T| 5 SPACES
--> }T 5 13760544 T=
-T{ SPACES.large
-T| 20 SPACES
--> }T 20 10692608 T=
-T{ SPACES.negative
-T| -5 SPACES
--> }T 0 0 T=
-T{ SPACES.with_output
-T| 42 . 3 SPACES 43 . CR
--> }T 10 11278119 T=
-T{ SPACES.empty_stack
-T| SPACES
-->ERR
-Block 7074
-T{ EMIT.letter_A
-T| 65 EMIT CR
--> }T 2 2025 T=
-T{ EMIT.letter_Z
-T| 90 EMIT CR
--> }T 2 2800 T=
-T{ EMIT.digit
-T| 48 EMIT CR
--> }T 2 1498 T=
-T{ EMIT.space_char
-T| 32 EMIT CR
--> }T 2 1002 T=
-T{ EMIT.newline
-T| 10 EMIT
--> }T 1 10 T=
-Block 7075
-T{ EMIT.high_ascii
-T| 127 EMIT CR
--> }T 2 3947 T=
-T{ EMIT.truncation
-T| 321 EMIT CR
--> }T 2 2025 T=
-T{ EMIT.negative
-T| -1 EMIT CR
--> }T 2 7915 T=
-T{ EMIT.sequence
-T| 72 EMIT 73 EMIT 10 EMIT
--> }T 3 71465 T=
-T{ EMIT.empty_stack
-T| EMIT
-->ERR
-Block 7076
-T{ TYPE.basic_string
-T| 72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR
--> }T 3 72457 T=
-T{ TYPE.empty_string
-T| HERE 0 TYPE CR
--> }T 1 10 T=
-T{ TYPE.numbers
-T| 49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR
--> }T 3 48649 T=
-T{ TYPE.zero_length
-T| PAD 0 TYPE
--> }T 0 0 T=
-T{ TYPE.one_item
-T| PAD TYPE
-->ERR
-Block 7077
-T{ TYPE.empty_stack
-T| TYPE
-->ERR
-T{ COUNT.basic~2
-T| 4 PAD C! PAD COUNT . PAD - . CR
--> }T 5 15470063 T=
-T{ COUNT.empty~2
-T| 0 PAD C! PAD COUNT . PAD - . CR
--> }T 5 11775979 T=
-T{ COUNT.max_length~2
-T| 255 PAD C! PAD COUNT . PAD - . CR
--> }T 7 6459661 T=
-T{ COUNT.empty_stack~2
-T| COUNT
-->ERR
-Block 7078
-T{ WORD.empty_stack
-T| WORD
-->ERR
-T{ BLOCK.basic
-T| 1 BLOCK DUP . CR
--> 1 }TD
-T{ BLOCK.zero_block
-T| 0 BLOCK
-->ERR
-T{ BLOCK.large_block
-T| 65536 BLOCK
-->ERR
-T{ BLOCK.negative
-T| -1 BLOCK
-->ERR
-Block 7079
-T{ BLOCK.empty_stack
-T| BLOCK
-->ERR
-T{ BUFFER.basic
-T| 1 BUFFER DUP . CR
--> 1 }TD
-T{ BUFFER.zero_block
-T| 0 BUFFER
-->ERR
-T{ BUFFER.flush_dirty
-T| 2 BLOCK 1+ 2 BUFFER
--> 2 }TD 0 0 T=
-T{ BUFFER.empty_stack
-T| BUFFER
-->ERR
-Block 7080
-T{ UPDATE.basic
-T| 1 BLOCK UPDATE
--> 1 }TD 0 0 T=
-T{ UPDATE.multiple
-T| 1 BLOCK UPDATE UPDATE
--> 1 }TD 0 0 T=
-T{ UPDATE.no_block
-T| 0 SCR ! UPDATE
--> }T 0 0 T=
-T{ SAVE-BUFFERS.basic
-T| SAVE-BUFFERS
--> }T 0 0 T=
-T{ SAVE-BUFFERS.dirty_blocks
-T| 1 BLOCK UPDATE SAVE-BUFFERS
--> 1 }TD 0 0 T=
-Block 7081
-T{ SAVE-BUFFERS.no_dirty
-T| SAVE-BUFFERS
--> }T 0 0 T=
-T{ EMPTY-BUFFERS.basic
-T| EMPTY-BUFFERS
--> }T 0 0 T=
-T{ EMPTY-BUFFERS.after_use
-T| 1 BLOCK EMPTY-BUFFERS
--> 1 }TD 0 0 T=
-T{ EMPTY-BUFFERS.dirty_blocks
-T| 1 BLOCK UPDATE EMPTY-BUFFERS
--> 1 }TD 0 0 T=
-T{ LOAD.basic
-T| 1 LOAD
--> }T 0 0 T=
-Block 7082
-T{ LOAD.zero_block
-T| 0 LOAD
-->ERR
-T{ LOAD.nonexistent
-T| 9999 LOAD
-->ERR
-T{ LOAD.empty_stack
-T| LOAD
-->ERR
-T{ LIST.basic
-T| 1 LIST
--> 0 }TD
-T{ LIST.zero_block
-T| 0 LIST
-->ERR
-Block 7083
-T{ LIST.nonexistent
-T| 9999 LIST
-->ERR
-T{ LIST.empty_stack
-T| LIST
-->ERR
-T{ SCR.basic
-T| SCR @ . CR
--> }T 3 48091 T=
-T{ SCR.after_list
-T| 1 LIST SCR @ . CR
--> 0 }TD
-T{ SCR.after_load
-T| 1 LOAD SCR @ . CR
--> }T 3 48091 T=
-Block 7084
-T{ HERE.basic~2
-T| HERE HERE = . CR
--> }T 4 1388686 T=
-T{ HERE.after_comma~2
-T| HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP /
--> 0 }T 0 0 T=
-T{ HERE.after_c_comma
-T| HERE 65 C, HERE SWAP - . CR
--> }T 3 48091 T=
-T{ HERE.after_allot
-T| HERE 10 ALLOT HERE SWAP - . CR
--> }T 4 1506889 T=
-T{ HERE.stability
-T| HERE DUP HERE = . CR
--> 1 }TD 4 1388686 T=
-Block 7085
-T{ ALLOT.basic~2
-T| HERE 10 ALLOT HERE SWAP - . CR
--> }T 4 1506889 T=
-T{ ALLOT.zero~2
-T| HERE 0 ALLOT HERE SWAP - . CR
--> }T 3 47130 T=
-T{ ALLOT.negative~2
-T| HERE -4 ALLOT HERE SWAP - . CR
--> }T 4 1391569 T=
-T{ ALLOT.large
-T| HERE 100 ALLOT HERE SWAP - . CR
--> }T 5 13175195 T=
-T{ ALLOT.after_use
-T| ALIGN HERE 10 ALLOT 42 OVER ! @ . CR
--> }T 4 1598184 T=
-Block 7086
-T{ ALLOT.empty_stack
-T| ALLOT
-->ERR
-T{ ,.basic~2
-T| 42 , HERE 1 CELLS - @ . CR
--> }T 4 1598184 T=
-T{ ,.negative~2
-T| -999 , HERE 1 CELLS - @ . CR
--> }T 6 529078 T=
-T{ ,.zero
-T| 0 , HERE 1 CELLS - @ . CR
--> }T 3 47130 T=
-T{ ,.max_int
-T| 2147483647 , HERE 1 CELLS - @ . CR
--> }T 12 4848918 T=
-Block 7087
-T{ ,.min_int
-T| -2147483648 , HERE 1 CELLS - @ . CR
--> }T 13 5383556 T=
-T{ ,.multiple
-T| 10 , 20 , HERE 1 CELLS - @ . HERE 1 CELLS - @ . CR
--> }T 7 12227402 T=
-T{ ,.empty_stack
-T| ,
-->ERR
-T{ PAD.basic~2
-T| PAD PAD = . CR
--> }T 4 1388686 T=
-T{ PAD.different_from_here~2
-T| PAD HERE = . CR
--> }T 3 47130 T=
-Block 7088
-T{ PAD.stability
-T| PAD DUP PAD = . CR
--> 1 }TD 4 1388686 T=
-T{ CREATE.basic
-T| CREATE test1 42 , test1 @ . CR
--> }T 4 1598184 T=
-T{ CREATE.empty_name
-T| CREATE
-->ERR
-T{ CREATE.redefine_shadows
-T| CREATE T 1 , CREATE T 2 , T @ . CR
--> }T 3 49052 T=
-T{ CREATE.duplicate
-T| CREATE test2 CREATE test2
--> }T 0 0 T=
-Block 7089
-T{ CREATE.long_name
-T| CREATE abcdefghijklmnopqrstuvwxyz
--> }T 0 0 T=
-T{ FORGET.basic
-T| CREATE temp1 FORGET temp1
--> }T 0 0 T=
-T{ IMMEDIATE.basic
-T| : test3 42 ; IMMEDIATE test3 . CR
--> }T 4 1598184 T=
-T{ IMMEDIATE.already_immediate
-T| : test4 43 ; IMMEDIATE IMMEDIATE
--> }T 0 0 T=
-T{ FIND.existing
-T| FIND DUP . CR
--> 0 }TD
-Block 7090
-T{ FIND.user_word
-T| : test5 44 ; FIND test5 . CR
--> 0 }TD
-T{ FIND.nonexistent
-T| FIND nonexistent . CR
--> }T 3 47130 T=
-T{ FIND.empty
-T| FIND
--> 0 }T 0 0 T=
-T{ DEFINITIONS.basic
-T| FORTH DEFINITIONS
--> }T 0 0 T=
-T{ DEFINITIONS.multiple
-T| FORTH DEFINITIONS DEFINITIONS
--> }T 0 0 T=
-Block 7091
-T{ VOCABULARY.basic
-T| VOCABULARY TEST-VOC1 TEST-VOC1 DEFINITIONS
--> }T 0 0 T=
-T{ VOCABULARY.create_and_switch
-T| VOCABULARY MYVOC MYVOC DEFINITIONS CONTEXT @ . CR
--> 0 }TD
-T{ VOCABULARY.word_isolation
-T| VOCABULARY ISOLATED ISOLATED DEFINITIONS : ISOWORD 99 ; FORTH
-T| DEFINITIONS
--> }T 0 0 T=
-T{ VOCABULARY.cross_vocab_access
-T| VOCABULARY V1 V1 DEFINITIONS : V1WORD 11 ; FORTH V1WORD . CR
-->ERR
-T{ VOCABULARY.multiple_vocabs
-T| VOCABULARY VA VOCABULARY VB VOCABULARY VC VA DEFINITIONS
--> }T 0 0 T=
-Block 7092
-T{ VOCABULARY.duplicate
-T| VOCABULARY TESTVOC VOCABULARY TESTVOC
--> }T 0 0 T=
-T{ VOCABULARY.empty_name
-T| VOCABULARY
-->ERR
-T{ FORTH.basic
-T| FORTH DEFINITIONS
--> }T 0 0 T=
-T{ FORTH.persistence
-T| FORTH : TEST1 42 ; TEST1 . CR
--> }T 4 1598184 T=
-T{ FORTH.from_other
-T| VOCABULARY OTHER-VOC OTHER-VOC FORTH
--> }T 0 0 T=
-Block 7093
-T{ DEFINITIONS.basic~2
-T| FORTH DEFINITIONS
--> }T 0 0 T=
-T{ DEFINITIONS.new_vocab
-T| VOCABULARY TEST-VOC6 TEST-VOC6 DEFINITIONS
--> }T 0 0 T=
-T{ DEFINITIONS.word_creation
-T| VOCABULARY TEST-VOC7 TEST-VOC7 DEFINITIONS : TEST2 43 ;
--> }T 0 0 T=
-T{ CONTEXT.basic
-T| CONTEXT @ . CR
--> 0 }TD
-T{ CONTEXT.initial
-T| FORTH CONTEXT @ . CR
--> 0 }TD
-Block 7094
-T{ CURRENT.basic
-T| CURRENT @ . CR
--> 0 }TD
-T{ CURRENT.after_def
-T| VOCABULARY TEST-VOC8 TEST-VOC8 DEFINITIONS CURRENT @ . CR
--> 0 }TD
-T{ ABORT.basic
-T| ABORT
--> }T 0 0 T=
-T{ ABORT.with_data
-T| 1 2 3 ABORT DEPTH . CR
--> }T 0 0 T=
-T{ ABORT.in_definition_runtime
-T| : BAD-WORD ABORT ; 123 BAD-WORD DEPTH . CR
--> }T 0 0 T=
-Block 7095
-T{ :.basic
-T| : TEST1 42 ; TEST1 . CR
--> }T 4 1598184 T=
-T{ :.empty_name
-T| :
-->ERR
-T{ ;.alone
-T| ;
-->ERR
-T{ ;.immediate
-T| : TEST4 42 ; IMMEDIATE TEST4 . CR
--> }T 4 1598184 T=
-T{ CONSTANT.basic
-T| 42 CONSTANT MEANING MEANING . CR
--> }T 4 1598184 T=
-Block 7096
-T{ CONSTANT.zero
-T| 0 CONSTANT ZERO ZERO . CR
--> }T 3 47130 T=
-T{ CONSTANT.negative
-T| -1 CONSTANT MINUS MINUS . CR
--> }T 4 1388686 T=
-T{ CONSTANT.empty_stack
-T| CONSTANT
-->ERR
-T{ VARIABLE.basic
-T| VARIABLE VAR1 42 VAR1 ! VAR1 @ . CR
--> }T 4 1598184 T=
-T{ VARIABLE.multiple
-T| VARIABLE VAR2 VARIABLE VAR3
--> }T 0 0 T=
-Block 7097
-T{ VARIABLE.store_fetch
-T| VARIABLE VAR4 -99 VAR4 ! VAR4 @ . CR
--> }T 5 9757879 T=
-T{ CREATE.basic~2
-T| CREATE OBJ1
--> }T 0 0 T=
-T{ CREATE.with_data
-T| CREATE OBJ2 42 , OBJ2 @ . CR
--> }T 4 1598184 T=
-T{ CREATE.empty_name~2
-T| CREATE
-->ERR
-T{ DOES>.basic
-T| : CONST CREATE , DOES> @ ; 42 CONST MEANING MEANING . CR
--> }T 4 1598184 T=
-Block 7098
-T{ DOES>.multiple
-T| : ARRAY CREATE DOES> SWAP CELLS + ; CREATE ARR 10 CELLS ALLOT
--> }T 0 0 T=
-T{ DOES>.outside
-T| DOES>
-->ERR
-T{ [.basic
-T| : TEST5 [ 42 ] LITERAL ; TEST5 . CR
--> }T 4 1598184 T=
-T{ [.outside
-T| [
--> }T 0 0 T=
-T{ ].nested
-T| : TEST6 [ ] 42 ; TEST6 . CR
--> }T 4 1598184 T=
-Block 7099
-T{ IF.true
-T| : TEST1 IF 42 ELSE 24 THEN ; -1 TEST1 . CR
--> }T 4 1598184 T=
-T{ IF.false
-T| : TEST2 IF 42 ELSE 24 THEN ; 0 TEST2 . CR
--> }T 4 1540524 T=
-T{ IF.nested
-T| : TEST3 IF IF 1 ELSE 2 THEN ELSE 3 THEN ; -1 -1 TEST3 . CR
--> }T 3 48091 T=
-T{ IF.no_else
-T| : TEST4 IF 42 THEN ; -1 TEST4 . CR
--> }T 4 1598184 T=
-T{ IF.empty_stack
-T| IF
-->ERR
-Block 7100
-T{ ELSE.alone
-T| ELSE
-->ERR
-T{ THEN.alone
-T| THEN
-->ERR
-T{ BEGIN.until
-T| : TEST5 0 BEGIN 1+ DUP 5 = UNTIL ; TEST5 . CR
--> }T 3 51935 T=
-T{ BEGIN.while
-T| : TEST6 0 BEGIN DUP 5 < WHILE 1+ REPEAT ; TEST6 . CR
--> }T 3 51935 T=
-T{ BEGIN.alone
-T| BEGIN
-->ERR
-Block 7101
-T{ UNTIL.basic
-T| : TEST8 BEGIN DUP 1- DUP 0= UNTIL ; 5 TEST8 . CR
--> 5 4 3 2 1 }T 3 47130 T=
-T{ UNTIL.immediate
-T| : TEST9 BEGIN 1 UNTIL ; IMMEDIATE
--> }T 0 0 T=
-T{ UNTIL.no_begin
-T| UNTIL
-->ERR
-T{ WHILE.basic
-T| : TEST10 BEGIN DUP 5 < WHILE 1+ REPEAT ; 0 TEST10 . CR
--> }T 3 51935 T=
-T{ WHILE.zero_times
-T| : TEST11 BEGIN DUP 0< WHILE 1+ REPEAT ; 0 TEST11 . CR
--> }T 3 47130 T=
-Block 7102
-T{ WHILE.no_begin
-T| WHILE
-->ERR
-T{ REPEAT.basic
-T| : TEST12 BEGIN DUP 5 < WHILE 1+ REPEAT ; 0 TEST12 . CR
--> }T 3 51935 T=
-T{ REPEAT.no_while
-T| REPEAT
-->ERR
-T{ DO.basic
-T| : TEST13 5 0 DO I . LOOP ; TEST13 CR
--> }T 11 12528484 T=
-T{ DO.negative
-T| : TEST14 -1 -5 DO I . LOOP ; TEST14 CR
--> }T 13 11696776 T=
-Block 7103
-T{ DO.empty
-T| : TEST15 0 0 DO LOOP ;
--> }T 0 0 T=
-T{ DO.nested
-T| : TEST16 3 0 DO 3 0 DO J I + . LOOP LOOP ; TEST16 CR
--> }T 19 14426156 T=
-T{ LOOP.basic
-T| : TEST20 5 0 DO I . LOOP ; TEST20 CR
--> }T 11 12528484 T=
-T{ LOOP.no_do
-T| LOOP
-->ERR
-T{ +LOOP.basic
-T| : TEST21 10 0 DO I . 2 +LOOP ; TEST21 CR
--> }T 11 16410222 T=
-Block 7104
-T{ +LOOP.negative
-T| : TEST22 0 10 DO I . -1 +LOOP ; TEST22 CR
--> }T 24 15411990 T=
-T{ +LOOP.variable
-T| : TEST23 10 0 DO I . DUP +LOOP ; 3 TEST23 CR
--> 3 }T 9 8104156 T=
-T{ I.basic
-T| : TI 4 0 DO I . LOOP CR ; TI
--> }T 9 7781840 T=
-T{ I.single
-T| : TI1 1 0 DO I . LOOP CR ; TI1
--> }T 3 47130 T=
-T{ I.offset
-T| : TI2 5 3 DO I . LOOP CR ; TI2
--> }T 5 14549425 T=
-Block 7105
-T{ I.in_expr
-T| : TI3 3 0 DO I 2 * . LOOP CR ; TI3
--> }T 7 9837120 T=
-T{ J.basic
-T| : TJ 2 0 DO 3 0 DO J . LOOP LOOP CR ; TJ
--> }T 13 4074221 T=
-T{ J.paired
-T| : TJ2 2 0 DO 2 0 DO J I + . LOOP LOOP CR ; TJ2
--> }T 9 6857358 T=
-T{ EXIT.early_return
-T| : TEX 5 EXIT 99 ; TEX . CR
--> }T 3 51935 T=
-T{ EXIT.cond_exit_pos
-T| : TEX2 DUP 0> IF EXIT THEN NEGATE ; 3 TEX2 . CR
--> }T 3 50013 T=
-Block 7106
-T{ EXIT.cond_exit_neg
-T| : TEX2 DUP 0> IF EXIT THEN NEGATE ; -4 TEX2 . CR
--> }T 3 50974 T=
-T{ EXIT.no_skipped
-T| : TEX3 1 2 EXIT 3 ; TEX3 . . CR
--> }T 5 13623021 T=
-T{ LEAVE.basic
-T| : TLV 0 5 0 DO I 3 = IF LEAVE THEN 1+ LOOP ; TLV . CR
--> }T 3 50974 T=
-T{ LEAVE.at_start
-T| : TLV2 0 5 0 DO LEAVE 1+ LOOP ; TLV2 . CR
--> }T 3 48091 T=
-T{ LEAVE.qdloop
-T| : TLV3 0 5 0 ?DO I 2 = IF LEAVE THEN 1+ LOOP ; TLV3 . CR
--> }T 3 50013 T=
-Block 7107
-T{ U*.small
-T| 3 4 U* . . CR
--> }T 6 12751803 T=
-T{ U*.zero
-T| 0 5 U* . . CR
--> }T 5 11775018 T=
-T{ U*.full
-T| -1 -1 U* 2+ . 1 = . CR
--> }T 6 12631678 T=
-T{ U/MOD.small
-T| 7 0 2 U/MOD . . CR
--> }T 5 14546542 T=
-T{ U/MOD.exact
-T| 12 0 4 U/MOD . . CR
--> }T 5 14545581 T=
-Block 7108
-T{ U/MOD.double
-T| 0 1 2 U/MOD 2* . . CR
--> }T 5 11775018 T=
-T{ U/MOD.inverse
-T| -1 -1 U* -1 U/MOD 1+ . . CR
--> }T 5 11775018 T=
-T{ U/MOD.carry
-T| -1 -2 -1 U/MOD 1+ . 2+ . CR
--> }T 5 11775018 T=
-T{ U/MOD.by_zero
-T| 1 0 0 U/MOD
-->ERR
-T{ ?.basic
-T| VARIABLE Q1 42 Q1 ! Q1 ? CR
--> }T 4 1598184 T=
-Block 7109
-T{ EXECUTE.found
-T| : E1 7 ; FIND E1 EXECUTE . CR
--> }T 3 53857 T=
-T{ U..small
-T| 42 U. CR
--> }T 4 1598184 T=
-T{ U..unsigned
-T| -1 U. CR
--> }T 22 3892143 T=
-T{ CONVERT.digits
-T| : C1 0 0 BL WORD CONVERT DROP ; C1 123 . . CR
--> }T 7 9448876 T=
-T{ '.found
-T| ' DUP 0= . CR
--> }T 3 47130 T=
-Block 7110
-T{ .".in_definition
-T| : Q3 ." hi there" ; Q3 CR
--> }T 9 13319717 T=
-T{ LITERAL.basic
-T| : Q4 [ 5 ] LITERAL ; Q4 . CR
--> }T 3 51935 T=
-T{ STATE.interpreting
-T| STATE @ . CR
--> }T 3 47130 T=
-T{ STATE.compiling
-T| : Q5 STATE @ 0= . ; IMMEDIATE : Q6 Q5 ; CR
--> }T 3 47130 T=
-T{ COMPILE.basic
-T| : Q7 COMPILE DUP ; IMMEDIATE : Q8 Q7 ; 3 Q8 . . CR
--> }T 5 14548464 T=
-Block 7111
-T{ [COMPILE].basic
-T| : Q9 [COMPILE] IF ; IMMEDIATE : Q10 Q9 1 ELSE 2 THEN ; 0 Q10
-T| . -1 Q10 . CR
--> }T 5 13623021 T=
-T{ (.comment
-T| 1 ( 2 ) 3 . . CR
--> }T 5 14546542 T=
-T{ BLK.terminal
-T| BLK @ . CR
--> }T 3 47130 T=
-T{ 79-STANDARD.present
-T| 79-STANDARD
--> }T 0 0 T=
-T{ WORD.next_word
-T| : W1 BL WORD COUNT TYPE ; W1 HELLO
--> }T 5 1515698 T=
-Block 7112
-T{ WORD.delimiter
-T| : W2 44 WORD COUNT TYPE ; W2 A B,
--> }T 3 63523 T=
-T{ WORD.count
-T| : W3 BL WORD C@ . ; W3 ABC
--> }T 2 1613 T=
-T{ WORD.skips_leading
-T| : W4 BL WORD COUNT TYPE ; W4 X
--> }T 1 88 T=
-Block 7113
-T-REPORT
-FORGET T# DECIMAL
diff --git a/docs/v4.0.0/MESH.md b/docs/v4.0.0/MESH.md
index 3d7fb99f..ea2e8d87 100644
--- a/docs/v4.0.0/MESH.md
+++ b/docs/v4.0.0/MESH.md
@@ -705,8 +705,30 @@ Each is tested, committed and pushed before the next.
release by asking, holes. Its acceptance is to be approved before it is
built.
**6b. POST is the kernel's.** Ruled 2026-10-07 (section 9); design
- approved 2026-10-07, `NUCLEUS.md` 6.3 and section 7. Acceptance, as
- approved:
+ approved 2026-10-07, `NUCLEUS.md` 6.3 and section 7.
+ **Done 2026-10-07.**
+ - *The cases* (`v4/system/post_cases.c`, written by `v4/tools/mkpost.py`):
+ the same 538, checked against the capsule case by case. One expected
+ result changed: `>IN.initial` prints 6 where it printed 9, because a
+ case's line no longer begins with the capsule's `T| `; the generator
+ now runs v3 on the lines as the kernel sends them.
+ - *The runner* (`v4/system/post.c`), tested in
+ `v4/tests/test_host_quit.c` with cases that must pass and cases that
+ must fail.
+ - *The boot* (`v4/system/boot.c`) runs it after the capsules, prints
+ `PARITY:V4_SYSTEM`, and seals. `capsules/v4/post79.4th`, `(CATCH)` and
+ `(EMIT-HOOK)` are gone.
+ - *Verified.* `make -C v4 test`, `sanitize` and `hosted-check`; three
+ bare-metal boots, `logs/20261007-105118` (amd64), `-105335`
+ (aarch64), `-105651` (riscv64). On all six: POST 538 of 538,
+ `word_count=411`, `dict_hash=0x6fb1d09418b189ee`. At the prompt `T{`
+ is unknown, and `RS1`, which a case defines, prints `42 42` before and
+ after `COLD`. A hosted program built with one case's expected output
+ changed names the case and ends `PARITY:FAIL`, `POST: FAILED`.
+ - What the cases define takes 1,385 cells of the dictionary space's
+ 5,632.
+
+ Acceptance, as approved:
1. *Same verdict.* The three hosted programs and the three bare-metal
boots print `PARITY:V4_POST tests=538 pass=538 fail=0`,
`PARITY:V4_SYSTEM word_count=N dict_hash=0x...`, `PARITY:OK` and
diff --git a/docs/v4.0.0/POST79.md b/docs/v4.0.0/POST79.md
index 59853f05..60d28ae9 100644
--- a/docs/v4.0.0/POST79.md
+++ b/docs/v4.0.0/POST79.md
@@ -33,7 +33,7 @@ standard's and not v3's.
| `+!.negative` | `10 HERE ! -3 HERE +! HERE @ . CR` | error | unchanged | stack `empty`, prints `7 \n` | v3 raises an error FORTH-79 does not ask for: a store to HERE |
| `+!.accumulate` | `0 HERE ! 1 HERE +! 2 HERE +! 3 HERE +! HERE @ . CR` | error | unchanged | stack `empty`, prints `6 \n` | v3 raises an error FORTH-79 does not ask for: a store to HERE |
| `HERE.after_comma~2` | `HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP /` | error | unchanged | stack `0`, prints nothing | the case divides by zero unless HERE moved by one cell; on v3 it had moved by 8 |
-| `MOVE.basic` | `HERE 65 OVER C! HERE 1+ 66 OVER C! HERE HERE 16 + 2 MOVE HERE 16 + C@ . HERE 17 + C@ . CR` | stack `302 303`, printed `65 66 \n` | `65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ . HERE 17 + @ . CR` | stack `empty`, prints `65 66 \n` | FORTH-79: MOVE moves cells; and v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `MOVE.basic` | `HERE 65 OVER C! HERE 1+ 66 OVER C! HERE HERE 16 + 2 MOVE HERE 16 + C@ . HERE 17 + C@ . CR` | stack `294 295`, printed `65 66 \n` | `65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ . HERE 17 + @ . CR` | stack `empty`, prints `65 66 \n` | FORTH-79: MOVE moves cells; and v3's address unit is a byte; a v4 address unit is a cell (D-1) |
| `BASE.base_store` | `16 BASE ! 255 . CR` | stack `empty`, printed `597 \n` | unchanged | stack `empty`, prints `255 \n` | 255 read in base 16 and printed in base 16 is 255; v3 printed 467 |
| `<#.basic` | `DECIMAL 42 S>D <# #S #> TYPE CR` | stack `empty`, printed `774763251095801167872\n` | unchanged | stack `empty`, prints `42\n` | v3 prints 774763251095801167872 for 42 S>D <# #S #> |
| `<#.empty` | `0 <# #> TYPE CR` | stack `0`, printed `\n` | `0 0 <# #> TYPE CR` | stack `empty`, prints `\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single |
@@ -51,20 +51,20 @@ standard's and not v3's.
| `#>.empty` | `0 <# #> TYPE CR` | stack `0`, printed `\n` | `0 0 <# #> TYPE CR` | stack `empty`, prints `\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single |
| `#>.stack_effect` | `42 <# #S #> SWAP . . CR` | stack `empty`, printed `24 2 \n` | `42 0 <# #S #> SWAP DROP . CR` | stack `empty`, prints `2 \n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single |
| `HOLD.basic` | `42 <# 46 HOLD #S #> TYPE CR` | stack `empty`, printed `42.\n` | `42 0 <# 46 HOLD #S #> TYPE CR` | stack `empty`, prints `42.\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single |
-| `COUNT.basic` | `HERE S" Test" DROP COUNT . . CR` | stack `302`, printed `84 303 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and S" is not FORTH-79 |
-| `COUNT.empty` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 308 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
-| `COUNT.max_length` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 308 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
-| `COUNT.basic~2` | `HERE S" Test" DROP C@ HERE 1+ SWAP COUNT . . CR` | stack `412 418`, printed `0 85 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
-| `COUNT.empty~2` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 418 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
-| `COUNT.max_length~2` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 418 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
-| `CMOVE.basic` | `HERE S" Test" DUP >R HERE 10 + SWAP CMOVE CR` | stack `325`, printed `\n` | `65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD 11 + C@ . CR` | stack `empty`, prints `65 66 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and the v3 case leaves a value on the return stack |
-| `TYPE.basic_string` | `HERE S" Hello" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `400`, printed `Hello\n` | `72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `Hi\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt |
-| `TYPE.numbers` | `HERE S" 12345" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `406`, printed `12345\n` | `49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `12\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt |
-| `>IN.initial` | `>IN @ . CR` | stack `empty`, printed `860486384 \n` | unchanged | stack `empty`, prints `9 \n` | FORTH-79: >IN is the offset into the input, 9 here; v3 prints an address |
+| `COUNT.basic` | `HERE S" Test" DROP COUNT . . CR` | stack `294`, printed `84 295 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and S" is not FORTH-79 |
+| `COUNT.empty` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 300 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `COUNT.max_length` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 300 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `COUNT.basic~2` | `HERE S" Test" DROP C@ HERE 1+ SWAP COUNT . . CR` | stack `404 410`, printed `0 85 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `COUNT.empty~2` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 410 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `COUNT.max_length~2` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 410 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) |
+| `CMOVE.basic` | `HERE S" Test" DUP >R HERE 10 + SWAP CMOVE CR` | stack `317`, printed `\n` | `65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD 11 + C@ . CR` | stack `empty`, prints `65 66 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and the v3 case leaves a value on the return stack |
+| `TYPE.basic_string` | `HERE S" Hello" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `392`, printed `Hello\n` | `72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `Hi\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt |
+| `TYPE.numbers` | `HERE S" 12345" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `398`, printed `12345\n` | `49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `12\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt |
+| `>IN.initial` | `>IN @ . CR` | stack `empty`, printed `657828592 \n` | unchanged | stack `empty`, prints `6 \n` | FORTH-79: >IN is the offset into the input, 6 here; v3 prints an address |
| `UPDATE.no_block` | `0 SCR ! UPDATE` | error | unchanged | stack `empty`, prints nothing | v3 raises an error FORTH-79 does not ask for |
| `SCR.after_load` | `1 LOAD SCR @ . CR` | stack `empty`, printed `` | unchanged | stack `empty`, prints `1 \n` | v3 prints nothing after 1 LOAD; SCR is still 1 from the LIST before |
-| `FIND.existing` | `FIND DUP . CR` | stack `empty`, printed `860485744 \n` | unchanged | 0 value(s) left; output not compared | FORTH-79: FIND takes the next word, DUP here, and leaves its address, which is printed |
-| `FIND.user_word` | `: test5 44 ; FIND test5 . CR` | stack `empty`, printed `860812560 \n` | unchanged | 0 value(s) left; output not compared | the address FIND leaves is printed |
+| `FIND.existing` | `FIND DUP . CR` | stack `empty`, printed `657827952 \n` | unchanged | 0 value(s) left; output not compared | FORTH-79: FIND takes the next word, DUP here, and leaves its address, which is printed |
+| `FIND.user_word` | `: test5 44 ; FIND test5 . CR` | stack `empty`, printed `658154448 \n` | unchanged | 0 value(s) left; output not compared | the address FIND leaves is printed |
| `FIND.empty` | `FIND` | error | unchanged | stack `0`, prints nothing | FORTH-79: FIND leaves 0 when there is no word; v3 raises an error |
| `VOCABULARY.cross_vocab_access` | `VOCABULARY V1 V1 DEFINITIONS : V1WORD 11 ; FORTH V1WORD . CR` | stack `empty`, printed `11 \n` | unchanged | an error | FORTH-79: a word defined in another vocabulary is not found from FORTH; v3 finds it |
| `VOCABULARY.duplicate` | `VOCABULARY TESTVOC VOCABULARY TESTVOC` | error | unchanged | stack `empty`, prints nothing | v3 raises an error FORTH-79 does not ask for: defining a name again |
diff --git a/kernel/Makefile b/kernel/Makefile
index 123aad80..bc9bdd47 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -620,8 +620,8 @@ LOADER_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c
KERNEL_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c
# v4/system/boot.c is the boot the hosted v4 system runs too: nucleus, then
# the capsules from this kernel's own capsule directory, then the prompt.
-LOADER_V4_OBJS := $(patsubst v4/src/%.c,$(LOADER_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(LOADER_OBJ_DIR)/v4engine/v4_image.o $(LOADER_OBJ_DIR)/v4system/boot.o $(LOADER_OBJ_DIR)/v4system/blocks.o
-KERNEL_V4_OBJS := $(patsubst v4/src/%.c,$(KERNEL_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(KERNEL_OBJ_DIR)/v4engine/v4_image.o $(KERNEL_OBJ_DIR)/v4system/boot.o $(KERNEL_OBJ_DIR)/v4system/blocks.o
+LOADER_V4_OBJS := $(patsubst v4/src/%.c,$(LOADER_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(LOADER_OBJ_DIR)/v4engine/v4_image.o $(LOADER_OBJ_DIR)/v4system/boot.o $(LOADER_OBJ_DIR)/v4system/blocks.o $(LOADER_OBJ_DIR)/v4system/post.o $(LOADER_OBJ_DIR)/v4system/post_cases.o
+KERNEL_V4_OBJS := $(patsubst v4/src/%.c,$(KERNEL_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(KERNEL_OBJ_DIR)/v4engine/v4_image.o $(KERNEL_OBJ_DIR)/v4system/boot.o $(KERNEL_OBJ_DIR)/v4system/blocks.o $(KERNEL_OBJ_DIR)/v4system/post.o $(KERNEL_OBJ_DIR)/v4system/post_cases.o
endif
LOADER_SRCS := $(LOADER_SRCS_BASE) $(LOADER_EXTRA_SRCS)
diff --git a/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log b/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log
new file mode 100644
index 00000000..408182d1
--- /dev/null
+++ b/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log
@@ -0,0 +1,158 @@
+[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
+Architecture: amd64
+Build: Oct 7 2026 10:50:50
+
+UEFI BootServices: EXITED
+
+=== StarKernel Boot Information ===
+Memory map entries: 131
+Total memory: 1023 MB
+Usable memory: 966 MB
+===================================
+
+PMM initialized.
+PMM statistics:
+ Total pages: 248741
+ Free pages : 247218
+ 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=2149499758 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=1031765227, tick_hz=100, initial_count=10317652
+APIC Timer: configured (masked, ready to start)
+Heartbeat: init done
+Kernel initialization complete.
+Boot successful!
+
+StarForth v4: one host node, the F18-derived engine
+V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
+PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
+V4: capsule v4:forth79.4th signature: missing (unsigned)
+PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
+PARITY:V4_POST tests=538 pass=538 fail=0
+PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee
+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
+Artemis: virtio-blk attached
+[32m[HADES][INFO ] [0m[KRELTSC: 78934212] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
+ok> : SQ DUP * ;
+ ok
+ok> 7 SQ . 3 4 U* . .
+49 0 12 ok
+ok> T{
+UNKNOWN WORD: 'T{'
+ ERROR
+ok> RS1
+42 42
+ ok
+ok> COLD
+FORTH-79 Cold Start
+System initialized.
+ ok
+ok> RS1
+42 42
+ ok
+ok> 3 4 U* . .
+0 12 ok
+ok> FORGET U*
+Protected word
+ ERROR
+ok> 9 KERNEL-WORD ASK9 ASK9
+Argument out of range
+ ERROR
+ok> 1 BLOCK C@ . 2047 BLOCK C@ .
+0 0 ok
+ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
+65 ok
+ok> 3072 BLOCK C@ .
+0 ok
+ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
+Storage refused
+ ERROR
+ok> 9999999 BLOCK
+Block out of range
+ ERROR
+ok> HERE .
+9585 ok
+ok> BYE
+BYE: cold restart
diff --git a/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log b/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log
new file mode 100644
index 00000000..aa3b6393
--- /dev/null
+++ b/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log
@@ -0,0 +1,131 @@
+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
+Architecture: aarch64
+Build: Oct 7 2026 10:53:09
+
+UEFI BootServices: EXITED
+
+=== StarKernel Boot Information ===
+Memory map entries: 108
+Total memory: 4093 MB
+Usable memory: 4054 MB
+===================================
+
+PMM initialized.
+PMM statistics:
+ Total pages: 1039357
+ Free pages : 1037946
+ 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!
+
+StarForth v4: one host node, the F18-derived engine
+V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
+PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
+V4: capsule v4:forth79.4th signature: missing (unsigned)
+PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
+PARITY:V4_POST tests=538 pass=538 fail=0
+PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee
+PARITY:OK
+POST: PASSED
+[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
+PCI: init...
+virtio-blk: found device
+Artemis: virtio-blk attached
+[32m[HADES][INFO ] [0m[KRELTSC: 1501177] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
+ok> : SQ DUP * ;
+ ok
+ok> 7 SQ . 3 4 U* . .
+49 0 12 ok
+ok> T{
+UNKNOWN WORD: 'T{'
+ ERROR
+ok> RS1
+42 42
+ ok
+ok> COLD
+FORTH-79 Cold Start
+System initialized.
+ ok
+ok> RS1
+42 42
+ ok
+ok> 3 4 U* . .
+0 12 ok
+ok> FORGET U*
+Protected word
+ ERROR
+ok> 9 KERNEL-WORD ASK9 ASK9
+Argument out of range
+ ERROR
+ok> 1 BLOCK C@ . 2047 BLOCK C@ .
+0 0 ok
+ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
+65 ok
+ok> 3072 BLOCK C@ .
+0 ok
+ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
+Storage refused
+ ERROR
+ok> 9999999 BLOCK
+Block out of range
+ ERROR
+ok> HERE .
+9585 ok
+ok> BYE
+BYE: cold restart
diff --git a/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log b/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log
new file mode 100644
index 00000000..8b1b0a8c
--- /dev/null
+++ b/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log
@@ -0,0 +1,201 @@
+
+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 = 0x00000000bdca29f8
+riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
+
+
+ _____ _ _ __ _
+ / ____| | | |/ / | |
+ | (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
+ \___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
+ ____) | || (_| | | | . \ __/ | | | | | __/ |
+ |_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
+
+LithosAnanke v2.1.0
+Architecture: riscv64
+Build: Oct 7 2026 10:56:11
+
+UEFI BootServices: EXITED
+
+=== StarKernel Boot Information ===
+Memory map entries: 100
+Total memory: 1020 MB
+Usable memory: 975 MB
+===================================
+
+PMM initialized.
+PMM statistics:
+ Total pages: 250273
+ Free pages : 249621
+ Used pages : 652
+ Total MB : 977
+ Free MB : 975
+ 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!
+
+StarForth v4: one host node, the F18-derived engine
+V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
+PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308
+V4: capsule v4:forth79.4th signature: missing (unsigned)
+PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4
+PARITY:V4_POST tests=538 pass=538 fail=0
+PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee
+PARITY:OK
+POST: PASSED
+[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
+PCI: init...
+virtio-blk: found device
+Artemis: virtio-blk attached
+[32m[HADES][INFO ] [0m[KRELTSC: 40981668] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
+ok> : SQ DUP * ;
+ ok
+ok> 7 SQ . 3 4 U* . .
+49 0 12 ok
+ok> T{
+UNKNOWN WORD: 'T{'
+ ERROR
+ok> RS1
+42 42
+ ok
+ok> COLD
+FORTH-79 Cold Start
+System initialized.
+ ok
+ok> RS1
+42 42
+ ok
+ok> 3 4 U* . .
+0 12 ok
+ok> FORGET U*
+Protected word
+ ERROR
+ok> 9 KERNEL-WORD ASK9 ASK9
+Argument out of range
+ ERROR
+ok> 1 BLOCK C@ . 2047 BLOCK C@ .
+0 0 ok
+ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
+65 ok
+ok> 3072 BLOCK C@ .
+0 ok
+ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
+Storage refused
+ ERROR
+ok> 9999999 BLOCK
+Block out of range
+ ERROR
+ok> HERE .
+9585 ok
+ok> BYE
+BYE: cold restart
diff --git a/v4/Makefile b/v4/Makefile
index 14f4582a..b2563050 100644
--- a/v4/Makefile
+++ b/v4/Makefile
@@ -139,7 +139,7 @@ CAPSULE_DIR_C := $(BINDIR)/capsule_generated.c
# the kernel's capsule code: find, check the hash, verify the signature,
# split a payload into blocks
-SYSTEM_SRCS := $(HERE)/system/boot.c \
+SYSTEM_SRCS := $(HERE)/system/boot.c $(HERE)/system/post.c $(HERE)/system/post_cases.c \
$(addprefix $(ROOT)/kernel/src/capsule/,capsule_find.c capsule_validate.c capsule_sig.c capsule_blocks.c) \
$(ROOT)/kernel/src/hash/xxhash64.c $(ROOT)/kernel/src/crypto/x509_ed25519.c $(CRYPTO_SRCS)
# The kernel's sources are held to the kernel's warnings, not this model's.
@@ -169,7 +169,7 @@ $(foreach i,$(HOSTED_ISAS),$(eval $(call HOSTED_RULE,$(i))))
# `make post` boots the amd64 system alone, which is the quick check after a
# change to the vocabulary: nucleus, forth79.4th, POST, prompt. `make
-# post79` writes the POST capsule, ../capsules/v4/post79.4th, again from
+# post79` writes POST's cases, system/post_cases.c, again from
# v3's cases and tools/post79_rules.py (tools/mkpost.py); it needs the
# hosted v3 binary.
.PHONY: post post79
diff --git a/v4/README.md b/v4/README.md
index c6e3de1e..d622b0ea 100644
--- a/v4/README.md
+++ b/v4/README.md
@@ -159,21 +159,25 @@ a time with POST after each, is the next step (`NUCLEUS.md` section 8).
## POST
-`capsules/v4/post79.4th`: 538 cases in blocks 7000 up, covering 126 of the
-130 words of the FORTH-79 Required Word Set. 443 are v3's cases with what
-the hosted v3 binary did as the expected result. The other 107, and the 27
-v3 cases left out, are listed with reasons in `docs/v4.0.0/POST79.md`.
+POST is the kernel's, as in v3 (`MESH.md` step 6b, `NUCLEUS.md` 6.3). The
+kernel holds the cases, `v4/system/post_cases.c`: 538 of them, covering 126
+of the 130 words of the FORTH-79 Required Word Set. 431 are v3's cases with
+what the hosted v3 binary did as the expected result; every other case,
+and the v3 cases left out, are listed with reasons in
+`docs/v4.0.0/POST79.md`.
- `make -C v4 post` boots the amd64 system: the quick check after a change.
- `make -C v4 hosted-check` boots all three hosted ISAs and compares them.
-- `make -C v4 post79` writes the capsule again (`tools/mkpost.py`,
+- `make -C v4 post79` writes the cases again (`tools/mkpost.py`,
`tools/post79_rules.py`); it needs the hosted v3 binary.
-POST is FORTH: a harness of FORTH-79 words and two nucleus hooks, `(CATCH)`
-and `(EMIT-HOOK)`. It forgets itself when it has finished. The boot passes
-only on seeing POST's tally line with `fail=0` (`v4/system/boot.c`). A colon
-definition broken on purpose (`U/MOD` without its last `SWAP`) fails five
-cases and the boot stops with `POST: FAILED`.
+The runner, `v4/system/post.c`, feeds each case to the node a line at a
+time, keeps what the node prints, reads its data stack from outside, and
+judges: an error exactly if one is expected, and otherwise the stack and
+every character printed. Nothing of POST is in the node's dictionary. What
+the cases define stays there, as in v3, and the system is sealed after
+POST. The boot then prints `PARITY:V4_SYSTEM word_count=N dict_hash=0x...`,
+and passes only if no case failed (`v4/system/boot.c`).
Not tested: `KEY`, `EXPECT`, `QUERY` (the keyboard) and `QUIT` (it returns
without ` ok`).
diff --git a/v4/capsule/core.v4 b/v4/capsule/core.v4
index fa29129e..d086d23d 100644
--- a/v4/capsule/core.v4
+++ b/v4/capsule/core.v4
@@ -251,18 +251,12 @@ header CMOVE
(OUT) (OUT^) a! ! ;
NONE: drop ;
-\ EMIT puts the character with what has been printed, unless (EMIT-HOOK)
-\ holds the xt of a word: then that word is given it instead ( c -- ), and
-\ returns to EMIT's caller. Everything the node prints goes through EMIT,
-\ so a hook sees all of it. The hook is taken off when the text being
-\ interpreted ends (quit.v4), so that nothing can leave a node silent.
-\ POST uses it to compare what a case prints (docs/v4.0.0/NUCLEUS.md 6.3).
-\ A is kept: the words that print have always been free to use it across
-\ an EMIT. As v3, only the low 8 bits of the character are printed.
+\ EMIT puts the character with what has been printed. Everything the node
+\ prints goes through EMIT. A is kept: the words that print have always
+\ been free to use it across an EMIT. As v3, only the low 8 bits of the
+\ character are printed.
header EMIT
: EMIT ( c -- )
- (EMIT-HOOK) b! @b if NONE push ;
- NONE: drop
255 and a push push \ A, and then the character, to the return stack
(OUT^) b! @b a! pop !+ a !b \ the character goes where (OUT^) points, which moves on
a (OUT)+256 xor if FULL drop pop a! ;
diff --git a/v4/capsule/quit.v4 b/v4/capsule/quit.v4
index 41cdf6f8..d458ede5 100644
--- a/v4/capsule/quit.v4
+++ b/v4/capsule/quit.v4
@@ -48,18 +48,10 @@ macro R-CLEAR RSTACK-DEPTH b! a !b endmacro
\ structures. A definition that was under way stays hidden.
: (RESET) 0 STATE a! ! (CG-RESET) CFBASE (CFP) a! ! ;
-\ CATCHING A LINE'S ERROR. While the variable (CATCH) is not zero, a line
-\ that ends in an error -- a fault, or a code in NODE-ERROR -- does not say
-\ ERROR: (CATCH) is set to -1 and the line is reported as completed. Whatever message the
-\ error printed has gone wherever EMIT was sending it. POST uses this to
-\ go on to its next case, and to check the cases that must fail
-\ (docs/v4.0.0/NUCLEUS.md 6.3). (EMIT-HOOK), core.v4, is set to 0 here at
-\ the end of every line, caught or not.
-\
\ ( s -- ) the text is done with. What it printed is sent, then a message
\ saying how it ended -- 0 QUIT, 1 completed, 2 an error -- and the node waits
-\ for the next. (DONE) is entered with the same number and decides whether
-\ an error was one to catch; it is always jumped to, never called, by
+\ for the next. (DONE) is entered with the same number and, for an error,
+\ stops compiling first; it is always jumped to, never called, by
\ something that has emptied the return stack (or by a fault, which empties
\ it). (LINE-STATUS) keeps how the last text ended.
: (FINISH) ( s -- )
@@ -70,11 +62,8 @@ macro R-CLEAR RSTACK-DEPTH b! a !b endmacro
jump (IDLE)
: (DONE)
- (EMIT-HOOK) b! 0 !b \ what is printed is printed again
if GO -1 + if OK
- drop (RESET)
- (CATCH) b! @b if LOUD drop -1 !b 1 jump (DONE) \ caught: the text completed
- LOUD: drop 2 jump (FINISH)
+ drop (RESET) 2 jump (FINISH)
OK: drop 1 jump (FINISH)
GO: drop 0 jump (FINISH)
@@ -247,13 +236,11 @@ header (SEAL)
\ further, the message for the code is printed (-1: the word has printed
\ its own) and the line ends with ERROR. The codes are listed in core.v4.
header NODE-ERROR inline : NODE-ERROR' NODE-ERROR ;
-header (CATCH) inline : (CATCH)' (CATCH) ;
header (ME) inline : (ME)' (ME) ;
header (CONSOLE) inline : (CONSOLE)' (CONSOLE) ;
header (LOST) inline : (LOST)' (LOST) ;
header (WORD-DEFINED) inline : (WORD-DEFINED)' (WORD-DEFINED) ;
header (WORD-FORGOTTEN) inline : (WORD-FORGOTTEN)' (WORD-FORGOTTEN) ;
-header (EMIT-HOOK) inline : (EMIT-HOOK)' (EMIT-HOOK) ;
header QUIT
: QUIT R-CLEAR (RESET) CR 0 jump (DONE)
diff --git a/v4/system/boot.c b/v4/system/boot.c
index f69558b3..106093bd 100644
--- a/v4/system/boot.c
+++ b/v4/system/boot.c
@@ -4,6 +4,7 @@
* It is not part of the engine (v4/src): it needs the capsule directory,
* which only a whole system has.
*/
+#include "v4/post.h"
#include "v4/blocks.h"
#include "v4/boot.h"
#include "v4/message.h"
@@ -13,18 +14,18 @@
#include "starkernel/capsule_blocks.h"
/* The capsules, in the order they are loaded. */
-/* POST is part of the boot: v4:post79.4th is loaded after the vocabulary it
- * tests and must end with a clean tally. -DV4_POST_AT_BOOT=0 leaves it
- * out, for work on a vocabulary that does not pass yet. */
+static const char *const boot_capsules[] = {
+ "v4:forth79.4th",
+};
+
+/* POST is part of the boot, and is the kernel's (v4/include/v4/post.h;
+ * docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in, the kernel feeds
+ * its cases to the node and judges them, and the boot passes only if none
+ * failed. -DV4_POST_AT_BOOT=0 leaves it out, for work on a vocabulary
+ * that does not pass yet. */
#ifndef V4_POST_AT_BOOT
#define V4_POST_AT_BOOT 1
#endif
-static const char *const boot_capsules[] = {
- "v4:forth79.4th",
-#if V4_POST_AT_BOOT
- "v4:post79.4th",
-#endif
-};
#define LINE_MAX 1025u /* a line is at most 1024 characters, a block */
#define STEP_LIMIT 4000000000ULL /* instruction words one line may take */
@@ -77,37 +78,6 @@ static uint32_t word_count(const v4_node *n, const v4_image *im)
/* ---- handing the node a line ---------------------------------------------- */
-/* POST's verdict. The POST capsule ends by printing one line,
- * PARITY:V4_POST tests=N pass=N fail=N
- * and the boot passes only if it has seen that line with fail=0. That no
- * line was refused is not enough: a POST that was broken half way would
- * refuse nothing. */
-static char post_line[96];
-static unsigned post_len;
-static int post_seen, post_clean;
-
-static int text_at(const char *line, unsigned len, unsigned at, const char *want)
-{
- unsigned i;
- for (i = 0; want[i]; i++)
- if (at + i >= len || line[at + i] != want[i]) return 0;
- return 1;
-}
-
-static void post_watch(char c)
-{
- static const char clean[] = " fail=0";
- if (c != '\n') {
- if (post_len < sizeof post_line) post_line[post_len++] = c;
- return;
- }
- if (text_at(post_line, post_len, 0, "PARITY:V4_POST ")) {
- post_seen = 1;
- post_clean = post_len >= sizeof clean - 1 && text_at(post_line, post_len, post_len - (unsigned)(sizeof clean - 1), clean);
- }
- post_len = 0;
-}
-
/* The boot is the node's neighbour on two of its ports. On port 0 it is
* the kernel: the node writes the number of a request there (ENGINE.md
* 3.3) -- for a block (blocks.h), or for one of the host's words. On port
@@ -120,7 +90,10 @@ static void post_watch(char c)
/* What the kernel keeps of the node's block window (blocks.h). */
static v4_blocks boot_blocks;
-int v4_boot_line(const v4_boot *b, const char *text, unsigned len)
+/* Hand the node a line and run it to its end. What it prints goes to the
+ * console; or, if `keep` is given, into `keep`, at most `cap` characters,
+ * and none of it is shown: *printed is then how many it printed in all. */
+static int run_line(const v4_boot *b, const char *text, unsigned len, char *keep, unsigned cap, unsigned *printed)
{
static v4_message out, in; /* one line at a time: the boot is not re-entered */
v4_node *n = b->n;
@@ -155,8 +128,8 @@ int v4_boot_line(const v4_boot *b, const char *text, unsigned len)
if (v4_message_type(&in) == V4_MSG_OUTPUT) {
for (i = 0; i < chars; i++) {
char c = v4_message_char(&in, i);
- post_watch(c);
- b->out(&c, 1);
+ if (!keep) b->out(&c, 1);
+ else { if (*printed < cap) keep[*printed] = c; (*printed)++; }
}
} else if (v4_message_type(&in) == V4_MSG_DONE) {
return (int)in.word[V4_MSG_HEADER];
@@ -185,6 +158,27 @@ int v4_boot_line(const v4_boot *b, const char *text, unsigned len)
}
}
+int v4_boot_line(const v4_boot *b, const char *text, unsigned len)
+{
+ return run_line(b, text, len, 0, 0u, 0);
+}
+
+#if V4_POST_AT_BOOT
+/* POST's host (post.h): a line is handed to the node as any line is, and
+ * what the node prints is kept for the runner and not shown. */
+static int post_line(void *self, const char *text, unsigned text_len, char *out, unsigned cap, unsigned *len)
+{
+ int how;
+ *len = 0;
+ how = run_line((const v4_boot *)self, text, text_len, out, cap, len);
+ return (how == V4_TEXT_QUIT || how == V4_TEXT_COMPLETED || how == V4_TEXT_ERROR) ? how : -1;
+}
+static void post_say(void *self, const char *text, unsigned len)
+{
+ ((const v4_boot *)self)->out(text, len);
+}
+#endif
+
/* ---- one capsule --------------------------------------------------------- */
static void say_where(const v4_boot *b, const char *name, uint32_t block, uint32_t line)
@@ -345,7 +339,6 @@ int v4_boot_run(const v4_boot *b)
{
unsigned i;
- post_len = 0; post_seen = 0; post_clean = 0;
/* a node is born with nothing in it, and is sent the nucleus */
if (!v4_image_born(b->n, b->es, b->h, b->im)) {
say(b, "V4: the nucleus is not for this build of the engine\nPARITY:FAIL\nPOST: FAILED\n");
@@ -375,16 +368,24 @@ int v4_boot_run(const v4_boot *b)
for (i = 0; i < sizeof boot_capsules / sizeof boot_capsules[0]; i++)
if (!load_capsule(b, boot_capsules[i])) { say(b, "PARITY:FAIL\nPOST: FAILED\n"); return 0; }
#if V4_POST_AT_BOOT
- if (!post_seen || !post_clean) {
- say(b, post_seen ? "V4: POST reported failures\n" : "V4: POST did not report\n");
- say(b, "PARITY:FAIL\nPOST: FAILED\n");
- return 0;
+ {
+ v4_post_host host;
+ v4_post_tally tally;
+ host.self = (void *)b; host.n = b->n; host.line = post_line; host.say = post_say;
+ if (!v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally)) {
+ say(b, "V4: POST reported failures\nPARITY:FAIL\nPOST: FAILED\n");
+ return 0;
+ }
}
#endif
- /* The kernel's words and the capsules are the system: COLD comes back
- * to here, and FORGET will not go below it. */
+ /* The kernel's words, the capsules and what POST's cases defined are
+ * the system, as in v3: COLD comes back to here, and FORGET will not go
+ * below it. */
v4_image_seal(b->n, b->im);
+ say(b, "PARITY:V4_SYSTEM word_count="); say_dec(b, word_count(b->n, b->im));
+ say(b, " dict_hash="); say_hex(b, v4_boot_dict_hash(b->n, b->im));
+ say(b, "\n");
#if V4_POST_AT_BOOT
say(b, "PARITY:OK\nPOST: PASSED\n");
diff --git a/v4/system/post_cases.c b/v4/system/post_cases.c
index 8fd6a58d..431f440a 100644
--- a/v4/system/post_cases.c
+++ b/v4/system/post_cases.c
@@ -877,7 +877,7 @@ const v4_post_case v4_post_cases[] = {
{ "-TRAILING.empty", l318, 1u, V4_POST_STACK, 0, 0u, "\012", 1u },
{ "CMOVE.basic", l319, 2u, V4_POST_STACK, 0, 0u, "65 66 \012", 7u },
{ "CMOVE.empty", l320, 1u, V4_POST_STACK, 0, 0u, "", 0u },
- { ">IN.initial", l321, 1u, V4_POST_STACK, 0, 0u, "9 \012", 3u },
+ { ">IN.initial", l321, 1u, V4_POST_STACK, 0, 0u, "6 \012", 3u },
{ ">IN.advances", l322, 1u, V4_POST_STACK, 0, 0u, "0 \012", 3u },
{ "..positive", l323, 1u, V4_POST_STACK, 0, 0u, "42 \012", 4u },
{ "..negative", l324, 1u, V4_POST_STACK, 0, 0u, "-42 \012", 5u },
diff --git a/v4/tests/host_map.h b/v4/tests/host_map.h
index 16b0ed5e..664a2fe6 100644
--- a/v4/tests/host_map.h
+++ b/v4/tests/host_map.h
@@ -65,8 +65,6 @@
#define SRC (BVARS + 8)
#define SRC_HOOK (BVARS + 9)
#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 - 32) /* the node's ports (node.h): V4_PORTS of them, then "any port" and "which port". Port 0 is where its requests go. */
#define CONSOLE (BUF0_W - 16) /* the node what this one prints is sent to; 0: whoever sent the text being served */
@@ -175,8 +173,6 @@ static int host_load(v4_text *tx, v4_node *n, const char *const *files, unsigned
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, "(ME)", ME);
diff --git a/v4/tests/test_host_quit.c b/v4/tests/test_host_quit.c
index 37ba0c42..f391683c 100644
--- a/v4/tests/test_host_quit.c
+++ b/v4/tests/test_host_quit.c
@@ -1277,6 +1277,11 @@ int main(void)
post_lost = 0;
}
+ /* ---- nothing of POST is on the node (NUCLEUS.md 6.3) ---- */
+ boot();
+ CHECK(is(say("(CATCH)\n"), "UNKNOWN WORD: '(CATCH)'\n ERROR\nok> ") && is(say("(EMIT-HOOK)\n"), "UNKNOWN WORD: '(EMIT-HOOK)'\n ERROR\nok> ")
+ && is(say("T{\n"), "UNKNOWN WORD: 'T{'\n ERROR\nok> "), "the nucleus has neither of the variables the POST capsule needed, nor its words");
+
/* ---- storage that refuses a write (MESH.md 8.2) ---- */
boot();
CHECK(is(say(REFUSING_FIRST " BLOCK DROP UPDATE SAVE-BUFFERS 65 EMIT\n"), "Storage refused\n ERROR\nok> "), "a write storage will not take says so, and the prompt returns");
@@ -1450,7 +1455,7 @@ int main(void)
boot_bare();
CHECK(load_source("tools.fth"), "tools.fth compiles, every line of it");
CHECK(is(say(": SQ DUP * ; SEE SQ\n"), ": SQ\n dup call * \n ; \n ok\nok> "), "a definition: an in-line word, a call by name, the return");
- CHECK(is(say("SEE DUP\n"), ": DUP\n dup ; \n ok\nok> ") && is(say("SEE EMIT\n"), out) && strncmp(out, ": EMIT\n @p ", 12) == 0 && strstr(out, " b! @b \n if ") && strstr(out, " pop a! ; \n"),
+ CHECK(is(say("SEE DUP\n"), ": DUP\n dup ; \n ok\nok> ") && is(say("SEE EMIT\n"), out) && strncmp(out, ": EMIT\n @p 255 and ", 20) == 0 && strstr(out, " pop a! ; \n"),
"the capsule's own words; a literal's value follows its @p");
CHECK(is(say("VARIABLE V 7 V ! SEE V\n"), ": V\n data: 7 \n ok\nok> ") && is(say("5 CONSTANT K SEE K\n"), ": K\n data: 5 \n ok\nok> "), "a variable and a constant show what they hold");
CHECK(is(say(": IM 1 ; IMMEDIATE SEE IM\n"), ": IM\n @p 1 ; \nIMMEDIATE\n ok\nok> "), "an immediate word says so");
diff --git a/v4/tests/test_host_unit.c b/v4/tests/test_host_unit.c
index c2bcfd6d..fbe8ee96 100644
--- a/v4/tests/test_host_unit.c
+++ b/v4/tests/test_host_unit.c
@@ -31,6 +31,7 @@
#include "v4/manage.h"
#include "v4/blocks.h"
#include "v4/message.h"
+#include "v4/post.h"
#include "v4/text.h"
#include "block_subsystem.h"
#include
@@ -154,7 +155,6 @@ static int host_open(void *self, const char *name, unsigned len)
(void)self;
if (len == 17 && memcmp(name, "v4:nucleus-64.f18", 17) == 0) { hera_reads.is_f18 = 1; hera_reads.cells_at = 0; return 1; }
if (len == 14 && memcmp(name, "v4:forth79.4th", 14) == 0) return read_file(&hera_reads, "forth79.4th");
- if (len == 13 && memcmp(name, "v4:post79.4th", 13) == 0) return read_file(&hera_reads, "post79.4th");
return 0;
}
static int host_cell(void *self, v4_cell *w)
@@ -277,6 +277,30 @@ static const char *tell(v4_cell node, const char *text)
}
static int told(v4_cell node, const char *text) { return tell(node, text)[0] == 0 && ended == 1 && ended_how == V4_TEXT_COMPLETED; }
+/* POST's host, for the node numbered 10 (v4/include/v4/post.h): a line is
+ * told to it from the console, and what it prints is handed to the runner. */
+static int post_line(void *self, const char *text, unsigned text_len, char *out, unsigned cap, unsigned *len)
+{
+ static char line[V4_MSG_MAX_CHARS + 1];
+ const char *r;
+ (void)self;
+ *len = 0;
+ if (text_len > V4_MSG_MAX_CHARS) return -1;
+ memcpy(line, text, text_len); line[text_len] = 0;
+ r = tell(10, line);
+ if (ended != 1 || ended_from != 10) return -1;
+ *len = printed_len;
+ memcpy(out, r, printed_len < cap ? printed_len : cap);
+ return (int)ended_how;
+}
+static char post_said[2048];
+static unsigned post_said_len;
+static void post_say(void *self, const char *text, unsigned len)
+{
+ (void)self;
+ if (post_said_len + len < sizeof post_said) { memcpy(post_said + post_said_len, text, len); post_said_len += len; post_said[post_said_len] = 0; }
+}
+
/* Every line of a capsule of FORTH blocks, told to a node from the console:
* how many lines did not complete. */
static unsigned load(v4_cell node, const char *file)
@@ -376,7 +400,16 @@ int main(void)
}
CHECK(strcmp(tell(10, "NODE-ME ."), "0 ") == 0 && refused == 0, "it asks where it is, and is answered");
CHECK(load(10, "forth79.4th") == 0, "it takes in FORTH-79");
- CHECK(load(10, "post79.4th") == 0 && post_passed[10] == 1 && post_other == 0, "and passes POST");
+ {
+ v4_post_host host;
+ v4_post_tally tally;
+ host.self = 0; host.n = node_numbered(10); host.line = post_line; host.say = post_say;
+ CHECK(v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally) && tally.tests == 538 && tally.pass == 538 && tally.fail == 0
+ && strstr(post_said, "PARITY:V4_POST tests=538 pass=538 fail=0\n") != NULL && strstr(post_said, "POST FAIL") == NULL,
+ "and passes POST, which the kernel runs on her: %u of %u, %u failed; \"%s\"", tally.pass, tally.tests, tally.fail, post_said);
+ }
+ CHECK(strstr(tell(10, "T{"), "UNKNOWN WORD") != NULL, "nothing of POST's harness is on her: \"%s\"", printed);
+ CHECK(strcmp(tell(10, "RS1"), "42 42 \n") == 0, "what POST's cases defined is: \"%s\"", printed);
CHECK(load(10, "hera.4th") == 0, "and its own capsule, which makes it Hera");
CHECK(told(10, "(SEAL)"), "that is the system it comes back to");
@@ -387,9 +420,10 @@ int main(void)
CHECK(ended == 1 && ended_how == V4_TEXT_COMPLETED && ended_from == 10, "Hera births four nodes and joins them: \"%s\"", r);
}
CHECK(born_count == 4 && refused == 0, "four nodes were asked for: %u", born_count);
- CHECK(post_passed[10] == 1 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0,
- "a node she births is not POSTed: POST is the kernel's, once, on Hera: %u; %u %u %u %u, %u failed",
+ CHECK(post_passed[10] == 0 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0,
+ "a node she births is not POSTed, and no node prints a POST tally: POST is the kernel's, once, on Hera: %u %u %u %u %u, %u failed",
post_passed[10], post_passed[11], post_passed[12], post_passed[13], post_passed[14], post_other);
+ CHECK(strstr(tell(10, "COLD"), "Cold Start") != NULL && strcmp(tell(10, "RS1"), "42 42 \n") == 0, "COLD on Hera comes back to a system that has what POST's cases defined: \"%s\"", printed);
CHECK(parity_count == 4 && parity_number[0] == 11 && parity_number[1] == 12 && parity_number[2] == 13 && parity_number[3] == 14, "the parity of each was recorded: %u", parity_count);
CHECK(parity_hash[0] == parity_hash[1] && parity_hash[1] == parity_hash[2] && parity_hash[2] == parity_hash[3],
"and their dictionary hashes are the same: %016llx %016llx %016llx %016llx",
diff --git a/v4/tools/mkpost.py b/v4/tools/mkpost.py
index ffd200fb..bfa60777 100755
--- a/v4/tools/mkpost.py
+++ b/v4/tools/mkpost.py
@@ -240,10 +240,14 @@ ANSI = re.compile(r"\x1b\[[0-9;]*m")
def run_v3(v3, cases):
"""Runs the cases in one session. Returns a list, one entry per case:
None if v3 did not get through it, else (error, stack, output)."""
- script = [": T| ; IMMEDIATE", ": TCLR BEGIN DEPTH WHILE DROP REPEAT ;"]
+ # The lines are run as the kernel sends them to the node: without the
+ # "T| " each began with when they were lines of a capsule. A case that
+ # looks at where it is in its line (>IN) depends on it.
+ script = [": TCLR BEGIN DEPTH WHILE DROP REPEAT ;"]
for n, case in enumerate(cases):
script.append('TCLR DECIMAL FORTH DEFINITIONS ." [[B%d]]"' % n)
- script.extend(case["lines"])
+ assert all(line.startswith("T| ") for line in case["lines"]), case
+ script.extend(line[3:] for line in case["lines"])
script.append('." [[E%d]]" BASE @ DECIMAL .S BASE ! ." [[S%d]]"' % (n, n))
script.append("BYE")
done = subprocess.run([v3, "--log-none"], input=("\n".join(script) + "\n").encode("latin-1"),
diff --git a/v4/tools/post79_rules.py b/v4/tools/post79_rules.py
index a0308877..fae2ce9a 100644
--- a/v4/tools/post79_rules.py
+++ b/v4/tools/post79_rules.py
@@ -112,7 +112,9 @@ STANDARD = {
"TYPE.basic_string": dict(text="72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR", out="Hi\n", why=D1 + "; and " + RS),
"TYPE.numbers": dict(text="49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR", out="12\n", why=D1 + "; and " + RS),
- ">IN.initial": dict(out="9 \n", why="FORTH-79: >IN is the offset into the input, 9 here; v3 prints an address"),
+ # 6: the line is ">IN @ . CR" and >IN is read when "@" has been taken with the blank after it. It was 9
+ # while the cases were a capsule, whose lines each began "T| " (until MESH.md step 6b).
+ ">IN.initial": dict(out="6 \n", why="FORTH-79: >IN is the offset into the input, 6 here; v3 prints an address"),
"WORD.empty_input": None, "WORD.space_delim": None, "WORD.newline_delim": None, "WORD.tab_delim": None,
"WORD.comma_delim": None, "WORD.skip_leading": None, "WORD.single_char": None, "WORD.long_word": None,