Collapse OS Documentation Browser


asm/ code/ hw/ arch.txt avr.txt blk.txt blksrv.txt bootstrap.txt cross.txt design.txt dict.txt dis.txt drivers.txt ed.txt emul.txt faq.txt grid.txt hal.txt impl.txt intro.txt me.txt primer.txt ps2.txt rxtx.txt sdcard.txt sega.txt selfhost.txt spi.txt usage.txt


List of words defined in arch-specific boot code and Core words.


Stack notation: "<stack before> -- <stack after>". Rightmost is
top of stack (TOS). For example, in "a b -- c d", b is TOS
before, d is TOS after. "R:" means that the Return Stack is

Some words have a variable stack signature, most often in pair
with a flag. These are indicated with "?" to tell that the argu-
ment might not be there. For example, "-- n? f" means that "n"
might or might not be there.

Word references (wordref): When we say we have a "word
reference", it's a pointer to a word's entry point. That is,
making native jump to the address contained in the wordref will
execute the word.

For example, the address that "' DUP" puts on the stack is a
word reference to DUP. See impl.txt for details.

"*I*" in description indicates an IMMEDIATE word.
"*A*" in description indicates A register usage.
"*B*" in description indicates B register usage.


Across words, different symbols are used in different contexts,
but we try to been consistent in their use. Here's their def-

! - Store
@ - Fetch
$ - Initialize
^ - Arguments in their opposite order
< - Input
> - 1. Pointer in a buffer 2. Opposite of "<".
( - Lower boundary
) - Upper boundary
' - Address of
* - Word indirection (pointer to word)
? - Is it ...?

Placement of those symbols is important. To the left of the
words, it refers to inputs and to the right, the output.

System variables

See doc/usage.txt for details. These ones have a "'" pair:

BLK>     Currently selected Block.
CURRENT  Address of the last word of the dictionary.
HERE     Addr of next available space in dict
IN(      Beginning of the input buffer.
IN>      Current pos in input buffer.

These ones are addresses and must be accessed with @ and !:

IOERR    Nonzero when an IO error occurred in some drivers.
NL       1 or 2 chars to spit during NL>, MSB first. If MSB is
         0, it's ignored.
LN<      Routine that feeds lines to the interpreter. Generally
BLKDTY   Whether current block is dirty

Values and aliases

TO x     n --         Write n to value x.
[TO] x   n --         *I*. Same as TO.
VAL!     n a --       Write n to value a.

Entry management

'? x     -- f Find x it in dict. If found, f=1. Otherwise, f=0.
' x      -- w Push addr of word x to w. If not found, aborts.
['] x    --   *I* Like "'", but spits the addr as a number
              literal. If not found, aborts.
FIND     sa sl -- w? f
         Find "sa sl" in dict. If found, w=wordref, f=1.
         Otherwise, f=0.
FORGET   x -- Rewind the dictionary (both CURRENT and HERE) up
              to x's previous entry.

Defining words

: x ... ;   --     Define a new word.
ALIAS x y   --     Define an alias y with a starting value of x
CREATE x    --     Create cell named x. Doesn't allocate.
[COMPILE] x --     *I* Compile word x and write it to HERE.
                   IMMEDIATE words are *not* executed.
COMPILE x   --     *I* Meta compiles: write wordrefs that will
                   compile x when executed.
CONSTANT x  n --   Create a constant x with value n.
CONSTS x    n --   Creates n new constants. See usage.txt.
VALUE x     n --   Creates cell x that when called pushes its
VALUES x    n --   Create a serie of x values. See usage.txt
DOER        --     See primer.txt
DOES>       --     See primer.txt
CDOES>      --     See usage.txt
IMMEDIATE   --     Flag the latest defined word as immediate.
LITN        n --   Write number n as a literal.


Note that flow words can only be used in definitions. In the
INTERPRET loop, they don't have the desired effect because each
word from the input stream is executed immediately. In this
context, branching doesn't work.

f IF A ELSE B THEN: if f is true, execute A, if false, execute
B. ELSE is optional.
[IF] .. [THEN]: Meta-IF. Works outside definitions. No [ELSE].
BEGIN .. f UNTIL: if f is false, branch to BEGIN.
BEGIN .. AGAIN: Always branch to BEGIN.
n >R BEGIN .. NEXT: Loop n times.

(         --   *I* Comment. Ignore input until ")" is read.
\         --   *I* Line comment. Ignore input until EOL.
[         --   *I* Begin interpretative mode. In a definition,
               execute words instead of compiling them.
]         --   End interpretative mode.
ABORT     --   Resets PS and RS and returns to interpreter.
ABORT" x" --   *I* Compiles a ." followed by a ABORT.
EXECUTE   a -- Execute wordref at addr a
INTERPRET --   Main interpret loop.
LEAVE     --   In a DO..LOOP, exit at the next LOOP call.
QUIT      --   Reset RS, return to interpreter prompt.

Parameter Stack

DROP        a --
DUP         a -- a a
?DUP        DUP if a is nonzero
NIP         a b -- b
OVER        a b -- a b a
ROT         a b c -- b c a
ROT>        a b c -- c a b
SWAP        a b -- b a
TUCK        a b -- b a b
2DROP       a a --
2DUP        a b -- a b a b

Return Stack

>R          n -- R:n        Pops PS and push to RS
R>          R:n -- n        Pops RS and push to PS
R@          -- n            Copy RS TOS to PS
R~          R:n --          Drop RS TOS

Stacks meta

.S   --   *A* Prints stack information as well as the contents
          of PS.
SCNT -- n Size of PS in bytes
RCNT -- n Size of RS in bytes


@        a -- n       Set n to value at address a
!        n a --       Store n in address a
,        n --         Write n in HERE and advance it.
+!       n a --       Increase number at addr a by n.
[]=      a1 a2 u -- f Compare u bytes between a1 and a2. Returns
                      true if equal.
C@       a -- c       Set c to byte at address a
C@+      a -- a+1 c   Fetch c from a and inc a.
C!       c a --       Store byte c in address a
C!+      c a -- a+1   Store byte c in a and inc a.
C,       b --         Write byte b in HERE and advance it.
ALLOT    n --         Move HERE by n bytes.
ALLOT0   n --         *A* ALLOT and fill with zero.
FILL     a n b --     *A* Fill n bytes at addr a with val b.
L,       n --         Write n in little-endian regardless of
                      native endianess (L=LSB first)
M,       n --         Write n in nig-endian regardless of
                      native endianess (M=MSB first)
MOVE     a1 a2 u --   *A* Copy u bytes from a1 to a2, starting
                      with a1, going up.
MOVE,    a u --       *A* Copy u bytes from a to HERE.

A/B registers

>A       n -- A:n
A>       A:n -- n A:n
A+       A:n -- A:n+1
A-       A:n -- A:n-1
AC@+     A:a -- c A:a+1
AC!+     c A:a -- A:a+1
>B       n -- B:n
B>       B:n -- n B:n
B+       B:n -- B:n+1
B-       B:n -- B:n-1

Arithmetic / Bits

+           a b -- a+b
-           a b -- a-b
-^          a b -- b-a
*           a b -- a*b
/           a b -- a/b
<<          a -- a<<1
<<8         a -- a<<8
>>          a -- a>>1
>>8         a -- a>>8
L|M         n -- lsb msb    Split n word in 2 bytes, MSB on TOS
1+          n -- n+1
1-          n -- n-1
MOD         a b -- a%b
/MOD        a b -- r q      r:remainder q:quotient
AND         a b -- a&b
OR          a b -- a|b
XOR         a b -- a^b
LSHIFT      a u -- a<<u
RSHIFT      a u -- a>>u


=    n1 n2 -- f Push true if n1 == n2
<    n1 n2 -- f Push true if n1 < n2
>    n1 n2 -- f Push true if n1 > n2
>=   n1 n2 -- f Push true if n1 >= n2
<=   n1 n2 -- f Push true if n1 <= n2
0<   n -- f     Push true if n-as-signed is negative
=><= n l h -- f Push true if l <= n <= h
NOT  f -- f     Push the logical opposite of f

Strings and lines

See doc/usage.txt for the concepts of strings and lines.

LIT" x" --     Read following characters and write to HERE as a
               string literal.
LNLEN   a -- n Return length of line at a, the line ending at
               the last visible char of it.
S=      sa1 sl1 sa2 sl2 -- f
        Returns whether string s1 == s2.


.        n --     Print n in its decimal form
.x       n --     Print n's LSB in hex form. Always 2
.X       n --
         Print n in hex form. Always 4 characters.
         Numbers are never considered negative. "-1 .X" --> ffff
," xxx" --        Write xxx to HERE
." xxx" --        *I* Compiles string literal xxx followed by a
                  call to STYPE.
CURWORD -- sa sl  Yield the last read word (see WORD).
EMIT    c --      Spit char c to output stream
EMITLN  a --      *A* EMIT line at addr a
IN<     -- c      Read one char from buffered input, if end of
                  input is reached, read new line.
IN<?    -- c-or-0 Read from buffered input if its end hasn't
                  been reached, 0 otherwise.
IN(     -- a      Beginning of input buffer.
IN)     -- a      End of the input buffer, exclusive.
IN$     --        Flush input buffer
KEY?    -- c? f   Polls the keyboard for a key. If a key is
                  pressed, f is true and c is the char. Other-
                  wise, f is false and c is *not* on the stack.
KEY     -- c      Get char c from direct input.
NL>     --        Emit newline
PARSE   sa sl -- n? f *AB*
        Parses string s as a number and push the result in n if
        it can be parsed, with f=1. Otherwise, push f=0.
PC!     c a --    Spit c to port a
PC@     a -- c    Fetch c from port a
SPC>    --        Emit space character
STYPE   sa sl --  *A* EMIT all chars of string.
WAITW   sa sl --  Call WORD until we get the same string as
                  sa sl.
WORD    -- sa sl  Read one word from buffered input and push it.
                  That word is a string (begins with a length
WORD!   sa sl --  The next WORD call will not read from input
                  and yield this string instead.

These ASCII consts are defined:

KEY? and EMIT are aliases to (key?) and (emit) (see doc/drivers)
KEY is a loop over KEY?.

NL> spits CRLF by default, but can be configured to spit an
alternate newline char. See impl.txt.

BLK subsystem (see doc/blk)

\S     --        Interrupts LOAD of current block.
BLK(   -- a      Beginning addr of blk buf.
BLK)   -- a      Ending addr of blk buf.
BLK@   n --      Read block n into buffer and make n active.
BLK!   --        Write currently active block, if dirty.
COPY   s d --    Copy contents of s block to d block.
FLUSH  --        Write current block to disk if dirty and inval-
                 idates current block cache.
LIST   n --      Prints the contents of the block n on screen
                 in the form of 16 lines of 64 columns.
LOAD   n --      Interprets Forth code from block n
LOADR  n1 n2 --  Load block range between n1 and n2, inclusive.
WIPE   --        *A* Empties current block

RX/TX subsystem (see doc/rxtx)

RX<?   -- c? f   If a char is available on RX, return it in c
                 with f=1. Otherwise, f=0.
RX<    -- c      Block until a char is available in RX.
RX<<   --        Consume RX<? and drop result until there's
                 nothing to be received.
RX[    --        Replace KEY? with RX<?.
]RX    --        Put back the old KEY? handler.
TX>    c --      Spit c to TX, blocking until it can do it.
TX[    --        Replace EMIT with TX>.
]TX    --        Put back the old EMIT handler.


BOOT    --       Boot back to a fresh system.
CRC16   c b -- c Computes byte b into c, a 16-bit CRC with a
                 $1021 polynomial (XMODEM CRC).
DUMP    n a --   Prints n bytes at addr a in a hexdump format.
                 Prints in chunks of 8 bytes. Doesn't do partial
                 lines. Output is designed to fit in 32 columns.
NOOP    --       Do nothing.
TICKS   n --     Wait for approximately 0.1 millisecond. Don't
                 use with n=0.


These words load the related application from blocks:

ARCHM  Arch-specific loader words and macros
ED     Block Editor
VE     Visual Editor
ME     Memory Editor
RSH    Remote shell and XMODEM implementation
AVRP   AVR programmer
XCOMPL Cross-compilation "low" part. XCOMPH (and many others) is
       defined in XCOMP itself.

Kernel internals

Some words from the kernel are designed to be internal but
ended up being used in "userland". Let's document them:

_bchk   n -- n     Checks whether n is a valid 8-bit signed
                   branching offset, that is, in the range -128
                   to 127. If not, abort with "br ovfl".

Collapse OS and its documentation are created by Virgil Dupras and licensed under the GNU GPL v3.

This documentation browser by James Stanley. Please report bugs on github or to

This page generated at 2022-01-16 21:05:03 from documentation in CollapseOS snapshot 20220115.