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.