diff --git a/docs/v4.0.0/DECOMPOSITION.md b/docs/v4.0.0/DECOMPOSITION.md index 930b4179..dfc9974d 100644 --- a/docs/v4.0.0/DECOMPOSITION.md +++ b/docs/v4.0.0/DECOMPOSITION.md @@ -147,8 +147,8 @@ IF body1 ELSE body2 THEN → if L1 drop body1 jump L2 times, as on the F18. `FOR ... UNEXT` is the same but the body must fit in one instruction word. **Register conventions.** `A` and `B` are caller-saved. A word that uses them says so. Words in this -document that clobber `A`: `@ ! +! -! 2@ 2! C@ C! UM* * UM/MOD Q.FROM-INT Q.TO-INT Q.* Q./ Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS HOLD SIGN # #S SEND RECV`. Words that clobber `B`: -`Q./ Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS <# HOLD SIGN # #S #> SEND RECV`. +document that clobber `A`: `@ ! +! -! 2@ 2! C@ C! UM* * UM/MOD Q.FROM-INT Q.TO-INT Q.* Q./ Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS HOLD SIGN # #S TYPE SEND RECV`. Words that clobber `B`: +`Q./ Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS <# HOLD SIGN # #S #> EMIT CR SPACE TYPE SEND RECV`. **Return-stack words** (`>R R> R@ 2>R 2R> 2R@ I J UNLOOP` and the loop runtimes) are always IN. @@ -517,12 +517,12 @@ return stack. `-ROT` is in line (`SWAP push SWAP pop`). | Word | Fate | Notes | | --- | --- | --- | -| `EMIT` | DEV | Console service: one-character message. | +| `EMIT` | DEV | Console service: one-character message. Until the mesh exists it is a store to the `CONSOLE-TX` register (§7): `CONSOLE-TX b! !b`. As in v3, the low byte of the cell is the character. Executed on the golden model (2026-10-03). Clobbers `B`. | | `KEY` | DEV | Console service: blocking receive. | | `?TERMINAL` | DEV | Console service: non-blocking status. | -| `TYPE` | CAP | Loop of `C@ EMIT`, or one string message to the console node. | -| `CR` | CAP | `10 EMIT` | -| `SPACE` | CAP | `BL EMIT` | +| `TYPE` | CAP | `( baddr u -- )`. Loop of `C@ EMIT`, or one string message to the console node: `-if OK drop drop NODE-ERROR b! -1 !b ; OK: if DONE over C@ EMIT push 1 + pop -1 + jump OK DONE: drop drop ;` — nothing for `u = 0`; for `u < 0` nothing is printed and `NODE-ERROR` is set, where v3 printed nothing and raised its error flag. The address range is not checked (out-of-range addressing is still open, `node.h`). Executed on the golden model (2026-10-03). Leaves its caller 4 data cells and 3 return entries, the depth being `C@`'s as written. Clobbers `A` and `B`. | +| `CR` | CAP | `10 EMIT`, as `10 jump EMIT` — executed on the golden model (2026-10-03). Character 10, as v3; the console turns it into a new line. | +| `SPACE` | CAP | `BL EMIT`, as `32 jump EMIT` — executed on the golden model (2026-10-03). | | `SPACES` | CAP | `BEGIN dup 0> WHILE SPACE 1- REPEAT drop` | | `."` `(do-string)` | CC | Compiler words. | diff --git a/v4/tests/test_terminal.c b/v4/tests/test_terminal.c new file mode 100644 index 00000000..359ab414 --- /dev/null +++ b/v4/tests/test_terminal.c @@ -0,0 +1,282 @@ +/* test_terminal.c -- EMIT, CR, SPACE and TYPE, executed. + * + * DECOMPOSITION.md 5.10. EMIT is a device service; on the single-node model + * it is a store to the CONSOLE-TX capture register (node.h), so what these + * words print can be read back and compared with v3. + * + * v3 (v3/src/word_source/io_words.c): EMIT prints the low byte of the cell; + * CR prints character 10; SPACE prints a blank; TYPE ( addr u -- ) prints u + * bytes, nothing for u = 0, and for u < 0 prints nothing and raises its error + * flag. v4 sets NODE-ERROR in that last case, as D-13 does for HOLD. + * + * Two transcripts of the real v3 binary are recorded below as expected + * output. They were taken on 2026-10-03 from + * printf '