Collapse OS Documentation Browser


asm/ code/ hw/ avr.txt blk.txt bootstrap.txt cross.txt dict.txt ed.txt faq.txt grid.txt hal.txt impl.txt intro.txt me.txt primer.txt protocol.txt rsh.txt sega.txt selfhost.txt usage.txt


List of words defined in arch-specific boot code (for example,
B280 for Z80) and Core words (B210).


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 type field*. For
example, the address that "' DUP" puts on the stack is a
wordref, that is, a reference to the entry type field of the
word DUP. See impl.txt for details.

PF: Parameter field. The area following the entry type field of
a word. For example, "' H@ 1+" points to the PF of the word H@.

Words between "()" are "support words" that aren't really meant
to be used directly, but as part of another word.

"*I*" in description indicates an IMMEDIATE word.
"*F*" in description indicates an word that sets Flags.


Throughout words, different symbols are used in different
contexts, but we try to been consistent in their use. Here's
their definitions:

! - 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.

Values and aliases

Values and aliases (see usage.txt) can be handled with those

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

Collapse OS' core has a few *indirect* values and aliases which
can be manipulated with *TO, [*TO] and *VAL!.


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.
NL       1 or 2 chars to spit during NL>, MSB first. If MSB is
         0, it's ignored.

Aliases (see further below for description):


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     a --   Define a new alias with a starting value of a
*ALIAS x    a --   Define a new ialias where the indirection
                   points to a (actual alias in *a).
CREATE x    --     Create cell named x. Doesn't allocate a PF.
[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.
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
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.
x y DO .. LOOP: LOOP increments y. if y != x, branch to DO.

(         --   *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.
UNLOOP    --   Remove loop counters from RS before an early
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
2>R         x y -- R:x y    Equivalent to SWAP >R >R
R>          R:n -- n        Pops RS and push to PS
2R>         R:x y -- x y    Equivalent to R> R> SWAP
I           -- n            Copy RS TOS to PS

Stacks meta

'S -- n Current address of PSP
'R -- n Current address of RSP
.S --   Prints stack information as well as the contents of PS.
S0 -- n Start address of PS
R0 -- n Start address of RS


@        a -- n       Set n to value at address a
!        n a --       Store n in address a
,        n --         Write n in HERE and advance it.
[]=      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 --         ALLOT and fill with zero.
FILL     a n b --     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 --   Copy u bytes from a1 to a2, starting
                      with a1, going up.
MOVE,    a u --       Copy u bytes from a to HERE.
PAD      -- a         a is a safe space for tmp stuff.
RANGE    a u -- ah al Get low/high bounds of an addr+length
                      pair. Useful for DO..LOOP.

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.
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 --      EMIT line at addr a
IN<     -- c      Read one char from buffered input.
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
        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 --  EMIT all chars of string.
WORD    -- sa sl
        Read one word from buffered input and push it.
        That word is a string (begins with a length byte).

These ASCII consts are defined:

KEY? and EMIT are *ALIAS to (key?) and (emit) (see TTY protocol
in protocol.txt). 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.txt)

BLK(   -- a      Beginning addr of blk buf.
BLK)   -- a      Ending addr of blk buf.
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   --        Empties current block


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:

ED     Block Editor
VE     Visual Editor
ASM    Assembler common words
Z80A   Z80 assembler
8086A  8086 assembler
AVRA   AVR assembler
8086A  8086 assembler
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 2021-09-19 21:05:03 from documentation in CollapseOS snapshot 20210917.