Reference Card

General

AmForth is a 16bit 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 is accessed byte wise (8bits 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.

Words not found here are not part of the compileable core system. Their forth sources are in the /lib directory, usually named after the word name: e.g. 2dup is defined in a file named 2dup.frt.

Arithmetics (AVR8)

  • 1- ( n1 – n2 ) optimized decrement
  • 1+ ( n1|u1 – n2|u2 ) optimized increment
  • 2/ ( n1 – n2 ) arithmetic shift right
  • 2* ( n1 – n2 ) arithmetic shift left, filling with zero
  • abs ( n1 – u1 ) get the absolute value
  • >< ( n1 – n2 ) exchange the bytes of the TOS
  • cell+ ( a-addr1 – a-addr2 ) add the size of an address-unit to a-addr1
  • d2/ ( d1 – d2 ) shift a double cell value right
  • d2* ( d1 – d2 ) shift a double cell left
  • dabs ( d – ud ) double cell absolute value
  • dinvert ( d1 – d2) invert all bits in the double cell value
  • d- ( d1 d2 – d3 ) subtract d2 from d1
  • dnegate ( d1 – d2 ) double cell negation
  • d+ ( d1 d2 – d3) add 2 double cell values
  • 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
  • - ( n1|u1 n2|u2 – n3|u3 ) subtract n2 from n1
  • m+ ( d1 n1 – d2) add a number to a double cell
  • m* ( n1 n2 – d) multiply 2 cells to a double cell
  • + ( n1 n2 – n3) add n1 and n2
  • +! ( n a-addr – ) add n to content of RAM address a-addr
  • popcnt ( n1 – n2 ) count the Number of 1 bits (population count)
  • rshift ( n1 n2 – n3 ) shift n1 n2-times logically right
  • /mod ( n1 n2 – rem quot) signed division n1/n2 with remainder and quotient
  • true ( – -1 ) leaves the value -1 (true) on TOS
  • um/mod ( ud u2 – rem quot) unsigned division ud / u2 with remainder
  • um* ( u1 u2 – d) multiply 2 unsigned cells to a double cell
  • u/mod (u1 u2 – rem quot) unsigned division with remainder
  • 0 ( – 0 ) place a value 0 on TOS

Compare (AVR8)

  • d= ( n1 n2 – flag ) compares two double cell values
  • d0> ( d – flag ) compares if a double double cell number is greater 0
  • d0< ( d – flag ) compares if a double double cell number is less than 0
  • = ( n1 n2 – flag ) compares two values for equality
  • > ( n1 n2 – flag ) flag is true if n1 is greater than n2
  • 0> ( n1 – flag ) true if n1 is greater than 0
  • 0<> ( n – flag ) true if n is not zero
  • u< ( u1 u2 – flasg) true if u1 < u2 (unsigned)
  • 0= ( n – flag ) compare with 0 (zero)
  • 0< ( n1 – flag) compare with zero

Compiler (AVR8)

  • code ( – ) (C: cchar – ) create named entry in the dictionary, XT is the data field
  • :noname ( – xt ) create an unnamed entry in the dictionary, XT is DO_COLON
  • does> ( i*x – j*y ) (R: nest-sys1 – ) (C: colon-sys1 – colon-sys2 ) organize the XT replacement to call other colon code
  • end-code ( – ) finish a code definition
  • 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
  • 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
  • s, ( addr len – ) compiles a string from RAM to Flash
  • unloop ( – ) (R: loop-sys – ) remove loop-sys, exit the loop and continue execution after it
  • user ( n cchar – ) create a dictionary entry for a user variable at offset n
  • wlscope ( addr len – addr’ len’ wid ) dynamically place a word in a wordlist. The word name may be changed.

Dictionary (AVR8)

  • :command:`` ( n – ) compile 16 bit into flash at DP

Environment (AVR8)

  • /pad ( – padsize ) Size of the PAD buffer in bytes
  • wordlists ( – n ) maximum number of wordlists in the dictionary search order
  • mcu-info ( – faddr len ) flash address of some CPU specific parameters

Extended VM (AVR8)

  • a@ ( – n2 ) Read memory pointed to by register A (Extended VM)
  • a@- ( – n ) Read memory pointed to by register A, decrement A by 1 cell (Extended VM)
  • a@+ ( – n ) Read memory pointed to by register A, increment A by 1 cell (Extended VM)
  • a! ( n – ) Write memory pointed to by register A (Extended VM)
  • a!- ( – n2 ) Write memory pointed to by register A, decrement A by 1 cell (Extended VM)
  • a!+ ( – n2 ) Write memory pointed to by register A, increment A by 1 cell (Extended VM)
  • a> ( n1 – n2 ) read the A register (Extended VM)
  • b@ ( – n2 ) Read memory pointed to by register B (Extended VM)
  • b@- ( – n ) Read memory pointed to by register B, decrement B by 1 cell (Extended VM)
  • b@+ ( – n ) Read memory pointed to by register B, increment B by 1 cell (Extended VM)
  • b! ( n – ) Write memory pointed to by register B (Extended VM)
  • b!- ( – n2 ) Write memory pointed to by register B, decrement B by 1 cell (Extended VM)
  • b!+ ( – n2 ) Write memory pointed to by register B, increment B by 1 cell (Extended VM)
  • b> ( n1 – n2 ) read the B register (Extended VM)
  • na@ ( n1 – n2 ) Read memory pointed to by register A plus offset (Extended VM)
  • na! ( n offs – ) Write memory pointed to by register A plus offset (Extended VM)
  • nb@ ( n1 – n2 ) Read memory pointed to by register B plus offset (Extended VM)
  • nb! ( n offs – ) Write memory pointed to by register B plus offset (Extended VM)
  • >a ( n – ) Write to A register (Extended VM)
  • >b ( n – ) Write to B register (Extended VM)

Interrupt (AVR8)

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

Logic (AVR8)

  • 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 (AVR8)

  • !@spi ( n1 – n2 ) SPI exchange of 2 bytes, high byte first
  • 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
  • n@spi ( addr len – ) read len bytes from SPI to addr
  • n!spi ( addr len – ) write len bytes to SPI from addr
  • rx?-poll ( – f) check if a character can be appended to output queue using register poll
  • rx-poll (c – ) wait for one character and read it from the terminal connection using register poll
  • c!@spi ( txbyte – rxbyte) SPI exchange of 1 byte
  • tx?-poll ( – f) check if a character can be send using register poll
  • tx-poll (c – ) check availability and send one character to the terminal using register poll
  • ubrr ( – v) returns usart UBRR settings
  • +usart ( – ) initialize usart
  • wdr ( – ) calls the MCU watch dog reset instruction

Memory (AVR8)

  • 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.
  • c! ( c a-addr – ) store a single byte to RAM address
  • (!i-nrww) ( n f-addr – ) writes n to flash memory using assembly code (code to be placed in boot loader section)
  • @ ( 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
  • fill ( a-addr u c – ) fill u bytes memory beginning at a-addr with character c
  • ! ( 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

Multitasking (AVR8)

  • 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 (AVR8)

  • hld ( – addr ) pointer to current write position in the Pictured Numeric Output buffer

Search Order (AVR8)

  • forth-wordlist ( – wid ) get the system default word list
  • get-current ( – wid) get the wid of the current compilation word list
  • set-current ( wid – ) set current word list to the given word list wid
  • wordlist ( – wid ) create a new, empty wordlist

Stack (AVR8)

  • 2r@ ( – d) (R: d – d ) fetch content of TOR
  • 2r> ( – x1 x2 ) (R: x1 x2 –) move DTOR to TOS
  • 2>r ( x1 x2 – ) (R: – x1 x2) move DTOS to TOR
  • drop ( n – ) drop TOS
  • dup ( n – n n ) duplicate TOS
  • lp0 ( – addr) start address of leave 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
  • n>r ( x-n .. x-1 n – ) (R: – x-n .. x-1 n) move n items from data stack to return stack
  • over ( x1 x2 – x1 x2 x1 ) Place a copy of x1 on top of the stack
  • ?dup ( n1 – [ n1 n1 ] | 0) duplicate TOS if non-zero
  • rot ( n1 n2 n3 – n2 n3 n1) rotate the three top level cells
  • rp@ ( – n) current return stack pointer address
  • rp! ( addr – ) (R: – x*y) set return stack pointer
  • r@ ( – n) (R: n – n ) fetch content of TOR
  • r> ( – n ) (R: n –) move TOR to TOS
  • sp@ ( – addr ) current data stack pointer
  • sp! ( addr – i*x) set data stack pointer to addr
  • swap ( n1 n2 – n2 n1) swaps the two top level stack cells
  • >r ( n – ) (R: – n) move TOS to TOR

String (AVR8)

  • compare ( r-addr r-len f-addr f-len – f) compares two strings in RAM

System (AVR8)

  • allot ( n – ) allocate or release memory in RAM
  • cold ( i*x – ) (R: j*y – ) start up amforth.
  • (defer) ( i*x – j*x ) runtime of defer
  • (value) ( – n ) runtime of value
  • Edefer@ ( xt1 – xt2 ) does the real defer@ for eeprom defers
  • Edefer! ( xt1 xt2 – ) does the real defer! for eeprom defers
  • execute ( xt – ) execute XT
  • nfa>lfa ( nfa – lfa ) get the link field address from the name field address

System Value (AVR8)

  • 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
  • (marker) ( – e-addr ) The eeprom address until which MARKER saves and restores the eeprom data.
  • !i ( n addr – ) Deferred action to write a single 16bit cell to flash
  • turnkey ( – n*y ) Deferred action during startup/reset

System Variable (AVR8)

  • latest ( – addr ) system state
  • lp ( – addr ) leave stack pointer
  • newest ( – addr ) system state
  • state ( – addr ) system state
  • up@ ( – addr ) get user area pointer
  • up! ( addr – ) set user area pointer

Time (AVR8)

  • 1ms ( – ) busy waits (almost) exactly 1 millisecond

Tools (AVR8)

  • cfolddepth ( flagset – n ) constant fold depth
  • ee>ram ( e-addr r-addr len – ) copy len cells from eeprom to ram
  • 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
  • immediate? ( flagset – +/-1 ) return +1 if immediate, -1 otherwise, flag from name>flags
  • init-ram ( – ) setup the default user area from eeprom
  • itype ( addr n – ) reads string from flash and prints it
  • name>flags ( nt – f ) get the flags from a name token
  • nfa>cfa ( nt – xt ) get the XT from a name token
  • unused ( – n ) Amount of available RAM (incl. PAD)