1. Interpreter
The outer interpreter looks for words and numbers delimited by whitespace. Everything is interpreted as a word or a number. Numbers are pushed onto the stack. Words are looked up and acted upon. Names of words are limited to 15 characters. Some words are compile-time use only and cannot be used interpretively. These are noted in the result column.
2. Data and the stack
The data stack (S:) is directly accessible and has 16-bit cells for holding numerical values. Functions get their arguments from the stack and leave their results there as well. There is also a return address stack (R:) that can be used for temporary storage.
2.1. Notation
Notation |
Meaning |
|
Single-cell integers (16-bit). |
|
Unsigned integers (16-bit). |
|
Single-cell item (16-bit). |
|
Character value (8-bit). |
|
Double-cell signed and unsigned (32-bit). |
|
Triple-cell signed and unsigned (48-bit). |
|
Quad-cell signed and unsigned (64-bit). |
|
Boolean flag: 0 is false, -1 is true. |
|
16-bit addresses. |
|
cell-aligned address. |
|
character or byte address. |
|
32-bit address. |
2.2. Numbers and values
Code |
Result |
|
Leave integer two onto the stack. |
|
Leave decimal 255 onto the stack. |
|
Leave integer three onto the stack. |
|
Leave integer sixteen onto the stack. |
|
Leave double number on the stack. |
|
Set number format to base 10. |
|
Set number format to hexadecimal. |
|
Set number format to binary. |
|
Sign extend single to double number. |
2.3. Displaying data
Word |
Result |
|
Display a number. |
|
Display u unsigned. |
|
Display u with field width n, 0<n<256. |
|
Display double number. |
|
Display unsigned double number. |
|
Display stack content (nondestructively). |
|
Emit status string for base, current data section, and display the stack contents. |
|
Display memory from address, for u bytes. |
2.4. Stack manipulation
Word |
Result |
|
Duplicate top item. |
|
Duplicate top item if nonzero. |
|
Swap top two items. |
|
Copy second item to top. |
|
Discard top item. |
|
Remove x1 from the stack. |
|
Rotate top three items. |
|
Insert x2 below x1 in the stack. |
|
Duplicate the u-th item on top. |
|
Duplicate top double-cell item. |
|
Swap top two double-cell items. |
|
Discard top double-cell item. |
|
Send to return stack. |
|
Take from return stack. |
|
Copy top item of return stack. |
|
Discard top item of return stack. |
|
Leave data stack pointer. |
|
Set the data stack pointer to address. |
3. Operators
3.1. Arithmetic with single-cell numbers
Some of these words require core.fs
and math.fs
.
Word |
Result |
|
Add. |
|
Subtract. |
|
Multiply. |
|
Divide. |
|
Divide. |
|
Divide. |
|
Unsigned 16/16 to 16-bit division. |
|
Unsigned division. |
|
Leave one. |
|
Add one. |
|
Subtract one. |
|
Add two. |
|
Subtract 2 from n. |
|
Multiply by 2; Shift left by one bit. |
|
Divide by 2; Shift right by one bit. |
|
Scale. |
|
Scale with remainder. |
|
Unsigned Scale u1*u2/u3 |
|
Absolute value. |
|
Negate n. |
|
Negate n1 if n2 is negative. |
|
Leave minimum. |
|
Leave maximum. |
|
Unsigned minimum. |
|
Unsigned maximum. |
3.2. Arithmetic with double-cell numbers
Some of these words require core.fs
, math.fs
and qmath.fs
.
Word |
Result |
|
Add double numbers. |
|
Subtract double numbers. |
|
Add single cell to double number. |
|
Signed 16*16 to 32-bit multiply. |
|
Multiply by 2. |
|
Divide by 2. |
|
Unsigned 16x16 to 32 bit multiply. |
|
Unsigned 32x16 to 32-bit multiply. |
|
Unsigned division. |
|
Unsigned division. |
|
Floored division. |
|
Symmetric division. |
|
Scale with triple intermediate result. |
|
Scale with triple intermediate result. |
|
Absolute value. |
|
Negate double number. |
|
Negate d if n is negative. |
3.3. Relational
Word |
Result |
|
Leave true if x1 x2 are equal. |
|
Leave true if x1 x2 are not equal. |
|
Leave true if n1 less than n2. |
|
Leave true if n1 greater than n2. |
|
Leave true if n is zero. |
|
Leave true if n is negative. |
|
Leave true if xl ⇐ x < xh. |
|
Leave true if u1 < u2. |
|
Leave true if u1 > u2. |
|
Leave true if d1 d2 are equal. |
|
Leave true if d is zero. |
|
Leave true if d is negative. |
|
Leave true if d1 < d2. |
|
Leave true if d1 > d2. |
3.4. Bitwise
Word |
Result |
|
Ones complement. |
|
Invert double number. |
|
Bitwise and. |
|
Bitwise or. |
|
Bitwise exclusive-or. |
|
Left shift by u bits. |
|
Right shift by u bits. |
4. Memory
Typically, the microcontroller has three distinct memory contexts: Flash, EEPROM and SRAM. FlashForth unifies these memory spaces into a single 64kB address space.
4.1. AVR8 Memory map
All operations are restricted to 64kB byte address space that is divided into:
Range |
Use |
|
SRAM |
|
EEPROM |
|
Flash |
The SRAM space includes the IO-space and special function registers. The high memory mark for the Flash context is set by the combined size of the boot area and FF kernel.
4.2. Memory Context
Word |
Result |
|
Set address context to SRAM. |
|
Set address context to EEPROM. |
|
Set address context to Flash. |
|
Disable writes to Flash, EEPROM. |
|
Enable writes to Flash, EEPROM, default. |
|
Flush the flash write buffer. |
|
Leave the current data section dictionary pointer. |
|
Align the current data section dictionary pointer to cell boundary. |
|
Leave the high limit of the current data space. |
4.3. Accessing Memory
Word |
Result |
|
Store x to address. |
|
Fetch from address. |
|
Fetch cell and increment address by cell size. |
|
Store 2 cells to address. |
|
Fetch 2 cells from address. |
|
Store character to address. |
|
Fetch character from address. |
|
Fetch char, increment address. |
|
Add n to cell at address. |
|
Fetch from addr and decrement addr by 2. |
|
Write to the A register. |
|
Read from the A register. |
4.4. Accessing Extended (Flash) Memory
Word |
Result |
|
Store u to real flash address. |
|
Fetch from real flash address. |
4.5. Accessing bits in RAM
Word |
Result |
|
Set bits in file register with mask c. |
|
Clear bits in file register with mask c. |
|
AND file register byte with mask c. |
The following come from bit.fs
|
Define a word to set a bit. |
|
Define a word to clear a bit. |
|
Define a word to test a bit. |
5. The Dictionary
5.1. Dictionary management
Code |
Result |
|
Mark the dictionary and memory allocation state with |
|
Return to the dictionary and allotted-memory state that existed before |
|
Find name in dictionary. |
|
Forget dictionary entries back to name. |
|
Reset all dictionary and allotted-memory pointers. |
|
List all words in dictionary. |
|
List words containing xxx. |
5.2. Defining constants and variables
Code |
Result |
|
Define new constant. |
|
Define double constant. |
name |
Leave value on stack. |
|
Define a variable in the current data section. |
|
Define double variable. |
varname |
Leave address on stack. |
|
Define value. |
|
Assign new value to valname. |
valname |
Leave value on stack. |
|
Define a user variable at offset |
5.3. Examples
Code |
Result |
|
Set SRAM context for variables and values. Be careful not to accidentally define variables in EEPROM or Flash memory. That memory wears quickly with multiple writes. |
|
Define value in SRAM. |
|
Define variable in SRAM. |
|
Store 6 in variable |
|
Define value in EEPROM. |
|
Leaves |
|
Warm restart clears SRAM data. |
|
Leaves |
|
Sets new value. |
|
Leaves |
|
Prints the number of bytes free. |
|
Sets RB1 as output. |
|
Defines a word to set RB1 high. |
|
Sets RB1 high. |
5.4. Defining compound data objects
Code |
Result |
|
Create a word definition and store the current data section pointer. |
|
Define the runtime action of a created word. compile only |
|
Advance the current data section dictionary pointer by u bytes. |
|
Append x to the current data section. |
|
Append c to the current data section. |
|
Append a string at HERE. |
|
Append x to the flash data section. |
|
Append c to the flash data section. |
|
Compile xt into the flash dictionary. |
|
Convert code field addr to name field addr. |
|
Convert name field addr to code field addr. |
|
Convert |
|
Leave the data field address of the created word. |
|
Define headerless forth code. |
5.5. Array examples
Code | Comments |
---|---|
ram |
We want these arrays made in RAM memory. |
create my-array 20 allot my-array 20 $ff fill my-array 20 dump |
Create an array, fill it with 1s, and display its content. |
create my-cell-array 100 , 340 , 5 , |
Initialise an array of cells. |
my-cell-array 2 cells + @ |
Should leave 5. |
create my-byte-array 18 c, 21 c, 255 c, |
Initialised an array of bytes. |
my-byte-array 2 chars + c@ |
Should leave 255. |
: mk-byte-array create allot does> + ; |
Make our own defining word to make byte array objects, as shown in the FF User’s Guide. |
10 mk-byte-array my-bytes |
Creates an array object my-bytes, which has stack effect |
18 0 my-bytes c! |
Sets an element. The execution |
21 1 my-bytes c! |
Sets another. |
255 2 my-bytes c! |
And another. |
2 my-bytes c@ |
Should leave 255. The execution of |
: mk-cell-array create cells allot does> swap cells + ; |
Make a defining word, this time to make cell array objects.
Its stack effect is |
5 mk-cell-array my-cells |
Creates an array object |
3000 0 my-cells ! |
Sets an element. |
45000 1 my-cells ! |
…and another. |
63000 2 my-cells ! |
…and another. |
1 my-cells @ . |
Should print |
5.6. Memory operations
Some of these words come from core.fs
.
Word |
Result |
|
Move |
|
Fill u bytes with c starting at address. |
|
Fill u bytes with 0 starting at address. |
|
Fill u bytes with spaces starting at address. |
|
Convert cells to address units. |
|
Convert chars to address units. |
|
Add one to address. |
|
Add size of cell to address. |
|
Align address to a cell boundary. |
5.7. Predefined constants
Word |
Result |
|
Size of one cell in characters. |
|
Boolean true value. |
|
Boolean false value. |
|
ASCII space. |
|
Leave the cpu instruction-cycle frequency in kHz. |
|
Size of the terminal input buffer. |
5.8. Predefined variables
Word |
Result |
|
Variable containing number base. |
|
Interrupt vector (SRAM variable). |
|
Vector for user start-up word. |
|
Deferred execution vector for the info displayed by quit. |
|
EMIT vector. Default is |
|
KEY vector. Default is |
|
KEY? vector. Default is |
|
Current input source. |
|
Variable holding the address of the latest defined word. |
|
Variable for start of data stack. |
|
Bottom of return stack. |
|
Number of saved return stack cells. |
|
Address of the terminal input buffer. |
|
Terminal input buffer pointer. |
|
Variable containing the offset, in characters,
from the start of |
|
Address of the temporary area for strings. |
|
Leave the address of the current data section
dictionary pointer. |
|
Hold pointer for formatted numeric output. |
|
Variable holding a user pointer. |
6. The Compiler
6.1. Defining functions
Code |
Result |
|
Begin colon definition. |
|
End colon definition. |
|
Enter interpreter state. |
|
Enter compilation state. |
|
Compilation state. |
|
End an interrupt word. |
|
Compile value on stack at compile time. |
|
Compile double value on stack at compile time. |
|
Inline the following word. |
|
Mark the last compiled word as inlined. |
|
Mark latest definition as immediate. |
|
Leave a nonzero value if addr contains an immediate flag. |
|
Leave a nonzero flag if |
|
Postpone action of immediate word. !( — )! compile only |
|
Show definition. Load |
6.2. Comments
Word |
Result |
|
Inline comment. Note that there needs to be a space after the opening parenthesis. |
|
Skip rest of line. |
6.3. Examples of colon definitions
Code | Comments |
---|---|
: square ( n -- n**2 ) dup * ; |
Example with stack comment and |
7. Flow control
These control flow words can be used in a compile context only.
7.1. Structured flow control
Code |
Comments |
|
Conditional execution. |
|
Infinite loop. |
|
Loop until cond is true. |
|
Loop while cond is true. |
|
Loop u times. |
|
Sets loop counter to zero so that we leave
a |
From doloop.fs
, we get the ANSI loop constructs which iterate from initial
up to, but not including, limit:
limit initial |
|
limit initial |
|
|
Leave the current loop index. |
|
Leave the next-outer loop index. |
|
Leave the do loop immediately. |
|
Starts a do loop which is not run if
the arguments are equal. |
7.2. Loop examples
Code |
Result |
|
|
|
|
|
|
|
7.3. Case example
From case.fs
, we get words case
, of
, endof
, default
and endcase
to define case constructs.
: testcase 4 for r@ case 0 of ." zero " endof 1 of ." one " endof 2 of ." two " endof default ." default " endof endcase next ;
7.4. Unstructured flow control
Code |
Result |
|
Exit from a word. |
|
Reset stack pointer and execute quit. |
|
If flag is false, print message and abort. |
|
If flag is false, output ? and abort. |
|
if flag is false, type out last word executed, followed by text xxx. |
|
Interpret from keyboard. |
|
Make a warm start.
Reset reason will be displayed on restart. |
7.5. Vectored execution (Function pointers)
|
Search for name and leave its execution token (address). |
|
Search for name and compile it’s execution token. |
|
Execute word at address. |
|
Fetch vector from addr and execute. |
|
Define a deferred execution vector. |
|
Store execution token in vec-name. |
vec-name |
Execute the word whose execution token is stored in the data space of vec-name. |
|
Store interrupt vector to table. |
7.6. Autostart example
Code |
Result |
|
Autostart my-app. |
|
Disable turnkey application. |
7.7. Interrupt example
This example is taken directly from the FlashForth source.
ram variable icnt1 : irq_forth \ The service function is a Forth colon definition [i \ in the Forth interrupt context. icnt1 @ 1+ icnt1 ! ]i ;i ' irq_forth 0 int! \ Set the user interrupt vector. : init \ Alternatively, compile a word ['] irq_forth 0 int! \ so that we can install the ; \ interrupt service function ' init is turnkey \ at every warm start.
8. The P register
The P register can be used as a variable or as a pointer.
It can be used in conjunction with for
… next
or at any other time.
Word |
Result |
|
Store address to P(ointer) register. |
|
Fetch the P register to the stack. |
|
Push contents of P to return stack and store new address to P. |
|
Pop from return stack to P register. |
|
Increment P register by one. |
|
Add 2 to P register. |
|
Add n to the p register. |
|
Store x to the location pointed to by the p register. |
|
Store c to the location pointed to by the p register. |
|
Fetch the cell pointed to by the p register. |
|
Fetch the char pointed to by the p register. |
In a definition, !p>r
and r>p
should always be used
to allow proper nesting of words.
9. Characters
Code |
Result |
|
Convert char to a digit according to base. |
|
Convert n to ascii character value. |
|
Convert a character to an ASCII value. |
|
Parse a character and leave ASCII value. |
|
Compile inline ASCII character. |
9.1. Strings
Some of these words come from core.fs
.
Code |
Result |
|
Compile string into flash. |
|
Compile string to print into flash. |
|
Place string from a1 to a2 as a counted string. !( addr1 u addr2 — )! |
|
Compare strings in RAM( |
|
Scan string until |
|
Skip chars until |
|
Trim string. |
|
Convert string to a number. |
|
Convert string to a number and flag. |
|
Get optional minus sign. |
|
Type line to terminal, |
|
Get line from the terminal. |
|
Leave address of input buffer and number of characters. |
|
Interpret a string in SRAM. |
|
Interpret the buffer. |
|
Parse a word in TIB. |
|
Parse a word in TIB and write length into TIB.
Leave the address of length byte on the stack. |
9.2. Pictured numeric output
Formatted string representing an unigned double-precision integer
is constructed in the end of tib
.
Digits are converted in order of least significant to most significant.
Word |
Result |
|
Begin conversion to formatted string. |
|
Convert 1 digit to formatted string. |
|
Convert remaining digits. |
|
Add char to formatted string. |
|
Add minus sign to formatted string, if |
|
End conversion, leave address and count
of formatted string. |
For example, the following:
-1 34. <# # # #s rot sign #> type
results in -034 ok
A more useful example might be to define a word that formats a double value to include a decimal point before the last two digits.
: (d.2) ( d -- ) swap over dabs <# # # [char] . hold #s rot sign #> ;
Now, the following:
-34. (d.2) type
results in -0.34 ok
10. Interaction with the operator
Interaction with the user is via a serial communications port, typically UART1.
Settings are 38400 baud, 8N1, using Xon/Xoff handshaking.
Which particular serial port is selected is determined by the
vectors 'emit
, 'key
and 'key?
.
Word |
Result |
|
Emit c to the serial port FIFO. |
|
Emit one space character. |
|
Emit n space characters. |
|
Emit carriage-return, line-feed. |
|
Get a character from the serial port FIFO. |
|
Leave true if character is waiting in the serial port FIFO. |
10.1. Serial communication ports
Word |
Result |
|
Send a character via UART0. |
|
Receive a character from UART0. |
|
Leave !true! if the UART0 receive buffer is not empty. |
|
Disable flow control for UART0 interface. |
|
Enable flow control for UART0 interface, default. |
|
Send character to UART1. |
|
Receive a character from UART1. |
|
Leave |
|
Disable flow control for UART1 interface. |
|
Enable flow control for UART1 interface, default. |
|
Disable flow control for UART2 interface. |
|
Enable flow control for UART2 interface, default. |
10.2. Other Hardware
Word |
Result |
|
Clear the WatchDog counter. |
|
Enable interrupts. |
|
Disable interrupts. |
|
Unlock Peripheral Pin Select registers. |
|
Lock Peripheral Pin Select registers. |
|
Pause for |
|
System ticks, 0—ffff milliseconds. |
11. Multitasking
Load the words for multitasking from task.fs
.
Word |
Result |
|
Define a new task in flash memory space. |
|
Initialise a user area and link it
to the task loop. |
|
Leave the address of the task definition table. |
|
Makes a task run by inserting it after operator
in the round-robin linked list. |
|
Remove a task from the task list. |
|
End all tasks except the operator task. |
|
List all running tasks. |
|
Switch to the next task in the round robin task list. |
|
Access user variables of other task. |
|
Leave the CPU load on the stack. |
|
Enable the load LED on AVR8. |
|
Disable the load LED on AVR8. |
|
CPU idle mode not allowed. |
|
CPU idle is allowed. |
|
Leave the address of the operator task. |
|
Link to next task. |
12. Structured Assembler
To use many of the words listed in the following sections, load the text file asm.fs
.
The assembler for each processor family provides the same set of structured flow control words,
however, the conditionals that go with these words are somewhat processor-specific.
Code |
Result |
|
Conditional execution. |
|
Loop indefinitely. |
|
Loop until condion is true. |
13. Assembler words for AVR8
For the ATmega instructions,
Rd
denotes the destination (and source) register,
Rr
denotes the source register,
Rw
denotes a register-pair code,
K
denotes constant data,
k
is a constant address, b
is a bit in the register,
x,Y,Z
are indirect address registers, A
is an I/O location address,
and q
is a displacement (6-bit) for direct addressing.
13.1. Conditions for structured flow control
Word |
Result |
|
carry set |
|
zero |
|
half carry set |
|
interrupt enabled |
|
lower |
|
less than |
|
negative |
|
T flag set |
|
no overflow |
|
invert condition |
13.2. Register constants
Word |
Result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Word |
Result |
Word |
result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13.3. Arithmetic and logic instructions
Word |
Result |
|
Add without carry. |
|
Add with carry. |
|
Add immediate to word. |
|
Subtract without carry. |
|
Subtract immediate. |
|
Subtract with carry. |
|
Subtract immediate with carry. |
|
Subtract immediate from word. |
|
Logical AND. |
|
Logical AND with immediate. |
|
Logical OR. |
|
Logical OR with immediate. |
|
Exclusive OR. |
|
One’s complement. |
|
Two’s complement. |
|
Set bit(s) in register. |
|
Clear bit(s) in register. |
|
Increment. |
|
Decrement. |
|
Test for zero or minus. |
|
Clear register. |
|
Set register. |
|
Multiply unsigned. |
|
Multiply signed. |
|
Multiply signed with unsigned. |
|
Fractional multiply unsigned. |
|
Fractional multiply signed. |
|
Fractional multiply signed with unsigned. |
13.4. Branch instructions
Word |
Result |
|
Relative jump. |
|
Indirect jump to (Z). |
|
Extended indirect jump to (Z). |
|
Jump. |
|
Relative call subroutine. |
|
Indirect call to (Z). |
|
Extended indirect call to (Z). |
|
Call subroutine. |
|
Subroutine return. |
|
Interrupt return. |
|
Compare, skip if equal. |
|
Compare. |
|
Compare with carry. |
|
Compare with immediate. |
|
Skip if bit in register cleared. |
|
Skip if bit in register set. |
|
Skip if bit in I/O register cleared. |
|
Skip if bit in I/O register set. |
13.5. Data transfer instructions
Word |
Result |
|
Copy register. |
|
Copy register pair. |
|
Load immediate. |
|
Load direct from data space. |
|
Load indirect. |
|
Load indirect with displacement. |
|
Store direct to data space. |
|
Store indirect. |
|
Store indirect with displacement. |
|
In from I/O location. |
|
Out to I/O location. |
|
Push register on stack. |
|
Pop register from stack. |
13.6. Bit and bit-test instructions
Word |
Result |
|
Logical shift left. |
|
Logical shift right. |
|
Rotate left through carry. |
|
Rotate right through carry. |
|
Arithmetic shift right. |
|
Swap nibbles. |
|
Flag set. |
|
Flag clear. |
|
Set bit in I/O register. |
|
Clear bit in I/O register. |
|
Bit store from register to T. |
|
Bit load from T to register. |
|
Set carry. |
|
Clear carry. |
|
Set negative flag. |
|
Clear negative flag. |
|
Set zero flag. |
|
Clear zero flag. |
|
Global interrupt enable. |
|
Global interrupt disable. |
|
Set signed test flag. |
|
Clear signed test flag. |
|
Set two’s complement overflow. |
|
Clear two-s complement overflow. |
|
Set T in SREG. |
|
Clear T in SREG. |
|
Set half carry flag in SREG. |
|
Clear half carry flag in SREG. |
13.7. MCU control instructions
Word |
Result |
|
Break. |
|
No operation. |
|
Sleep. |
|
Watchdog reset. |
14. Synchronous serial communication
14.1. I2C communications as master
The following words are available as a common set of words for ATmega328P microcontrollers.
Load them from a file with a name like i2c-base-XXXX.fs
where XXXX
is the specific microcontroller.
Word |
Result |
|
Initializes I2C master mode, 100 kHz clock. |
|
Shut down the peripheral module. |
|
Leaves |
|
Address slave device for writing. |
|
Send byte and leave |
|
Address slave device for reading. |
|
Fetch a byte and |
|
Fetch one last byte. |
Low level words.
Word |
Result |
|
Leave |
|
Send start condition. |
|
Send restart condition. |
|
Send stop condition. |
|
Poll the I2C hardware until the operation has finished. |
|
Clock through bits so that slave devices are sure to release the bus. |
14.2. SPI communications as master
The following words are available as a common set of words for ATmega328P microcontrollers.
Load them from a file with a name like spiN-base-XXXX.fs
where XXXX
is the specific microcontroller and N
identifies the particular SPI module.
Because SPI devices are so varied in their specification, you likely have to
adjust the register settings in spi.init
to suit your particular device.
Word |
Result |
|
Initializes SPI master mode, 1 MHz clock. |
|
Shut down the peripheral module. |
|
Poll the SPI peripheral until the operation has finished. |
|
Send byte |
|
Send byte |
|
Select the external device. |
|
Deselect the external device. |
Bibliography
This reference assembled by Peter Jacobs, School of Mechanical Engineering, The University of Queensland, February-2016 as Report 2016/02. Ported to ASCIIDOC 2022-01-02.
This specific version was lightly edited by Lief Koepsel to only represent AVR8 microcontrollers.
It is a remix of material from the following sources:
-
FlashForth v5.0 source code and word list by Mikael Nordman http://flashforth.com/
-
EK Conklin and ED Rather Forth Programmer’s Handbook 3rd Ed. 2007 FORTH, Inc.
-
L Brodie Starting Forth 2nd Ed., 1987 Prentice-Hall Software Series.
-
Atmel 8-bit AVR Insturction Set Document 08561-AVR-07/10.