avrforth is a 16-bit subroutine threaded forth kernel for atmel's avr series of microcontrollers. Current development is done for the at90can128 (my cansynth board, to be exact), but it will run on most any mega device with minimal adjustments.
avrforth borrows some ideas from Terry Loveall's 4word. It is a colorless colorforth. The interpreter only interprets. Words must be compiled explicitly using the ] operator. Numeric input is handled by $, which parses the next word as a hexidecimal number.
avrforth uses null-terminated strings internally against tradition. I may switch to counted strings if they prove easier to deal with.
avrforth supports using the entire 128k instruction address space of the atmega128 and at90can128 for code.
avrforth has an interactive interpreter. It interprets input from the uart and compiles directly to flash. avrforth does not require separate memory to store program tokens.
avrforth has an integrated assembler. Assembly code words can be added without recompiling the kernel.
avrforth is public domain.
You need a host forth system to assemble avrforth. Development is done with gforth. You also need a utility to program the flash and a terminal program to communicate with the kernel through the avr's uart. I use avrdude and picocom for those tasks.
a quick run through...
Now you can send more program code or type commands interactively at the console.
Documentation has been pretty sparse but is getting better. Email me if there is anything in particular you need to know about.
Support for at90usb647 and at90usb1287.
Driver for device mode USB controller.
Vim syntax highlighting description.
Support for interrupt serivice routines in forth. Use the words
int; instead of
; to define a word and store it to a ram vector
provided by one of the peripheral drivers.
Support for (optional) separate interrupt stacks. This feature avoids having to make all task stacks large enough for the task and interrupt code. Configuration of stack sizes is in config.f.
task-dequeue added to remove a task from the task
-! added to complement
New drivers for spi and external memory which are more comprehensive than the previous versions.
Additional factoring in the assembler.
New a/d driver which is more comprehensive than the old version.
Make task initization easier --
task-init now takes
the size of return and data stacks as parameters instead of the
actual pointer addresses.
create-file instead of
the assembler to open files for writing.
Add predecrement memory access words:
Predecrement and postincrement words that write to memory now take the
address on the top of stack like
!. They previously took
the data on the top of stack.
Make send.f work for gforth versions < 0.6.9-20070604.
Added support for atmega48, atmega88, and atmega168. avrforth now runs on the arduino.
Added timer driver.
idump debugging word.
;; a macro (bugfix).
Fall back to the proper unoptimized versions of
if there are no literals (bugfix).
Use ram addresses instead of io addresses for atmega32 register definitions.
New gpio driver which simply creates constants for all
Added autoincrement memory words:
!+. debug.f depends on
which wasn't included previously.
New forth implementation of the 'send' shell script to send source files via the serial port. This version waits for avrforth to send a newline before sending the next line of source. The previous version simply waited a constant amount of time.
Support for at90can32 and at90can64.
Allow atmega8 and atmega32 to assemble again.
Turnkey action: the xt stored in the eeprom variable
will be executed at startup.
Bugfix for prescaler setting in timer initialization.
Support for atmega16 and atmega162.
single stops all tasks except the interpreter.
2/ words to core.f. They were
originally just macros.
Started debug.f, which contains
dump for inspecting memory.
Made location of gforth configurable in the makefile.
Support for atmega128.
Initial versions of extended precision arithmetic and linear interpolation wordsets.
avrforth has been rewritten to use my own forth style assembler, which is included under asm/. Presently, only the at90can128 has been tested -- support for other devices will be added back eventually.
Renamed bit operations
clear. Added byte flag words
off with the usual meaning.
Added words to control external memory.
xmem enables external
bank selects the current bank. Current support
assumes 128k of sram and maps it from $8000 to $ffff in 4 banks. Different
configurations can be handled by modifying the source.
Updated atmega8 defines.
Initial twi driver.
Smaller and faster implementation of
New words, mainly double cell:
Updated atmega32 support.
Fixed a bug with conditional assembly that prevented usart initialization from occurring if usart0 was selected.
Ensured that the can driver is only included for the at90can128.
mobrxb now clear
status bits before enabling the mob.
pause while waiting for spi transfer to complete.
Switched back to round robin cooperative multitasking.
ec! support eeprom byte access.
evar allocates variables in eeprom.
ticks returns system tick counter.
var now requires the length of variable to allocate.
rot no longer reverses the second stack item (bugfix).
Initial can driver.
The usart driver is now interrupt driven. The sizes of the tx and rx circular buffers can be set in config.asm.
avrforth has switched to a state machine type multitasking. There is now
a periodic timer interrupt to run tasks.
add and remove tasks from the active list.
int> save and restore registers
for use in interrupt service routines.
initial drivers for the spi and a/d converter.
within to core wordset.
off to set and clear bits.
Literals are optimized to sbi and cbi instructions.
supported multiple usarts.
moved target specific defines to config.asm.
pop renamed to
ones to avoid confusion with the
emit now use vectored i/o.
'emit are the respective vectors.
interface with the usart and are the default values for these vectors.
then, and the various
ifs are now macros.
b. are new words for hex output that use
digit as factors.
pop calculates population count (number of ones).
ntz calculates number of trailing zeros.
f! fetch and store condition codes.
0? tests the TOS, like
? used to.
? now compares the TOS with a literal.
Added some double cell words:
High level multiplication:
High level division:
umod. Fixed bug in
Large input values are now handled correctly.
Support for counted loops:
-next. The index is stored on the return stack.
words a high level word. Added
and a common factor
false affect the condition codes
for a future
i! now only performs an erase cycle if a bit needs to change
from 0 to 1; saves flash cycles.
Added high level register definitions for the at90can128. My main avrforth development board is the cansynth.
?dupwhich removes a preceding
dropor compiles a
dupif the previous word was not a
+now have macros which produce optimized code when preceded by a literal.
jumpnow uses a list of addresses since calls are no longer always two words due to the rcall optimization.
."which prevented it from working with odd-length strings.
gowhich was reseting the stack pointers after each line of input.
??, which performs a nondestructive comparision (much like
?is a nondestructive test). added support for the atmega16. the compiler now uses relative addressing instructions if they will reach (rcall and rjmp).
m/mod. moved usart words to a separate driver source file.
*. Also changed over a few more i/o instructions to use the optimizing macros.
.dbwith an odd number of bytes.
jumpimplements jump tables, and
waitwaits for a bit flag deferring with pause until the flag is set. also changed a few calls to rcalls.
orare optimized for literals in the kernel. the next step is to add macros to use the optimizations in compiled code.
ecellshave been removed. since you already need to keep track of which memory space you're using on the avr, remembering to add in a
2*is not such a big deal.
taskinitinitializes a task stack frame.
taskqueueputs a task in the round robin queue.
pausedefers execution to other tasks.
thenhigh level words. added
-ifare non-destuctive now (they branch based on cpu flags and don't consume the top stack item). added atmega8 as supported target. added
ecells. also added
emptyto save/restore interpreter state.
1-are now macros. added
i!, and others rewritten as high level words
idpback in ram
idpput in registers