eForth for the Teensy 3.6

Porting the version of eForth I had running on the MSP430 to the Teensy 3.6 wasn't too dificult. The hard part was the initialization of the hardware. It is very difficult to find problems when about the only diagnostic aid is the LED since JTAG isn't available. (The connections are broken out to pads but the on board boot loader prevents their use.)

The one major PITA is that this is a Cortex M4 CPU which means 16 bit thumb mode only. ARM CPUs that support thumb mode indicate which mode to use via the lsb of the address. This causes difficulty with Forth because at times I need to use an address to load a value from memory and at others I want to transfer execution to that address. The lsb must be cleared for the first and must be set for the second.

You might think that since only the thumb mode is supported that the CPU would ignore that mode bit. But it doesn't. Have I mentioned lately that I hate mode bits? (I suggest reading "The Soul of a New Machine" to get another angle on that thought.)

Source code:

Teensy 3.6 eForth

In addition to the eForth core there are some extensions. Some basic support for floating point operations, SD card support of course, interrupts, and my take on the Forth cooperative multitasker.


One new feature in this port of eForth is the ability to have an interrupt execute an eForth word. Most of the interrupt vectors point to a single assembly language routine that uses the vector number to index into a RAM table. The word VECTOR! stores the address of the high level ISR into the table.

Most of the registers that need to be saved were already saved by the default interrupt actions so only a couple more are needed. Transferring execution is simple because this is direct threaded code. Just jump to the code address of the desired definition. Getting back is trickier.

The high level ISR code will exit using the eForth word EXIT. This pops the Forth return stack into the instruction pointer which is then used by NEXT to get the next code address. So a short dummy high level address list is created at isr_exit_list and it points to the exit code.

With this ability and the high speed of the ARM I can avoid having to write ISRs in assembly. And writing a new ARM assembler in Forth. I have written Forth assemblers before (most recently for the MSP430) and that is pretty easy. But the instruction set for the Thumb mode looks fairly complicated. Perhaps it is simpler once you dig into it but I can postpone that for a while now.

From the users viewpoint the only new word is VECTOR! which takes a code address (TICK the word to execute) and vector number. One caution: executing COLD after starting up an interrupt will almost certainly crash the system. It may take a while since the ISR code will not vanish immediately. But eventually it will be overwritten.

See my logger code for an example.