Reference card

General

AmForth is a 16bit indirect threaded code (ITC) forth. It is almost compatible with the forth standards from 1994 and 200x. It runs on the bare metal controller with no further dependencies. The interpreter operates on whitespace delimited words. The compiler is a single pass compiler that writes directly to the flash based dictionary.

There are three distinct address spaces for flash, eeprom and RAM. Flash is addressed word wise (16 bits per address unit), RAM and EEPROM are accessed byte wise (8 bits per address unit). The standard return stack has 40 cells, the data stack is limited by the available RAM size. Numbers can be prefixed by $ to indicate hexadecimal, % for binary and # for decimal numbers. A trailing dot is used for double cell numbers.

The words described below form the compilable core of AmForth, which is written in assembler. There are additional words written in Forth. These can be found in the /lib directory. See the Cookbook for details on their definition and usage.

Stack patterns, categories and descriptions are automatically extracted from the assembler source code. These are being reviewed, but may still have errors in notation or substance.

Notation

n n1 n2 n3 ...signed number, single cell
u u1 u2 u3 ...unsigned number, single cell
d d1 d2 d3 ...signed number, double cell
ud ud1 ud2 ...unsigned number, double cell
x x1 x2 x3 ...single cell
f f1 f2 f3 ...logical flag, 0 is false, not 0 is true
a a1 a2 a3 ...address in RAM
ca ca1 ca2 ...address of character (byte) in RAM
fa fa1 fa2 ...address in FLASH
ea ea1 ea2 ...address in EEPROM
xt xt1 xt2 ...execution token (XT)
c c1 c2 c3 ...character (byte)
✓ ✗✓ present ✗ not present in prebuilt hex file

Arithmetics

*( n1 n2 -- n3 ) multiply routine
+( n1 n2 -- n3) add n1 and n2
+!( n a-addr -- ) add n to content of RAM address a-addr
-( n1|u1 n2|u2 -- n3|u3 ) subtract n2 from n1
/( n1 n2 -- n3) divide n1 by n2. giving the quotient
/mod( n1 n2 -- rem quot) signed division n1/n2 with remainder and quotient
0( -- 0 ) place a value 0 on TOS
1+( n1|u1 -- n2|u2 ) optimized increment
1-(S: n1 -- n2 ) optimized decrement
2*( n1 -- n2 ) arithmetic shift left, filling with zero
2/( n1 -- n2 ) arithmetic shift right
><( n1 -- n2 ) exchange the bytes of the TOS
?dnegate( d1 n -- d2 ) negate d1 if n negative
?negate( n1 n2 -- n3 ) negate n1 if n2 negative
abs( n1 -- n2 ) n2 is absolute value of n1
cell+( a-addr1 -- a-addr2 ) add the size of an address-unit to a-addr1
cells( n1 -- n2 ) n2 is the size in address units of n1 cells
d+( d1 d2 -- d3) add 2 double cell values
d-( d1 d2 -- d3 ) subtract d2 from d1
d2*( d1 -- d2 ) shift a double cell left
d2/( d1 -- d2 ) shift a double cell value right
dabs( d -- ud ) double cell absolute value
dinvert( d1 -- d2) invert all bits in the double cell value
dnegate( d1 -- d2 ) double cell negation
invert( n1 -- n2) 1-complement of TOS
log2( n1 -- n2 ) logarithm to base 2 or highest set bitnumber
lshift( n1 n2 -- n3) logically shift n1 left n2 times
m*( n1 n2 -- d) multiply 2 cells to a double cell
m+( d1 n1 -- d2) add a number to a double cell
mod( n1 n2 -- n3) divide n1 by n2 giving the remainder n3
popcnt( n1 -- n2 ) count the Number of 1 bits (population count)
rshift( n1 n2 -- n3 ) shift n1 n2-times logically right
true( -- -1 ) leaves the value -1 (true) on TOS
u/mod(u1 u2 -- rem quot) unsigned division with remainder
ud*
ud/mod( d1 n -- rem ud2 ) unsigned double cell division with remainder
um*( u1 u2 -- d) multiply 2 unsigned cells to a double cell
um/mod( ud u2 -- rem quot) unsigned division ud / u2 with remainder

Character IO

accept( ca +n1 -- n2 ) receive n2 bytes, store sequentially from ca, whilst n2 <= n1 and line terminator not received.
bl( -- 32 ) put ascii code of the blank to the stack
cr( -- ) cause subsequent output appear at the beginning of the next line
emit( c -- ) fetch the emit vector and execute it. should emit a character from TOS
emit?( -- f ) fetch emit? vector and execute it. should return the ready-to-send condition
key( -- c ) fetch key vector and execute it, should leave a single character on TOS
key?( -- f ) fetch key? vector and execute it. should turn on key sender, if it is disabled/stopped
space( -- ) emits a space (bl)
spaces( n -- ) emits n space(s) (bl)
type( addr n -- ) print a RAM based string

Compare

0<( n1 -- flag) compare with zero
0<>( n -- flag ) true if n is not zero
0=( n -- flag ) compare with 0 (zero)
0>( n1 -- flag ) true if n1 is greater than 0
<( n1 n2 -- flag) true if n1 is less than n2
<>( n1 n2 -- flag) true if n1 is not equal to n2
=( n1 n2 -- flag ) compares two values for equality
>( n1 n2 -- flag ) flag is true if n1 is greater than n2
d0<( d -- flag ) compares if a double double cell number is less than 0
d0>( d -- flag ) compares if a double double cell number is greater 0
max( n1 n2 -- n1|n2 ) compare two values, leave the bigger one
min( n1 n2 -- n1|n2 ) compare two values leave the smaller one
u<( u1 u2 -- flasg) true if u1 < u2 (unsigned)
u>( u1 u2 -- flag ) true if u1 > u2 (unsigned)
umax( u1 u2 -- u3 ) u3 is the unsigned greater of u1 , u2
umin( u1 u2 -- u3) u3 is the unsigned lessor of u1 , u2
within( n min max -- f) check if n is within min..max

Compiler

(( "ccc" -- ) skip everything up to the closing bracket on the same line
(create)( -- ) (C: "name" -- ) parse the input and create an empty vocabulary entry without XT and data field (PF)
(create-in)
+loop( n -- ) (R: loop-sys -- loop-sys| ) (C: do-sys -- ) compile (+loop) and resolve branches
."( -- ) (C: "ccc" -- ) compiles string into dictionary to be printed at runtime
2literal( -- x1 x2 ) (C: x1 x2 -- ) compile a cell pair literal in colon definitions
:( -- ) (C: "name" -- ) create a named entry in the dictionary, XT is DO_COLON
:noname( -- xt ) create an unnamed entry in the dictionary, XT is DO_COLON
;( -- ) finish colon defintion, compiles (exit) and returns to interpret state
?do( n1|u1 n2|u2 -- ) R( -- | loop-sys ) (C: -- do-sys) start a ?do .. [+]loop control structure
[( -- ) enter interpreter mode
[']( -- xt ) (C: "name" -- ) what ' does in the interpreter mode, do in colon definitions
[compile]( -- c ) (C: "name" -- ) Append the compilation semantics of "name" to the dictionary, if any
\( "ccc" -- ) everything up to the end of the current line is a comment
]( -- ) enter compiler mode
again( -- ) (C: dest -- ) compile a jump back to dest
ahead( f -- ) (C: -- orig ) do a unconditional branch
begin( -- ) (C: -- dest ) put the next location for a transfer of control onto the control flow stack
code( -- ) (C: cchar -- ) create named entry in the dictionary, XT is the data field
constant( -- x ) (C: x "name" -- ) create a constant in the dictionary
do( n1 n2 -- ) (R: -- loop-sys ) (C: -- do-sys ) start do .. [+]loop
does>( i*x -- j*y ) (R: nest-sys1 -- ) (C: colon-sys1 -- colon-sys2 ) organize the XT replacement to call other colon code
else(C: orig1 -- orig2 ) resolve the forward reference and place a new unresolved forward reference
end-code( -- ) finish a code definition
endloop( fa xt -- ) common factor of loop and +loop
exit( -- ) (R: nest-sys -- ) end of current colon word
header( addr len wid -- nfa ) creates the vocabulary header without XT and data field (PF) in the wordlist wid
i( -- n ) (R: loop-sys -- loop-sys) current loop counter
i-cell+( addr -- addr' ) skip to the next cell in flash
if( f -- ) (C: -- orig ) start conditional branch
immediate( -- ) set immediate flag for the most recent word definition
j( -- n ) (R: loop-sys1 loop-sys2 -- loop-sys1 loop-sys2) loop counter of outer loop
leave( -- ) (R: loop-sys -- ) immediatly leave the current DO..LOOP
literal( -- n ) (C: n -- ) compile a literal in colon defintions
loop(R: loop-sys -- ) (C: do-sys -- ) compile (loop) and resolve the backward branch
postpone( "name" -- ) Append the compilation semantics of "name" to the dictionary
recurse( -- ) compile the XT of the word currently being defined into the dictionary
repeat( -- ) (C: orig dest -- ) continue execution at dest, resolve orig
s"( -- addr len) (C: -- ) compiles a string to flash, at runtime leaves ( -- flash-addr count) on stack
s,( addr len -- ) compiles a string from RAM to Flash
then( -- ) (C: orig -- ) finish if
unloop( -- ) (R: loop-sys -- ) remove loop-sys, exit the loop and continue execution after it
until( f -- ) (C: dest -- ) finish begin with conditional branch, leaves the loop if true flag at runtime
user( n cchar -- ) create a dictionary entry for a user variable at offset n
variable( cchar -- ) create a dictionary entry for a variable and allocate 1 cell RAM
while( f -- ) (C: dest -- orig dest ) at runtime skip until repeat if non-true
wlscope( addr len -- addr' len' wid ) dynamically place a word in a wordlist. The word name may be changed.

Conversion

s>d( n1 -- d1 ) extend (signed) single cell value to double cell

Core

>body( XT -- PFA ) get body from XT

Dictionary

'( "name" -- XT ) search dictionary for name, return XT or throw an exception -13
,( n -- ) compile 16 bit into flash at DP
compile( -- ) read the following cell from the dictionary and append it to the current dictionary position.
create( -- a-addr ) (C: "name" -- ) create a dictionary header. XT is (constant), with the address of the data field of name
reveal( -- ) makes an entry in a wordlist visible, if not already done.

Environment

/hold( -- hldsize ) size of the pictured numeric output buffer in bytes
/pad( -- padsize ) Size of the PAD buffer in bytes
/user( -- usersize ) size of the USER area in bytes
cpu( -- faddr len ) flash address of the CPU identification string
forth-name( -- faddr len ) flash address of the amforth name string
mcu-info( -- faddr len ) flash address of some CPU specific parameters
version( -- n ) version number of amforth
wordlists( -- n ) maximum number of wordlists in the dictionary search order

Exceptions

?abort( f ca u -- ) abort and type string of length u at ca if f true
abort( i*x -- ) (R: j*y -- ) send an exception -1
abort"( f -- ) abort and type quote enclosed string
catch( i*x xt -- j*x 0 | i*x n ) execute XT and check for exceptions.
handler( -- a-addr ) USER variable used by catch/throw
throw( n -- ) throw an exception

Extended VM register (reg) A

>a( n -- ) Write to A reg
a!( n -- ) Write memory pointed to by reg A
a!+( n -- ) Write memory pointed to by reg A, increment A by 1 cell
a!-( n -- ) Write memory pointed to by reg A, decrement A by 1 cell
a>( -- n ) read the A reg
a@( -- n ) Read memory pointed to by reg A
a@+( -- n ) Read memory pointed to by reg A, increment A by 1 cell
a@-( -- n ) Read memory pointed to by reg A, decrement A by 1 cell
na!( n offs -- ) Write memory pointed to by reg A plus offset
na@( offs -- n ) Read memory pointed to by reg A plus offset

Extended VM register (reg) B

>b( n -- ) Write to B reg
b!( n -- ) Write memory pointed to by reg B
b!+( n -- ) Write memory pointed to by reg B, increment B by 1 cell
b!-( n -- ) Write memory pointed to by reg B, decrement B by 1 cell
b>( -- n ) read the B reg
b@( -- n ) Read memory pointed to by reg B
b@+( -- n ) Read memory pointed to by reg B, increment B by 1 cell
b@-( -- n ) Read memory pointed to by reg B, decrement B by 1 cell
nb!( n offs -- ) Write memory pointed to by reg B plus offset
nb@( offs -- n ) Read memory pointed to by reg B plus offset

Hardware

1w.reset( -- f ) Initialize 1-wire devices; return true if present
1w.slot( c -- c' ) Write and read one bit to/from 1-wire.

Interpreter

rec-find( addr len -- xt flags rectype-xt | rectype-null ) search for a word
rec-num( addr len -- f ) recognizer for integer numbers
rectype-dnum( -- addr ) Method table for double cell integers
rectype-null( -- addr ) there is no parser for this recognizer, this is the default and failsafe part
rectype-num( -- addr ) Method table for single cell integers
rectype-xt( -- addr ) actions to handle execution tokens and their flags

Interrupt

#int( -- n ) number of interrupt vectors (0 based)
+int( -- ) turns on all interrupts
-int( -- ) turns off all interrupts
int!( xt i -- ) stores XT as interrupt vector i
int-trap( i -- ) trigger an interrupt
int@( i -- xt ) fetches XT from interrupt vector i
irq[]#( i -- xt ) fetches XT from interrupt vector i

Logic

and( n1 n2 -- n3 ) bitwise and
negate( n1 -- n2 ) 2-complement
not( flag -- flag' ) identical to 0=
or( n1 n2 -- n3 ) logical or
xor( n1 n2 -- n3) exclusive or

MCU

!@spi( n1 -- n2 ) SPI exchange of 2 bytes, high byte first
!wdc( n -- ) timed write into watchdog control registers
+usart( -- ) initialize usart
-jtag( -- ) disable jtag at runtime
-wdt( -- ) disable watch dog timer at runtime
>rx-buf( ?? ) usart driver, receiving sizes have to be powers of 2!
bm-clear( bitmask byte-addr -- ) clear bits set in bitmask on byte at addr
bm-set( bitmask byte-addr -- ) set bits from bitmask on byte at addr
bm-toggle( bitmask byte-addr -- ) toggle bits set in bitmask on byte at addr
c!@spi( txbyte -- rxbyte) SPI exchange of 1 byte
isr-rx( ?? ) setup with ' isr-rx URXCaddr int!
n!spi( addr len -- ) write len bytes to SPI from addr
n@spi( addr len -- ) read len bytes from SPI to addr
rx-buf( -- c) get 1 character from input queue, wait if needed using interrupt driver
rx-poll(c -- ) wait for one character and read it from the terminal connection using register poll
rx?-buf( -- f) check if unread characters are in the input queue
rx?-poll( -- f) check if a unread character in the input device is available
sleep( mode -- ) put the controller into the specified sleep mode
tx-poll(c -- ) check availability and send one character to the terminal using register poll
tx?-poll( -- f) MCU check if a character can be send using register poll
ubrr( -- v) returns usart UBRR settings
wdr( -- ) calls the MCU watch dog reset instruction

Memory

!( n addr -- ) write n to RAM memory at addr, low byte first
!e( n e-addr -- ) write n (2bytes) to eeprom address
!u( n offset -- ) write n to USER area at offset
(!i-nrww)( n f-addr -- ) writes n to flash memory using assembly code (code to be placed in boot loader section)
(i!)( n fa -- ) writes a cell in flash
@( a-addr -- n ) read 1 cell from RAM address
@e( e-addr - n) read 1 cell from eeprom
@i( f-addr -- n1 ) read 1 cell from flash
@u( offset -- n ) read 1 cell from USER area
c!( c a-addr -- ) store a single byte to RAM address
c@( a-addr - c1 ) fetch a single byte from memory mapped locations
cmove(addr-from addr-to n -- ) copy data in RAM, from lower to higher addresses
cmove>(addr-from addr-to n -- ) copy data in RAM from higher to lower addresses.
fill( a-addr u c -- ) fill u bytes memory beginning at a-addr with character c

Multitasking

cas( new old addr -- f ) Atomic Compare and Swap: store new at addr and set f to true if contents of addr is equal to old.
pause( -- ) Fetch pause vector and execute it. may make a context/task switch

Numeric IO

#( d1 -- d2 ) pictured numeric output: convert one digit
#>( d1 -- addr count ) Pictured Numeric Output: convert PNO buffer into an string
#s( d -- 0 ) pictured numeric output: convert all digits until 0 (zero) is reached
.( n -- ) singed PNO with single cell numbers
.r( n w -- ) singed PNO with single cell numbers, right aligned in width w
<#( -- ) initialize the pictured numeric output conversion process
>number( ud1 c-addr1 u1 -- ud2 c-addr2 u2 ) convert a string to a number c-addr2/u2 is the unconverted string
base( -- a-addr ) location of the cell containing the number conversion radix
bin( -- ) set base for numeric conversion to 10
d.( d -- ) singed PNO with double cell numbers
d.r( d w -- ) singed PNO with double cell numbers, right aligned in width w
decimal( -- ) set base for numeric conversion to 10
digit?( c -- (number|) flag ) tries to convert a character to a number, set flag accordingly
hex( -- ) set base for numeric conversion to 10
hld( -- addr ) pointer to current write position in the Pictured Numeric Output buffer
hold( c -- ) prepend character to pictured numeric output buffer
number(addr len -- [n|d size] f) convert a string at addr to a number
sign( n -- ) place a - in HLD if n is negative
u.( u -- ) unsigned PNO with single cell numbers
u.r( u w -- ) unsigned PNO with single cells numbers, right aligned in width w
ud.( ud -- ) unsigned PNO with double cell numbers
ud.r( ud w -- ) unsigned PNO with double cell numbers, right aligned in width w

Numerical constants

-1( -- -1 ) Place -1 on the stack
1( -- 1 ) Place 1 on the stack
2( -- 2 ) Place 2 on the stack

Search Order

cfg-order( -- wid-n .. wid-1 n) Get the current search order word list
cfg-recs( -- wid-n .. wid-1 n) Get the current search order word list
forth-wordlist( -- wid ) get the system default word list
get-current( -- wid) get the wid of the current compilation word list
search-wordlist( c-addr len wid -- [ 0 ] | [ xt [-1|1]] ) searches the word list wid for the word at c-addr/len
set-current( wid -- ) set current word list to the given word list wid
wordlist( -- wid ) create a new, empty wordlist

Stack

2>r( x1 x2 -- ) (R: -- x1 x2) move DTOS to TOR
2drop( x1 x2 -- ) Remove the 2 top elements
2dup( x1 x2 -- x1 x2 x1 x2 ) Duplicate the 2 top elements
2r>( -- x1 x2 ) (R: x1 x2 --) move DTOR to TOS
2r@( -- d) (R: d -- d ) fetch content of TOR
2swap( x1 x2 x3 x4 -- x3 x4 x1 x2 ) Exchange the two top cell pairs
>r( n -- ) (R: -- n) move TOS to TOR
?dup( n1 -- [ n1 n1 ] | 0) duplicate TOS if non-zero
depth( -- n ) number of single-cell values contained in the data stack before n was placed on the stack.
drop( n -- ) drop TOS
dup( n -- n n ) duplicate TOS
lp0( -- addr) start address of leave stack
n>r( x-n .. x-1 n -- ) (R: -- x-n .. x-1 n) move n items from data stack to return stack
nip( n1 n2 -- n2 ) Remove Second of Stack
nr>( -- x-n .. x-1 n ) (R: x-n .. x-1 n -- ) move n items from return stack to data stack
over( x1 x2 -- x1 x2 x1 ) Place a copy of x1 on top of the stack
pick( nm...n0 u -- nm...n0 nu ) Copy the u'th stack item to TOS. 0 pick is dup, 1 pick is over
r>( -- n ) (R: n --) move TOR to TOS
r@( -- n) (R: n -- n ) fetch content of TOR
rot( n1 n2 n3 -- n2 n3 n1) rotate the three top level cells
rp!( addr -- ) (R: -- x*y) set return stack pointer
rp0( -- addr) start address of return stack
rp@( -- n) current return stack pointer address
sp!( addr -- i*x) set data stack pointer to addr
sp0( -- addr) start address of the data stack
sp@( -- addr ) current data stack pointer
swap( n1 n2 -- n2 n1) swaps the two top level stack cells
tuck( n1 n2 -- n2 n1 n2 ) Copy the first (top) stack item below the second stack item.

String

/string( addr1 u1 n -- addr2 u2 ) adjust string from addr1 to addr1+n, reduce length from u1 to u2 by n
compare( r-addr r-len f-addr f-len -- f) compares two strings in RAM
cscan( addr1 n1 c -- addr1 n2 ) Scan string at addr1/n1 for the first occurance of c, leaving addr1/n2, char at n2 is first non-c character
cskip( addr1 n1 c -- addr2 n2 ) skips leading occurancies in string at addr1/n1 leaving addr2/n2 pointing to the 1st non-c character
parse( char "ccc" -- c-addr u ) in input buffer parse ccc delimited string by the delimiter char.
parse-name( "" -- c-addr u ) In the SOURCE buffer parse whitespace delimited string. Returns string address within SOURCE.
place( addr1 len1 addr2 -- ) copy string as counted string
sliteral(C: addr len -- ) compiles a string to flash, at runtime leaves ( -- flash-addr count) on stack
tolower( C -- c) if C is an uppercase letter convert it to lowercase
toupper( c -- C ) if c is a lowercase letter convert it to uppercase

System

(defer)( i*x -- j*x ) runtime of defer
(value)( -- n ) runtime of value
.error( -- ) Deferred action for .error prompt
.input( -- ) Deferred action for .input prompt
.ok( -- ) Deferred action for .ok prompt
.ready( -- ) Deferred action for .ready prompt
Edefer!( xt1 xt2 -- ) does the real defer! for eeprom defers
Edefer@( xt1 -- xt2 ) does the real defer@ for eeprom defers
Rdefer!( xt1 xt2 -- ) The defer! for ram defers
Rdefer@( xt1 -- xt2 ) The defer@ for ram defers
Udefer!( xt1 xt2 -- ) does the real defer! for user based defers
Udefer@( xt1 -- xt2 ) does the real defer@ for user based defers
allot( n -- ) allocate or release memory in RAM
cold( i*x -- ) (R: j*y -- ) start up amforth.
defer!( xt1 xt2 -- ) stores xt1 as the xt to be executed when xt2 is called
defer@( xt1 -- xt2 ) returns the XT associated with the given XT
execute( xt -- ) execute XT
f_cpu( -- d ) put the cpu frequency in Hz on stack
interpret(i*x - j*x ) Interpret SOURCE word by word.
nfa>lfa( nfa -- lfa ) get the link field address from the name field address
quit( -- ) main loop of amforth. accept - interpret in an endless loop
recognize(addr len recstack -- i*x rectype-sometype | rectype-null ) walk the recognizer stack
refill( -- f ) refills the input buffer
refill-tib( -- f ) refills the input buffer
source( -- addr n ) address and current length of the input buffer
source-tib( -- addr n ) address and current length of the input buffer
warm( nx* -- ) (R: ny* -- ) initialize amforth further. executes turnkey operation and go to quit

System Value

!i( n addr -- ) Deferred action to write a single 16bit cell to flash
(marker)( -- e-addr ) The eeprom address until which MARKER saves and restores the eeprom data.
dp( -- f-addr ) address of the next free dictionary cell
ehere( -- e-addr ) address of the next free address in eeprom
environment( -- wid) word list identifier of the environmental search list
forth-recognizer( -- addr ) address of the next free data space (RAM) cell
here( -- addr ) address of the next free data space (RAM) cell
turnkey( -- n*y ) Deferred action during startup/reset

System Variable

#tib( -- addr ) variable holding the number of characters in TIB
>in( -- a-addr ) pointer to current read position in input buffer
latest( -- addr ) system state
lp( -- addr ) leave stack pointer
newest( -- addr ) system state
pad( -- a-addr ) Address of the temporary scratch buffer.
state( -- addr ) system state
tib( -- addr ) terminal input buffer address
up!( addr -- ) set user area pointer
up@( -- addr ) get user area pointer

Time

1ms( -- ) busy waits (almost) exactly 1 millisecond

Tools

.s( -- ) stack dump
?stack( -- ) check data stack depth and exit to quit if underrun
[char]( -- c ) (C: "name" -- ) skip leading space delimites, place the first character of the word on the stack
bounds( addr len -- addr+len addr ) convert a string to an address range
cfolddepth( flagset -- n ) constant fold depth
char( "name" -- c ) copy the first character of the next word onto the stack
ee>ram( e-addr r-addr len -- ) copy len cells from eeprom to ram
find-xt( c-addr len -- 0 | xt -1 | xt 1 ) search wordlists for an entry with the xt from c-addr/len
get-stack( e-addr -- item-n .. item-1 n) Get a stack from EEPROM
icompare( r-addr r-len f-addr f-len -- f) compares string in RAM with string in flash. f is zero if equal like COMPARE
icount( addr -- addr+1 n ) get count information out of a counted string in flash
init-ram( -- ) setup the default user area from eeprom
itype( addr n -- ) reads string from flash and prints it
map-stack( i*x XT e-addr -- j*y true | i*x false ) Iterate over a stack
name>flags( nt -- f ) get the flags from a name token
nfa>cfa( nt -- xt ) get the XT from a name token
noop( -- ) do nothing
set-stack( rec-n .. rec-1 n ee-addr -- ) Write a stack to EEPROM
show-wordlist( wid -- ) prints the name of the words in a wordlist
to( n -- ) store the TOS to the named value (eeprom cell)
unused( -- n ) Amount of available RAM (incl. PAD)
ver( -- ) print the version string
word( c -- addr ) skip leading delimiter character and parse SOURCE until the next delimiter. copy the word to HERE
words( -- ) prints a list of all (visible) words in the dictionary

Tools Ext (2012)

name>string( nt -- addr len ) get a (flash) string from a name token nt
traverse-wordlist( i*x xt wid -- j*x ) call the xt for every member of the wordlist wid until xt returns false