Distribution Readme

@
@    Mecrisp-Stellaris - A native code Forth implementation for ARM-Cortex M microcontrollers
@    Copyright (C) 2013  Matthias Koch
@
@    This program is free software: you can redistribute it and/or modify
@    it under the terms of the GNU General Public License as published by
@    the Free Software Foundation, either version 3 of the License, or
@    (at your option) any later version.
@
@    This program is distributed in the hope that it will be useful,
@    but WITHOUT ANY WARRANTY; without even the implied warranty of
@    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@    GNU General Public License for more details.
@
@    You should have received a copy of the GNU General Public License
@    along with this program.  If not, see <http://www.gnu.org/licenses/>.
@

;------------------------------------------------------------------------------
This is the stable release of Mecrisp-Stellaris,
a port of Mecrisp to the ARM Cortex M architecture.

It runs out of the box on:
  - TI Stellaris/Tiva Launchpad  with LM4F120H5QR / TM4C123GH6PM
  - TI Tiva Connected Launchpad  with TM4C1294NCPDT
  - TI MSP432 Launchpad          with MSP432P401R
  - STM L053 Discovery           with STM32L053C8T6
  - STM Nucleo L152RE            with STM32L152RE
  - STM Nucleo 401RE             with STM32F401RE
  - STM Nucleo 411RE             with STM32F411RET6
  - STM F0 Discovery             with STM32F051R8
  - STM VL Discovery             with STM32F100RB
  - Shenzhen LC Technology board with STM32F103C8T6
  - STM F3 Discovery             with STM32F303VCT6
  - STM F4 Discovery             with STM32F407VGT6
  - STM F429 Discovery           with STM32F429ZIT6
  - Freescale Freedom FRDM-KL25Z with KL25Z128VLK4
  - Freescale Freedom FRDM-KL46Z with KL46Z256VLL4
  - Freescale Freedom FRDM-K64F  with MK64FN1M0VLL12
  - Infineon XMC2GO              with XMC1100Q024F0064
  - EFM32 Giant Gecko            with EFM32GG990F1024
  - EFM32 Happy Gecko            with EFM32HG322F64

  - Breadboard friendly, DIP packaged LPC1114FN28
  -                                   LPC1114FBD48
  -                                   LPC1115FBD48
  - Very small TSSOP20 packaged       STM32F030F4

Contributions:
  - Teensy 3.1                   with MK20DX256VLH7
  - Chinese QF-LM4F232           with LM4F232H5QC
  - nRFgo Starter Kit & Microbit with nRF51822
  - STM L152 Discovery           with STM32L152RBT6
  - STM Nucleo L073RZ            with STM32L073RZ
  - STM Nucleo F207ZG            with STM32F207ZG
  - STM Nucleo F303K8            with STM32F303K8
  - STM Nucleo F303RE            with STM32F303RE
  - Espruino Pico                with STM32F401CD
  - STM Nucleo L432KC            with STM32L432KC
  - STM L476 Discovery           with STM32L476VG
  - STM F746 Discovery           with STM32F746NG
  - Atmel SAME70 X-plained       with ATSAME70Q21

http://mecrisp.sourceforge.net/

m-atthias@users.sf.net
;------------------------------------------------------------------------------

Mecrisp finally got a younger sister and mastered the jump
to the ARM Cortex M instruction set.

They share most of the design ideas, so Mecrisp-Stellaris can compile
directly into Flash, generates native code with constant folding and
inlining of short words.

Communication is via serial 115200 baud 8N1 over
  - UART0  in LM4F120   (connected to USB-serial bridge on Stellaris Launchpad)
  - UART0  in TM4C1294  (connected to USB-serial bridge on Tiva Connected Launchpad)
  - USCI0  in MSP432P401R  (TX on P1.3, RX on P1.2, connected to USB-serial bridge)
  - UART   in LPC1114FN28  (TX on P1.7, RX on P1.6)
  - UART   in LPC1114FBD48 (TX on P1.7, RX on P1.6)
  - UART   in LPC1115FBD48 (TX on P1.7, RX on P1.6)
  - USART1 in STM32F051    (TX on PA9, RX on PA10)
  - USART1 in STM32F030F4  (TX on PA9, RX on PA10)
  - USART1 in STM32F100    (TX on PA9, RX on PA10)
  - USART1 in STM32F103    (TX on PA9, RX on PA10)
  - USART1 in STM32F303    (TX on PA9, RX on PA10)
  - USART1 in STM32F429    (TX on PA9, RX on PA10)
  - USART1 in STM32L053C8  (TX on PA9, RX on PA10)
  - USART2 in STM32F401    (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
  - USART2 in STM32F407    (TX on PA2, RX on PA3)
  - USART2 in STM32F411    (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
  - USART2 in STM32L152    (TX on PA2, RX on PA3 connected to USB-serial bridge on Nucleo board)
  - USART2 in STM32L476    (TX on PD5, RX on PD6 connected to USB-serial bridge on Discovery board)
  - UART0  in KL25Z128     (connected to USB-serial bridge on Freedom board)
  - UART0  in KL46Z256     (connected to USB-serial bridge on Freedom board)
  - UART5  in LM4F232
  - UART0  in MK20DX256 (RX1/TX1 on Teensy 3.1.  Physical pins #2/#3 (these are also Digital IO 0/1 lines)
    	      		Digital IO pins 18/19 are setup for CTS/RTS respectively

;------------------------------------------------------------------------------
Hardware and configuration for LM4F120 and TM4C123:
;------------------------------------------------------------------------------
  Connect your cable to the Debug-USB-Port,
  set "PWR SELECT" switch to DEBUG and
  close VDD jumper.

  Flashing is possible with lm4flash:
  https://github.com/utzig/lm4tools

  On startup, this runs with internal PIOSC at 16 MHz,
  which is specified +-3% over whole temperature range.

;------------------------------------------------------------------------------
Hardware and configuration for TM4C1294:
;------------------------------------------------------------------------------
  Connect your cable to the Debug-USB-Port,
  set "POWER SELECT" jumpers (JP1) to "ICDI",
  close both "MCU 3V3" (JP2) and "+3v3" (JP3) jumpers and
  set communication jumper blocks (JP4 and JP5) both to UART mode.

  Flashing is possible with lm4flash:
  https://github.com/utzig/lm4tools

  On startup, this runs with internal PIOSC at 16 MHz,
  which is specified +-3% over whole temperature range.

;------------------------------------------------------------------------------
Hardware and configuration for MSP432P401R:
;------------------------------------------------------------------------------
  Connect your cable to the USB-Port,
  set "JTAG switch" to XDS position,
  close 5V, 3V3, RXD, TXD jumpers.

  Flashing is possible with DSLite, which is part of Energia 15:
  DSLite -c MSP432P401R.ccxml -f mecrisp-stellaris-msp432p401r.bin -l 0

  On startup, this runs with DCO on 12 MHz.

;------------------------------------------------------------------------------
Hardware and configuration for LPC1114FN28 on breadboard:
;------------------------------------------------------------------------------
  Connect 3.3 V power across
    + Vdd (Pin 21) and Vdda (Pin 7)
    - Vss (Pin 22) and Vssa (Pin 8)
  Connect TTL serial to
    TXD on P1.7 (Pin 16) and
    RXD on P1.6 (Pin 15)
  Connect two push buttons between
    /Reset (Pin 23) and GND
    Bootloader enable on P0.1 (Pin 24) and GND

  The chip enters serial bootloader in ROM
  if Reset button is released while
  the bootloader button is hold down.

  Flashing is possible with LPC21ISP:
  http://sourceforge.net/projects/lpc21isp/

  lpc21isp -wipe mecrisp-stellaris-lpc1114fn28.hex /dev/ttyUSB0 9600 12000

  On startup, this runs with internal RC oscillator at 12 MHz
  which is specified +-1% over whole temperature range.

;------------------------------------------------------------------------------
Hardware and configuration for STM32L053C8:
;------------------------------------------------------------------------------
  Connect USB cable to ST-Link USB port.
  Terminal is included into the debug section and can be used
  if you close solder bridges SB2 and SB3.

  Flashing is possible with st-flash:
  https://github.com/texane/stlink

  Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
  the low address range to generate short opcodes for calling core words, but
  for flashing the binary, you have to use the "true address" $08000000.
  st-flash erase
  st-flash write mecrisp-stellaris-stm32l053c8.bin 0x08000000

  On startup, this runs with internal 16 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32L152:
;------------------------------------------------------------------------------
  Connect USB cable to ST-Link USB port.
  Terminal is included into the debug section on Nucleo boards.

  Flashing is possible with st-flash:
  https://github.com/texane/stlink

  Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
  the low address range to generate short opcodes for calling core words, but
  for flashing the binary, you have to use the "true address" $08000000.
  st-flash erase
  st-flash write mecrisp-stellaris-stm32l152.bin 0x08000000

  On startup, this runs with internal 16 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32L476:
;------------------------------------------------------------------------------
  Connect USB cable to ST-Link USB port.
  Terminal is included into the debug section on Discovery boards.

  Flashing is possible with st-flash:
  https://github.com/texane/stlink
  on Windows using STLINK Tools from ST website:
  http://www.st.com/web/en/catalog/tools/PF258168#

  Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
  the low address range to generate short opcodes for calling core words, but
  for flashing the binary, you have to use the "true address" $08000000.
  st-flash erase
  st-flash write mecrisp-stellaris-stm32l476.bin 0x08000000

  On startup, this runs with internal 48 MHz MSI clock. Currently flash ECC is
  supported. (JJ:O)

;------------------------------------------------------------------------------
Hardware and configuration for STM32F401 and STM32F411:
;------------------------------------------------------------------------------
  Connect USB cable to ST-Link USB port.
  Terminal is included into the debug section on Nucleo boards.

  Flashing is possible with st-flash:
  https://github.com/texane/stlink

  Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
  the low address range to generate short opcodes for calling core words, but
  for flashing the binary, you have to use the "true address" $08000000.
  st-flash erase
  st-flash write mecrisp-stellaris-stm32f401.bin 0x08000000
  st-flash write mecrisp-stellaris-stm32f411.bin 0x08000000

  On startup, this runs with internal 16 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F407:
;------------------------------------------------------------------------------
  Connect USB cable to ST-Link USB port,
  connect your favourite serial link to PA2 (TX) and PA3 (RX),
  keep logic voltage levels in mind !

  Flashing is possible with st-flash:
  https://github.com/texane/stlink

  Flash memory is mirrored in hardware starting from address 0. Mecrisp uses
  the low address range to generate short opcodes for calling core words, but
  for flashing the binary, you have to use the "true address" $08000000.
  st-flash erase
  st-flash write mecrisp-stellaris-stm32f407.bin 0x08000000

  On startup, this runs with external 8 MHz crystal HSE clock,
  as internal oscillator is specified -8% + 4.5% over whole temp range.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F429:
;------------------------------------------------------------------------------
  Similiar to STM32F407.

  Connect USB cable to ST-Link USB port,
  connect your favourite serial link to PA9 (TX) and PA10 (RX),
  keep logic voltage levels in mind !

  st-flash erase
  st-flash write mecrisp-stellaris-stm32f429.bin 0x08000000

  On startup, this runs with external 8 MHz crystal HSE clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F030F4:
;------------------------------------------------------------------------------

  Connect everything necessary to power up and flash the chip.
  Connect your favourite serial link to PA9 (TX) and PA10 (RX),
  keep logic voltage levels in mind !

  st-flash erase
  st-flash write mecrisp-stellaris-stm32f030f4.bin 0x08000000

  On startup, this runs with internal 8 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F051:
;------------------------------------------------------------------------------
  Similiar to STM32F407.

  Connect USB cable to ST-Link USB port,
  connect your favourite serial link to PA9 (TX) and PA10 (RX),
  keep logic voltage levels in mind !

  st-flash erase
  st-flash write mecrisp-stellaris-stm32f051.bin 0x08000000

  On startup, this runs with internal 8 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F100:
;------------------------------------------------------------------------------
  Similiar to STM32F407.

  Connect USB cable to ST-Link USB port,
  connect your favourite serial link to PA9 (TX) and PA10 (RX),
  keep logic voltage levels in mind !

  st-flash erase
  st-flash write mecrisp-stellaris-stm32f100.bin 0x08000000

  On startup, this runs with internal 8 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for STM32F303:
;------------------------------------------------------------------------------
  Similiar to STM32F407.

  Connect USB cable to ST-Link USB port,
  connect your favourite serial link to PA9 (TX) and PA10 (RX),
  keep logic voltage levels in mind !

  st-flash erase
  st-flash write mecrisp-stellaris-stm32f303.bin 0x08000000

  On startup, this runs with internal 8 MHz HSI clock.

;------------------------------------------------------------------------------
Hardware and configuration for KL25Z128, KL46Z256, MK64FN1M0:
;------------------------------------------------------------------------------
  Connect USB cable to SDA-USB-PORT

  Flashing is via mass storage interface -
    the board will appear as Flash Disk, just copy .bin file in.
    Maybe you have to do an OpenSDA firmware update before.

  On startup, this runs with internal FLL at 20.97 MHz.

  If you wish to try Mecrisp-Stellaris without target hardware,
  there is a Cortex M0 instruction set emulator prepared for use with
  Freescale Freedom binary images. Go into kl25z128/thumbulator
  directory, type "make", copy the binary and then type
  "thumbulator mecrisp-stellaris-kl25z128.bin" to run.

;------------------------------------------------------------------------------
Hardware and configuration for XMC1100:
;------------------------------------------------------------------------------
  Connect USB cable for flashing and terminal.

  Flashing is possible with JLinkExe from Segger, which is available for Linux:
  https://www.segger.com/jlink-software.html
  "Software and documentation pack", 32 Bit TGZ archive is fine.

  JLink_Linux_V510c_i386# ./JLinkExe -device XMC1100-0064 -if SWD -speed 4000
    erase
    loadfile mecrisp-stellaris-xmc1100.hex
    r
    g

  OpenOCD 0.9 has support for the XMC2GO, but it failed with the firmware version
  of my board. The command line would be something like this:

  openocd -f board/xmc-2go.cfg
  openocd -f board/xmc-2go.cfg -c "program mecrisp-stellaris-xmc1100.hex verify reset exit"

  If you have issues with broken characters in the terminal,
  try changing the UART_FDR_STEP value in terminal.s a bit.

  To circumvent a bug in the XMC2GO serial bridge, the baudrate is set a bit
  off the nominal value. If you connect your own terminal, make sure to change
  it to the correct value.
    See mecrisp-stellaris-source/xmc1100/terminal.s for hints.

  On startup, this runs with internal MCLK = PCKL = 8 MHz clock.

;------------------------------------------------------------------------------
Hardware and configuration for EFM32GG990 and EFM32HG322:
;------------------------------------------------------------------------------
  Connect USB cable to DBG connector for flashing and terminal.

  To get the mass storage flashing interface and USB-serial bridge,
  a firmware update of the on board debugger might be necessary.
  See instructions on MBED:
  https://developer.mbed.org/teams/SiliconLabs/wiki/Silicon-Labs-Firmware

  Flashing is done by copying the binary into the USB drive.

  Unfortunately, flashing this way doesn't not perform a proper mass erase.
  If you cannot get it up and running this way, you need use a proper debugger
  and erase the whole flash properly.

  On startup, this runs with internal HFCLK = HFRCO = 14 MHz clock.

;------------------------------------------------------------------------------
Hardware and configuration for MK20DX256VLH7 on a Teensy 3.1 board:
;------------------------------------------------------------------------------
  ( Contributed by Mark Schweizer )

  Connect USB cable to USB port
  Open Teensy Loader Application (https://www.pjrc.com/teensy/loader.html) on your PC
  Select the "mecrisp-stellaris-mk20dx256.hex" file in the mk20dx256 directory
  Select the "Auto" button (this automatically loads the coad and resets the Teensy when the programming button is pushed)
  Press the button on the Teensy 3.1 board to initite the bootloader
  Connect a serial cable to TX1/RX1 (physical pins #2/#3 (these are also Digital IO 0/1 lines)
  Optionally connect CTS/RTS to physical pins #25/26 (these are also Digital IO 18/18 lines)

     		  R C
     		  T T
       		  S S

    o o o o o o o o o o o o o o
   |--------------------------o
   |     	     	      o
USB|       Teensy 3.1 	      o
   |     		      o
   |--------------------------o
    o o o o o o o o o o o o o o

    G R T
    N X X
    D

  On startup, this runs with internal FLL at 20.97 MHz.  See MCG.txt for how to switch to 96MHz

;------------------------------------------------------------------------------
Hardware and configuration for nRF51822:
;------------------------------------------------------------------------------
  ( Contributed by John Huberts )

  I have been using the nRFgo Motherboard fitted with a nRF51822 module
  to do the development and testing. Programming is done using nRFStudio
  and the Segger J-LINK LITE that comes with the dev kit.

  I was also able to debug using GDB in the nRF51 Eclipse IDE

  The motherboard has a DB9 for serial port connection but jumpers need to
  be placed between P15 (RXD, TXD) and P9 (P2.0, P2.1). If you don't have a
  serial port on your PC then you will need a USB-serial cable.

  The UART can be configured to use other pins on the SOC by changing these
  lines in in terminal.s:

  .equ RX_PIN_NUMBER, 16
  .equ TX_PIN_NUMBER, 17

;------------------------------------------------------------------------------
Hardware and configuration for Microbit:
;------------------------------------------------------------------------------

  Flashing can be done by just copying mecrisp-stellaris-microbit.hex
  into the Microbit which comes with a mass storage interface.

  Communication is done over P0.24 TX and P0.25 RX, connected
  to USB-serial-bridge on debugger section.

;------------------------------------------------------------------------------

Mecrisp-Stellaris itself is sending LF for line ending,
but recognizes both LF and CR. Invoke Picocom with something like
picocom -b 115200 /dev/ttyACM0 --imap lfcrlf,crcrlf --omap delbs,crlf

For changing line ending to CR-LF or whatever else you like,
look at the beginning of mecrisp-stellaris-....s.

Assembling is done with the GCC-Arm-Embedded toolchain:
https://launchpad.net/gcc-arm-embedded/

;------------------------------------------------------------------------------

* Fetch-Modify-Store operations like +! or bic! are not atomic.

* You can contribute your favourite hardware handling routines
    to be included in upcoming releases !

* Chip specific sources have added English comments and hints included
    for simplify porting to other ARM Cortex-M chips.

* For design ideas, have a look into Mecrisp for MSP430, too !

;------------------------------------------------------------------------------
; Turnkey applications
;------------------------------------------------------------------------------

If you define a word with name "init" - its latest definition is called every
startup ! You you can redefine init if you like to add e.g. additional hardware
setup; don't forget to give your old definition of init a call if you have one.

;------------------------------------------------------------------------------
; Porting
;------------------------------------------------------------------------------

Mecrisp-Stellaris can assemble without change for M0, M3 and M4 cores.

M0 cores lack conditional execution "ite eq...", which has to be circumvented
by conditional branches. stmdb psp!, {tos} is missing, which I use to push to
data stack and they have no division in hardware.

There is an assembler switch "m0core" to assemble the core with replacement
code for ARM Cortex-M0 chips. Depending on your flash capabilities, there are
two useful switches:

  "charkommaavailable" which is self-explaining and
  "emulated16bitflashwrites" if your particular Flash controller
                             cannot write data in separate 16-Bit chunks.

Core needs about 14 kb flash at the moment, but reserves 16 kb for upcoming
additions, and needs 1.5 kb RAM for stacks and buffers plus variables for
interrupt handlers plus RAM dictionary space. Bare minimum for ARM to get it
running will be around 16kb/2kb, but to have fun with it and leave space for
real applications, go with at least of 32 kb flash and 4 kb RAM.

Look at the flash specification for your particular chip.

The compiler only depends on 2-aligned 16-Bit flash writes
one time per location, you can remove c, and halign without issues
from the compiler, but 8-Bit flash writes are nice to have
for compatibility with standard code.

For special cases having only 4-aligned 32-bit one-time writes to Flash,
there is a hflash! emulation layer.

Flash erasing is only available for the user, it doesn't need erase cycles
while compiling.

Keep these criteria in mind, pick your favourite chip and add it as your
contribution. It won't be too difficult, start with an UART echo written
in assembly without libraries, and I will be there for your help.

You have to change memory map, hardware initialisation and interrupt vectors,
write key?, key, emit?, emit for a first reaction and flash write access
for final success. There is a common mimimum set of handlers across
ARM Cortex CPUs, which will help you to get it running for the first time.

Unfortunately, there is a lot of bit twiddling necessary for peripherial
modules, as they differ a lot across manufacturers. ARMs seem to only share
core components like CPU, interrupt controler and a very basic systick timer.

I don't have the time to support a lot of different chips with examples.

TI ADCs have a sequencer FIFO buffer, ST ADCs need a DMA channel configured.
TI Flash controller offers 32 bit aligned writes only, but as many as you
wish per location until all bits are zero;
ST-M3 have 16 bit aligned Flash write only,
ST-M4 have 8 bit, 16 bit and 32 bit Flash writes available,
but only once per location.

I would like to focus on core development, support porting to other chips and
families with adaptions in core, but leave writing initialisation code,
testing and writing Forth examples to "family maintainers" which are deep
into their chip of choice.

;------------------------------------------------------------------------------
; Register allocator
;------------------------------------------------------------------------------

It should look and feel like the classic Mecrisp-Stellaris,
but with a very important difference:

It contains an analytical compiler which keeps track
of the top five stack elements and maps them to registers
whenever possible.

To dive in, you should load the disassembler and see
definitions you have just compiled.

Two examples, on M0:

: >gray ( u -- x ) dup 1 rshift xor ;  ok.
see >gray
00006B38: 0873  lsrs r3 r6 #1
00006B3A: 405E  eors r6 r3
00006B3C: 4770  bx lr
 ok.


: bitexp ( u -- u )  ok.
  ok.
  \ Returns an integer value equivalent to  ok.
  \ the exponential. For numbers > 16,  ok.
  \ bitexp(x) approx = 2^(x/8 + 1)  ok.
  ok.
  \ B(E(x)) = x for 16 <= x <= 247.  ok.
  ok.
  dup 247 u>  \ Overflow ?  ok.
  if drop $F0000000  ok.
  else  ok.
  ok.
    dup 16 u<= if 1 rshift  ok.
               else  ok.
                 dup ( u u )  ok.
                 7 and 8 or ( u b )  ok.
                 swap ( b u )  ok.
                 3 rshift 2 - lshift  ok.
               then  ok.
  ok.
  then  ok.
  ok.
  1-foldable ;  ok.
  ok.
see bitexp
00006BA2: 2EF7  cmp r6 #F7
00006BA4: B500  push { lr }
00006BA6: D902  bls 00006BAE
00006BA8: 26F0  movs r6 #F0
00006BAA: 0636  lsls r6 r6 #18
00006BAC: E00C  b 00006BC8
00006BAE: 2E10  cmp r6 #10
00006BB0: D801  bhi 00006BB6
00006BB2: 0876  lsrs r6 r6 #1
00006BB4: E008  b 00006BC8
00006BB6: 0033  lsls r3 r6 #0
00006BB8: 2007  movs r0 #7
00006BBA: 4003  ands r3 r0
00006BBC: 2008  movs r0 #8
00006BBE: 4303  orrs r3 r0
00006BC0: 08F6  lsrs r6 r6 #3
00006BC2: 3E02  subs r6 #2
00006BC4: 40B3  lsls r3 r6
00006BC6: 461E  mov r6 r3
00006BC8: BD00  pop { pc }

Note that it compiles bitexp without any stack movements at all.

;------------------------------------------------------------------------------
; Hacking
;------------------------------------------------------------------------------

If you wish to dive into the assembly sources, here comes a register map:

r0: Free scratch register            ( Saved on interrupt entry by hardware )
r1: Free scratch register            ( Saved on interrupt entry by hardware )
r2: Free scratch register            ( Saved on interrupt entry by hardware )
r3: Free scratch register            ( Saved on interrupt entry by hardware )

r4: Inner loop count                 ( Needs Push and Pop when used otherwise )
r5: Inner loop limit                 ( Needs Push and Pop when used otherwise )

r6=TOS: Top-Of-Stack                 ( Stack design is interrupt safe )
r7=PSP: Parameter Stack Pointer      ( Stack design is interrupt safe )

r8:  Unused
r9:  Unused
r10: Unused
r11: Unused
r12: Unused                          ( Saved on interrupt entry by hardware )

r13=SP: Return Stack Pointer
r14=LR: Link Register
r15=PC: Program Counter, always odd

;------------------------------------------------------------------------------
Here comes a word list,
  with short descriptions of all currently included words:
View it with fixed-width font !
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Terminal-IO  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        emit?           ( -- Flag ) Ready to send a character ?
        key?            ( -- Flag ) Checks if a key is waiting
        key             ( -- Char ) Waits for and fetches the pressed key
        emit            ( Char -- ) Emits a character.

        hook-emit?      ( -- a-addr ) Hooks for redirecting
        hook-key?       ( -- a-addr )   terminal IO
        hook-key        ( -- a-addr )     on the fly
        hook-emit       ( -- a-addr )

        serial-emit?    ( -- Flag )  Serial interface
        serial-key?     ( -- Flag )    terminal routines
        serial-key      ( -- Char )      as default communications
        serial-emit     ( Char -- )

        hook-pause      ( -- a-addr ) Hook for a multitasker
        pause           ( -- )        Task switch, none for default

;------------------------------------------------------------------------------
; Stack Jugglers  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

Single-Jugglers:

        depth           ( -- +n ) Gives number of single-cell stack items.
        nip             ( x1 x2 -- x2 )
        drop            ( x -- )
        rot             ( x1 x2 x3 -- x2 x3 x1 )
        -rot            ( x1 x2 x3 -- x3 x1 x2 )
        swap            ( x1 x2 -- x2 x1 )
        tuck            ( x1 x2 -- x2 x1 x2 )
        over            ( x1 x2 -- x1 x2 x1 )
        ?dup            ( x -- 0 | x x )
        dup             ( x -- x x )
        pick            ( ... xi+1 xi ... x1 x0 i -- ... x1 x0 xi )
                                  Picks one element from deep below

        >r              ( x -- ) (R: -- x )
        r>              ( -- x ) (R: x -- )
        r@              ( -- x ) (R: x -- x )
        rdrop           (  --  ) (R: x -- )
        rdepth          ( -- +n ) Gives number of return stack items.
        rpick           ( i -- xi ) R: ( ... xi ... x0 -- ... xi ... x0 )

Double-Jugglers:        They perform the same for double numbers.

        2nip            ( x1 x2 x3 x4 -- x3 x4 )
        2drop           ( x1 x2 -- )
        2rot            ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 )
        2-rot           ( x1 x2 x3 x4 x5 x6 -- x5 x6 x1 x2 x3 x4 )
        2swap           ( x1 x2 x3 x4 -- x3 x4 x1 x2 )
        2tuck           ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 )
        2over           ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )
        2dup            ( x1 x2 -- x1 x2 x1 x2 )

        2>r             ( x1 x2 -- ) (R: -- x1 x2 )
        2r>             ( -- x1 x2 ) (R: x1 x2 -- )
        2r@             ( -- x1 x2 ) (R: x1 x2 -- x1 x2 )
        2rdrop          ( -- )       (R: x1 x2 -- )

Stack pointers:

        sp@             ( -- a-addr )  Fetch  data stack pointer
        sp!             ( a-addr -- )  Store  data stack pointer
        rp@             ( -- a-addr )  Fetch return stack pointer
        rp!             ( a-addr -- )  Store return stack pointer

;------------------------------------------------------------------------------
; Logic  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        arshift         ( x1 u -- x2 ) Arithmetric right-shift of u bit-places
        rshift          ( x1 u -- x2 ) Logical right-shift of u bit-places
        lshift          ( x1 u -- x2 ) Logical  left-shift of u bit-places
        shr             ( x1 -- x2 )   Logical right-shift of one bit-place
        shl             ( x1 -- x2 )   Logical  left-shift of one bit-place
        ror             ( x1 -- x2 )   Logical right-rotation of one bit-place
        rol             ( x1 -- x2 )   Logical  left-rotation of one bit-place
        bic             ( x1 x2 -- x3 ) Bit clear, identical to "not and"
        not             ( x1 -- x2 )   Invert all bits
        xor             ( x1 x2 -- x3 ) Bitwise Exclusive-OR
        or              ( x1 x2 -- x3 ) Bitwise OR
        and             ( x1 x2 -- x3 ) Bitwise AND
        false           ( --  0 ) False-Flag
        true            ( -- -1 ) True-Flag
        clz             ( x1 -- u ) Count leading zeros

;------------------------------------------------------------------------------
; Calculus for single numbers  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        u/mod           ( u1 u2 -- u3 u4 ) 32/32 = 32 rem 32 Division
                                           u1 / u2 = u4 remainder u3
        /mod            ( n1 n2 -- n3 n4 ) n1 / n2 = n4 rem n3
        mod             ( n1 n2 -- n3 ) n1 / n2 = remainder n3
        /               ( n1 n2 -- n3 ) n1 / n2 = n3
        *               ( u1|n1 u2|n2 -- u3|n3 ) 32*32 = 32 Multiplication
        min             ( n1 n2 -- n1|n2 ) Keeps smaller of top two items
        max             ( n1 n2 -- n1|n2 ) Keeps greater of top two items
        umin            ( u1 u2 -- u1|u2 ) Keeps unsigned smaller
        umax            ( u1 u2 -- u1|u2 ) Keeps unsigned greater
        2-              ( u1|n1 -- u2|n2 ) Subtracts two, optimized
        1-              ( u1|n1 -- u2|n2 ) Subtracts one, optimized
        2+              ( u1|n1 -- u2|n2 ) Adds two, optimized
        1+              ( u1|n1 -- u2|n2 ) Adds one, optimized
        even            ( u1|n1 -- u2|n2 ) Makes even. Adds one if uneven.
        2*              ( n1 -- n2 ) Arithmetric  left-shift
        2/              ( n1 -- n2 ) Arithmetric right-shift
        abs             ( n -- u ) Absolute value
        negate          ( n1 -- n2 ) Negate
        -               ( u1|n1 u2|n2 -- u3|n3 ) Subtraction
        +               ( u1|n1 u2|n2 -- u3|n3 ) Addition

;------------------------------------------------------------------------------
; Calculus involving double numbers  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        um*             ( u1 u2 -- ud )        32*32 = 64 Multiplication
        ud*             ( ud1 ud2 -- ud3 )     64*64 = 64 Multiplication
        udm*            ( ud1 ud2 -- ud3-Low ud4-High ) 64*64=128 Multiplication

        um/mod          ( ud u1 -- u2 u3 )     ud / u1 = u3 remainder u2
        ud/mod          ( ud1 ud2 -- ud3 ud4 ) 64/64 = 64 rem 64 Division
                                               ud1 / ud2 = ud4 remainder ud3

        m*              ( n1 n2 -- d )         n1 * n2 = d
        m/mod           ( d  n1 -- n2 n3 )     d  / n1 = n3 remainder r2
        d/mod           ( d1 d2 -- d3 d4 )     d1 / d2 = d4 remainder d3
        d/              ( d1 d2 -- d3 )        d1 / d2 = d3
        */              ( n1 n2 n3 -- n4 )     n1 * n2 / n3 = n4
        u*/             ( u1 u2 u3 -- u4 )     u1 * u2 / u3 = u4
        */mod           ( n1 n2 n3 -- n4 n5 )  n1 * n2 / n3 = n5 remainder n4
        u*/mod          ( u1 u2 u3 -- u4 u5 )  u1 * u2 / u3 = u5 remainder u4

        d2*             ( d1 -- d2 ) Arithmetric  left-shift
        d2/             ( d1 -- d2 ) Arithmetric right-shift
        dshl            ( ud1 -- ud2 ) Logical left-shift, same as d2*
        dshr            ( ud1 -- ud2 ) Logical right-shift

        dabs            ( d -- ud ) Absolute value
        dnegate         ( d1 -- d2 ) Negate
        d-              ( ud1|d1 ud2|d2 -- ud3|d3 ) Subtraction
        d+              ( ud1|d1 ud2|d2 -- ud3|d3 ) Addition
        s>d             ( n -- d ) Makes a signed single number double length

;------------------------------------------------------------------------------
; Comparisions  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

Single-Comparisions:
        u<=             ( u1 u2 -- flag )  Unsigned comparisions
        u>=             ( u1 u2 -- flag )
        u>              ( u1 u2 -- flag )
        u<              ( u1 u2 -- flag )
        <=              ( n1 n2 -- flag )    Signed comparisions
        >=              ( n1 n2 -- flag )
        >               ( n1 n2 -- flag )
        <               ( n1 n2 -- flag )
        0<              ( n - flag )         Negative ?
        0<>             ( x -- flag )
        0=              ( x -- flag )
        <>              ( x1 x2 -- flag )
        =               ( x1 x2 -- flag )

Double-Comparisions:            They perform the same for double numbers.
        du>             ( ud1 ud2 -- flag )
        du<             ( ud1 ud2 -- flag )
        d>              ( d1 d2 -- flag )
        d<              ( d1 d2 -- flag )
        d0<             ( d -- flag )
        d0=             ( d -- flag )
        d<>             ( d1 d2 -- flag )
        d=              ( d1 d2 -- flag )

;------------------------------------------------------------------------------
; Tools (not only) for s31.32 fixed point numbers  (speciality!)
;------------------------------------------------------------------------------

Fixpoint numbers are stored ( n-comma n-whole ) and can be handled
like signed double numbers.

        f/              ( df1 df2 -- df3 ) Division of two fixpoint numbers
        f*              ( df1 df2 -- df3 ) Multiplication

        hold<           ( char -- )
                        Adds character to pictured number output buffer
                        from behind.
        f#S             ( n-comma1 -- n-comma2 )
                        Adds 32 comma-digits to number output
        f#              ( n-comma1 -- n-comma2 )
                        Adds one comma-digit to number output
        f.              ( df -- )
                        Prints a fixpoint number with 32 fractional digits
        f.n             ( df n -- )
                        Prints a fixpoint number with n fractional digits

        number          ( c-addr length -- 0 )
                                        -- n 1 )
                                        -- n-low n-high 2 )
                        Tries to convert a string to a number.

;------------------------------------------------------------------------------
; Number base  (exactly ANS)
;------------------------------------------------------------------------------

        binary          ( -- ) Sets base to 2
        decimal         ( -- ) Sets base to 10
        hex             ( -- ) Sets base to 16
        base            ( -- a-addr ) Base variable address

;------------------------------------------------------------------------------
; Memory access  (subtle differences to ANS, special cpu-specific extensions)
;------------------------------------------------------------------------------

        move            ( c-addr1 c-addr2 u -- ) Moves u Bytes in Memory
        fill            ( c-addr u c ) Fill u Bytes of Memory with value c

        cbit@           ( mask c-addr -- flag ) Test BIts in byte-location
        hbit@           ( mask a-addr -- flag ) Test BIts in halfword-location
        bit@            ( mask a-addr -- flag ) Test BIts in word-location

        cxor!           ( mask c-addr -- ) Toggle bits in byte-location
        hxor!           ( mask a-addr -- ) Toggle bits in halfword-location
        xor!            ( mask a-addr -- ) Toggle bits in word-location

        cbic!           ( mask c-addr -- ) Clear BIts in byte-location
        hbic!           ( mask a-addr -- ) Clear BIts in halfword-location
        bic!            ( mask a-addr -- ) Clear BIts in word-location

        cbis!           ( mask c-addr -- ) Set BIts in byte-location
        hbis!           ( mask a-addr -- ) Set BIts in halfword-location
        bis!            ( mask a-addr -- ) Set BIts in word-location

        2constant name  ( ud|d -- ) Makes a double constant.
        constant  name  ( u|n -- )  Makes a single constant.
        2variable name  ( ud|d -- ) Makes an initialized double variable
        variable  name  ( n|n -- )  Makes an initialized single variable
        nvariable name  ( n1*u|n n1 -- ) Makes an initialized variable with
                                         specified size of n1 words
                                         Maximum is 15 words

        buffer: name    ( u -- ) Creates a buffer in RAM with u bytes length

        2@              ( a-addr -- ud|d ) Fetches double number from memory
        2!              ( ud|d a-addr -- ) Stores double number in memory

        @               ( a-addr -- u|n ) Fetches single number from memory
        !               ( u|n a-addr -- ) Stores single number in memory
        +!              ( u|n a-addr -- ) Add to memory location

        h@              ( c-addr -- char ) Fetches halfword from memory
        h!              ( char c-addr ) Stores halfword in memory
        h+!             ( u|n a-addr -- ) Add to halfword memory location

        c@              ( c-addr -- char ) Fetches byte from memory
        c!              ( char c-addr ) Stores byte in memory
        c+!             ( u|n a-addr -- ) Add to byte memory location

;------------------------------------------------------------------------------
; Strings and beautiful output (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

String routines:

        type            ( c-addr length -- )
                        Prints a string.

        s" Hello"       Compiles a string and
                        ( -- c-addr length )
                        gives back its address and length when executed.

        ." Hello"       Compiles a string and
                        ( -- )
                        prints it when executed.

        ( Comment )     Ignore Comment
        \ Comment       Comment to end of line

        cr              ( -- ) Emits line feed
        bl              ( -- 32 ) ASCII code for Space
        space           ( -- ) Emits space
        spaces          ( n -- ) Emits n spaces if n is positive

        compare         ( caddr-1 len-1 c-addr-2 len-2 -- flag )
                        Compares two strings

        accept          ( c-addr maxlength -- length ) Read input into a string.

Counted string routines:

        ctype           ( cstr-addr -- )
                        Prints a counted string.

        c" Hello"       Compiles a counted string and
                        ( -- cstr-addr )
                        gives back its address when executed.

        cexpect         ( cstr-addr maxlength -- ) Read input into a counted string.

        count           ( cstr-addr -- c-addr length )
                        Convert counted string into addr-length string

        skipstring      ( cstr-addr -- a-addr )
                        Increases the pointer to the aligned end of the string.

Pictured numerical output:

        .digit          ( u -- char ) Converts a digit to a char
        digit           ( char -- u true | false ) Converts a char to a digit

        [char] *        Compiles code of following char
                        ( -- char ) when executed

        char *          ( -- char ) gives code of following char
        hold            ( char -- ) Adds character to pictured number
                                    output buffer from the front.

        sign            ( n -- ) Add a minus sign to pictured number
                                 output buffer, if n is negative

        #S              ( ud1|d1 -- 0 0 ) Add all remaining digits
                        from the double length number to output buffer
        #               ( ud1|d1 -- ud2|d2 ) Add one digit from the
                        double length number to output buffer
        #>              ( ud|d -- c-addr len )
                        Drops double-length number and finishes
                        pictured numeric output ready for type
        <#              ( -- ) Prepare pictured number output buffer
        u.              ( u -- ) Print unsigned single number
        .               ( n -- ) Print single number
        ud.             ( ud -- ) Print unsigned double number
        d.              ( d -- ) Print double number

Deep insights:

        words           ( -- ) Prints list of defined words.
        .s              ( many -- many ) Prints stack contents, signed
        u.s             ( many -- many ) Prints stack contents, unsigned
        h.s             ( many -- many ) Prints stack contents, unsigned, hex
        hex.            ( u -- ) Prints 32 bit unsigned in hex base,
                                 needs emit only.
                                 This is independent of number subsystem.

;------------------------------------------------------------------------------
; User input and its interpretation (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        query           ( -- ) Fetches user input to input buffer
        tib             ( -- cstr-addr ) Input buffer

        current-source  ( -- addr ) Double-Variable which contains source
        setsource       ( c-addr len -- ) Change source
        source          ( -- c-addr len ) Current source
        >in             ( -- addr ) Variable with current offset into source

        token           ( -- c-addr len ) Cuts one token out of input buffer
        parse           ( char -- c-addr len )
                        Cuts anything delimited by char out of input buffer

        evaluate        ( any addr len -- any ) Interpret given string
        interpret       ( any -- any ) Execute, compile, fold, optimize...
        quit            ( many -- ) (R: many -- ) Resets Stacks
        hook-quit       ( -- a-addr ) Hook for changing the inner quit loop

;------------------------------------------------------------------------------
; Dictionary expansion  (exactly ANS, some logical extensions)
;------------------------------------------------------------------------------

        align           ( -- ) Aligns dictionary pointer
        aligned         ( c-addr -- a-addr ) Advances to next aligned address
        cell+           ( x -- x+4 ) Add size of one cell
        cells           ( n -- 4*n ) Calculate size of n cells

        allot           ( n -- ) Tries to advance Dictionary Pointer by n bytes
                                 Aborts, if not enough space available
        here            ( -- a-addr|c-addr )
                        Gives current position in Dictionary

        ,               ( u|n -- ) Appends a single number to dictionary
        ><,             ( u|n -- ) Reverses high and low-halfword, then
                                     appends it to dictionary
        h,              ( u|n -- ) Appends a halfword to dictionary

        compiletoram?   ( -- ? ) Currently compiling into ram ?
        compiletoram    ( -- ) Makes ram   the target for compiling
        compiletoflash  ( -- ) Makes flash the target for compiling

        forgetram       ( -- ) Forget definitions in ram without a reset

;------------------------------------------------------------------------------
; Dictionary expansion  (speciality!)
;------------------------------------------------------------------------------

        string,         ( c-addr len -- ) Inserts a string of maximum 255 characters without runtime
        literal,        ( u|n -- ) Compiles a literal with runtime
        inline,         ( a-addr -- ) Inlines the choosen subroutine
        call,           ( a-addr -- ) Compiles a call to a subroutine
        jump,           ( Hole-for-Opcode Destination )
                        Writes an unconditional Jump
                        to a-addr-Destination with the given Bitmask as
                        Opcode into the halfword sized a-addr-Hole
        cjump,          ( Hole-for-Opcode Destination Bitmask )
                        Writes a conditional Jump
                        to a-addr-Destination with the given Bitmask as
                        Opcode into the halfword sized a-addr-Hole
        ret,            ( -- ) Compiles a ret opcode

        flashvar-here   ( -- a-addr ) Gives current RAM management pointer
        dictionarystart ( -- a-addr ) Current entry point for dictionary search
        dictionarynext  ( a-addr -- a-addr flag )
                        Scans dictionary chain and returns true if end is reached.

    Available depending on chip capabilities:

        c,              ( char -- ) Appends a byte to dictionary
        halign          ( -- ) Makes Dictionary Pointer even, if uneven.

        movwmovt,       ( x Register -- ) Generate a movw/movt-Sequence to
                                          get x into any given Register. M3/M4 only
       registerliteral, ( x Register -- ) Generate shortest possible sequence
                                          to get x into given low Register.
                                          On M0: A movs-lsls-adds... sequence
                                          M3/M4: movs / movs-mvns / movw / movw-movt

       12bitencoding    ( x -- x false | bitmask true )
                                          Can x be encoded as 12-bit immediate ?

;------------------------------------------------------------------------------
; Flags and inventory  (speciality!)
;------------------------------------------------------------------------------

        smudge          ( -- ) Makes current definition visible, burns
                               collected flags to flash and
                               takes care of proper ending
        inline          ( -- ) Makes current definition inlineable.
                               For flash, place it inside your definition !
        immediate       ( -- ) Makes current definition immediate.
                               For flash, place it inside your definition !
        compileonly     ( -- ) Makes current definition compileonly.
                               For flash, place it inside your definition !
        setflags        ( char -- ) Sets Flags with a mask. This isn't immediate,
                               but for flash, place it inside your definition !
        (create) name   ( -- ) Creates and links a new invisible dictionary
                               header that does nothing.
                               Use FIG-style <builds .. does> !
        find            ( c-addr len -- a-addr flags )
                               Searches for a String in Dictionary.
                               Gives back flags, which are different to ANS !

        0-foldable      ( -- ) Current word becomes foldable with zero constants
        1-foldable      ( -- ) Current word becomes foldable with one constants
        2-foldable      ( -- ) Current word becomes foldable with two constants
        3-foldable      ( -- ) Current word becomes foldable with 3   constants
            ...
        7-foldable      ( -- ) Current word becomes foldable with 7   constants

;------------------------------------------------------------------------------
; Compiler essentials  (subtle differences to ANS)
;------------------------------------------------------------------------------

        execute         ( a-addr -- ) Calls subroutine
        recurse         ( -- ) Lets the current definition call itself
        ' name          ( -- a-addr ) Tries to find name in dictionary
                                      gives back executable address
        ['] name        ( -- a-addr)  Tick that compiles the executable address
                                      of found word as literal
        postpone name   ( -- ) Helps compiling immediate words.
        does>           ( -- ) executes: ( -- a-addr )
                               Gives address to where you have stored data.
        <builds         ( -- ) Makes Dictionary header and reserves space
                               for special call.
        create name     ( -- ) Create a definition with default action which
                               cannot be changed later. Use <builds does> instead.
                               Equivalent to : create <builds does> ;
        state           ( -- a-addr ) Address of state variable
        ]               ( -- ) Switch to compile state
        [               ( -- ) Switch to execute state
        ;               ( -- ) Finishes new definition
        : name          ( -- ) Opens new definition

;------------------------------------------------------------------------------
; Control structures (exactly ANS)
;------------------------------------------------------------------------------
Internally, they have complicated compile-time stack effects.

Decisions:

flag if ... then
flag if ... else ... then

        then            ( -- )           This is the common
        else            ( -- )           flag if ... [else ...] then
        if              ( flag -- )      structure.
        ahead           ( -- )

Case:

n case
     m1   of ... endof
     m2   .. ... .....
   flag  ?of ... endof
    all others
  endcase

        case            ( n -- n )       Begins case structure
        of              ( m -- )         Compares m with n, choose this if n=m
        ?of             ( flag -- )      Flag-of, for custom comparisions
        endof           ( -- )           End of one possibility
        endcase         ( n -- )         Ends case structure, discards n

Indefinite Loops:

begin ... again
begin ... flag until
begin ... flag while ... repeat

        repeat          ( -- ) Finish of a middle-flag-checking loop.

        while           ( flag -- ) Check a flag in the middle of a loop

        until           ( flag -- ) begin ... flag until
                                    loops as long flag is true
        again           ( -- )  begin ... again
                                is an endless loop
        begin           ( -- )


Definite Loops:

limit index   do ... [one or more leave(s)] ... loop
             ?do ... [one or more leave(s)] ... loop
              do ... [one or more leave(s)] ... n +loop
             ?do ... [one or more leave(s)] ... n +loop


        k               ( -- u|n ) Gives third  loop index
        j               ( -- u|n ) Gives second loop index
        i               ( -- u|n ) Gives innermost loop index


        unloop          (R: old-limit old-index -- )
                        Drops innermost loop structure,
                        pops back old loop structures to loop registers

        exit            ( -- ) Returns from current definition.
                               Compiles a ret opcode.

        leave           ( -- ) (R: old-limit old-index -- )
                        Leaves current innermost loop promptly

        +loop           ( u|n -- )
                        (R: unchanged | old-limit old-index -- )
                        Adds number to current loop index register
                        and checks whether to continue or not

        loop            ( -- )
                        (R: unchanged | old-limit old-index -- )
                        Increments current loop index register by one
                        and checks whether to continue or not.

        ?do             ( Limit Index -- )
                        (R: unchanged | -- old-limit old-index )
                        Begins a loop if limit and index are not equal

        do              ( Limit Index -- )
                        (R: -- old-limit old-index )
                        Begins a loop

;------------------------------------------------------------------------------
; Common Hardware access
;------------------------------------------------------------------------------

        reset           ( -- ) Reset on hardware level
        dint            ( -- ) Disables Interrupts
        eint            ( -- ) Enables  Interrupts
        eint?           ( -- ) Are Interrupts enabled ?
        nop             ( -- ) No Operation. Hook for unused handlers !

        ipsr            ( -- ipsr ) Interrupt Program Status Register
        unhandled       ( -- ) Message for unhandled interrupts.

        irq-systick     ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-fault       ( -- a-addr ) For all faults
        irq-collection  ( -- a-addr ) Collection of all unhandled interrupts

;------------------------------------------------------------------------------
; Specials for LM4F120:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        cflash!         ( char c-addr -- )  Writes byte to flash
        hflash!         ( u|n a-addr -- )   Writes halfword to flash
        flash!          ( u|n 4-a-addr -- ) Writes single number to flash,
                                              4 aligned !
Interrupts:

        irq-porta       ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-portb
        irq-portc
        irq-portd
        irq-porte
        irq-portf
        irq-timer0a
        irq-timer0b
        irq-timer1a
        irq-timer1b
        irq-timer2a
        irq-timer2b
        irq-adc0seq0
        irq-adc0seq1
        irq-adc0seq2
        irq-adc0seq3
        irq-terminal

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for TM4C1294:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 16k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        cflash!         ( char c-addr -- )  Writes byte to flash
        hflash!         ( u|n a-addr -- )   Writes halfword to flash
        flash!          ( u|n 4-a-addr -- ) Writes single number to flash,
                                              4 aligned !
Interrupts:

        irq-porta       ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-portb
        irq-portc
        irq-portd
        irq-porte
        irq-portf
        irq-portg
        irq-porth
        irq-portj
        irq-portk
        irq-portl
        irq-timer0a
        irq-timer0b
        irq-timer1a
        irq-timer1b
        irq-timer2a
        irq-timer2b
        irq-timer3a
        irq-timer3b
        irq-adc0seq0
        irq-adc0seq1
        irq-adc0seq2
        irq-adc0seq3
        irq-adc1seq0
        irq-adc1seq1
        irq-adc1seq2
        irq-adc1seq3
        irq-ethernet
        irq-terminal

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for MSP432P401R:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        cflash!         ( char c-addr -- )  Writes byte to flash
        hflash!         ( u|n a-addr -- )   Writes halfword to flash
        flash!          ( u|n 4-a-addr -- ) Writes single number to flash,
                                              4 aligned !
Interrupts:

        irq-port1       ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-port2
        irq-port3
        irq-port4
        irq-port5
        irq-port6
        irq-watchdog
        irq-adc
        irq-timera0
        irq-timera1

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for LPC1114FN28, LPC1114FBD48 and LPC1115FBD48:
;------------------------------------------------------------------------------

        initflash       ( -- ) Clear buffers
        hflash!         ( u|n a-addr -- ) Writes halfword to flash (buffered)
        flushflash      ( -- ) Flush flash buffers
                                 needed if you comma in values after create

        flash-khz       ( -- addr ) Variable with current core frequency in kHz
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.
        16flash!        ( x1 x2 x3 x4 addr -- ) Flash aligned 16 Bytes at once

        irq-i2c         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-uart
        irq-adc

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F051:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti0_1
        irq-exti2_3
        irq-exti4_15
        irq-tim1_up
        irq-tim1_cc
        irq-tim2
        irq-tim3

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F030F4:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.
        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti0_1
        irq-exti2_3
        irq-exti4_15
        irq-tim1_up
        irq-tim1_cc
        irq-tim3

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32L053C8:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 128 byte flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        flash!          ( u|n a-addr -- )   Writes word to flash

Interrupts:

        irq-rtc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti0_1
        irq-exti2_3
        irq-exti4_15
        irq-touch
        irq-dma1
        irq-dma2_3
        irq-dma4_7
        irq-adc
        irq-lptim1
        irq-tim2
        irq-dac
        irq-tim21
        irq-tim22
        irq-i2c1
        irq-i2c2
        irq-spi1
        irq-spi2
        irq-usart1
        irq-usart2
        irq-rng
        irq-lcd
        irq-usb

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32L152:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 256 byte flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        flash!          ( u|n a-addr -- )   Writes word to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-dac
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0
        irq-tim2
        irq-tim3
        irq-tim4

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32L476:
;------------------------------------------------------------------------------

Flash:
        initflash       ( -- ) Clear buffers
        hflash!         ( u|n a-addr -- ) Writes halfword to flash (buffered)
        flushflash      ( -- ) Flush flash buffers
                               needed if you comma in values after create
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 2048 byte flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        16flash!        ( x1 x2 x3 x4 addr -- ) Flash 4 words aligned at 8 byte boundary at once

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0
        irq-tim2
        irq-tim3
        irq-tim4

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F100:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F103:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0

        irq-rtc
        irq-exti5
        irq-tim1brk
        irq-tim1up
        irq-tim1trg
        irq-tim1cc
        irq-tim2
        irq-tim3
        irq-tim4
        irq-i2c1ev
        irq-i2c1er
        irq-i2c2ev
        irq-i2c2er
        irq-spi1
        irq-spi2
        irq-usart1
        irq-usart2
        irq-usart3
        irq-exti10
        irq-rtcalarm
        irq-usbwkup
        irq-tim5
        irq-spi3
        irq-uart4
        irq-uart5
        irq-tim6
        irq-tim7
        irq-usbfs

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F303:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 2k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0
        irq-tim2
        irq-tim3
        irq-tim4

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for STM32F401, STM32F411, STM32F407 and STM32F429:
;------------------------------------------------------------------------------

Flash:
        eraseflash       ( -- ) Erases everything. Clears Ram. Restarts Forth.
        eraseflashsector ( u -- ) Erases one sector of Flash

        cflash!         ( char c-addr -- )  Writes byte to flash
        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-exti4
        irq-exti3
        irq-exti2
        irq-exti1
        irq-exti0
        irq-tim2
        irq-tim3
        irq-tim4

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for KL25Z128 and KL46Z256:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash - emulated
        flash!          ( u|n 4-a-addr -- ) Writes single number to flash,
                                              4 aligned !

Interrupts:

        irq-adc         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-dac
        irq-cmp
        irq-porta
        irq-portd

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for MK64FN1M0:
;------------------------------------------------------------------------------

Flash:
        initflash       ( -- ) Clear buffers
        hflash!         ( u|n a-addr -- ) Writes halfword to flash (buffered)
        flushflash      ( -- ) Flush flash buffers
                               needed if you comma in values after create
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 4 kb flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        16flash!        ( x1 x2 x3 x4 addr -- ) Flash 4 words aligned at 8 byte boundary at once

Interrupts:

        irq-adc0         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-adc1
        irq-dac0
        irq-dac1
        irq-cmp0
        irq-cmp1
        irq-cmp2
        irq-porta
        irq-portb
        irq-portc
        irq-portd
        irq-porte

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for XMC1100:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 256 byte flash page only.
                                      No Reset, no dictionary reinitialisation.

        initflash       ( -- ) Clear buffers
        hflash!         ( u|n a-addr -- ) Writes halfword to flash (buffered)
        flushflash      ( -- ) Flush flash buffers
                                 needed if you comma in values after create

        16flash!        ( x1 x2 x3 x4 addr -- ) Flash aligned 16 Bytes at once

Interrupts:

        irq-scu0        ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-scu1
        irq-eru0
        irq-eru1
        irq-eru2
        irq-eru3
        irq-usi0
        irq-usi1
        irq-usi2
        irq-usi3
        irq-usi4
        irq-usi5
        irq-adc0
        irq-adc1
        irq-ccu0
        irq-ccu1
        irq-ccu2
        irq-ccu3

;------------------------------------------------------------------------------
; Specials for EFM32GG990:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 4 kb flash page only.
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-dma         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-gpioeven
        irq-timer0
        irq-usart0rx
        irq-usart0tx
        irq-acmp0
        irq-adc0
        irq-dac0
        irq-i2c0
        irq-gpioodd
        irq-timer1
        irq-timer2
        irq-usart1rx
        irq-usart1tx
        irq-usart2rx
        irq-usart2tx
        irq-uart0rx
        irq-uart0tx
        irq-leuart0
        irq-leuart1
        irq-letimer0
        irq-pcnt0
        irq-pcnt1
        irq-pcnt2
        irq-rtc
        irq-cmu
        irq-vcmp
        irq-lcd
        irq-msc
        irq-aes

;------------------------------------------------------------------------------
; Specials for EFM32HG322:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1 kb flash page only.
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-dma         ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-gpioeven
        irq-timer0
        irq-acmp0
        irq-adc0
        irq-i2c0
        irq-gpioodd
        irq-timer1
        irq-usart1rx
        irq-usart1tx
        irq-leuart0
        irq-pcnt0
        irq-rtc
        irq-cmu
        irq-vcmp
        irq-msc
        irq-aes
        irq-usart0rx
        irq-usart0tx
        irq-usb
        irq-timer2

;------------------------------------------------------------------------------
; Specials for MK20DX256:
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash - emulated
        flash!          ( u|n 4-a-addr -- ) Writes single number to flash,
                                              4 aligned !

Interrupts:

        irq-adc0        ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-adc1
        irq-dac
        irq-cmp0
        irq-cmp1
        irq-cmp2
        irq-porta
        irq-portb
        irq-portc
        irq-portd
        irq-porte
        irq-uart0S
        irq-uart0E

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for nRF51822 and Microbit
;------------------------------------------------------------------------------

Flash:
        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        flashpageerase  ( a-addr -- ) Erase one 1k flash page only. Take care:
                                      No Reset, no dictionary reinitialisation.

        hflash!         ( u|n a-addr -- )   Writes halfword to flash

Interrupts:

        irq-power       ( -- a-addr ) Memory locations for IRQ-Hooks
        irq-radio
        irq-uart
        irq-spi0
        irq-spi1
        irq-gpiote
        irq-adc
        irq-tim0
        irq-tim1
        irq-tim2
        irq-rtc0
        irq-temp
        irq-rng
        irq-ecb
        irq-ccm_aar
        irq-wdt
        irq-rtc1
        irq-qdec
        irq-lpcomp
        irq-swi0
        irq-swi1
        irq-swi2
        irq-swi3
        irq-swi4
        irq-swi5

  Look into vectors.s and interrupts.s to add more interrupts.

;------------------------------------------------------------------------------
; Specials for Linux
;------------------------------------------------------------------------------

"Flash":

        eraseflash      ( -- ) Erases everything. Clears Ram. Restarts Forth.

        eraseflashfrom  ( a-addr -- ) Starts erasing at this address.
                                      Clears Ram. Restarts Forth.

        cflash!         ( char c-addr -- )  Writes byte to "flash"
        hflash!         ( u|n a-addr -- )   Writes halfword to "flash"

System:

        cacheflush      ( -- ) Flushes data and instruction cache
        syscall         ( r0 r1 r2 r3 r4 r5 r6 Syscall# -- r0 ) Perform Syscall
        arguments       ( -- a-addr ) Gives the initial stack pointer which
                                    contains command line arguments.
        bye             ( -- ) Leave Mecrisp-Stellaris


Matthias Koch, Summer 2013, updated Spring 2016

Distribution Changelog

05.06.2013, Matthias Koch, Mecrisp-Stellaris 0.1 experimental:

  I am very happy to announce Mecrisp-Stellaris !
  This is the very first beginning, expect monsters inside.

  As this is the younger sister of Mecrisp for MSP430,
  they share their development history and most design ideas.


12.06.2013, Matthias Koch, Mecrisp-Stellaris 0.2 experimental:

  - Unicode support
  - First interrupt handler for Systick-Timer
  - Lots of small changes
  - Ledcomm ported

15.06.2013, Matthias Koch, Mecrisp-Stellaris 0.3 experimental:

  - Recognizes both LF and CR as line ending
  - Uses hardware FIFO buffer for serial communication
  - Enables GPIO hardware on startup
  - Tidied up internal register usage
  - Faster interrupt entry
  - Fetch-Modify-Store definitions are now interrupt safe
  - Mecrisp-Stellaris now generates smaller code
  - Tidied up debug messages
  - Lots of small changes

23.06.2013, Matthias Koch, Mecrisp-Stellaris 0.4 experimental:

  - Examples in Forth for Analog, Timer, PWM and Interrupts
  - Interrupt handling for Ports and Timers included
  - Tidied up source code
  - Core needs less RAM
  - Lots of small changes

01.07.2013, Matthias Koch, Mecrisp-Stellaris 0.5 experimental:

  - Faster comparisons & bit@
  - Beautiful output for .s in current base
  - Analog Interrupts for ADC0 included
  - Examples in Forth for PLL setup and 1 Msps analog sampling

07.07.2013, Matthias Koch, Mecrisp-Stellaris 0.6 experimental:

  - New target: STM32F407 on STM32F4-Discovery board
  - Removed experimental atomic memory access from core
  - Rearranged source code and
    added English comments to simplify porting
  - First examples for STM32F4 included

29.07.2013, Matthias Koch, Mecrisp-Stellaris 0.6.1 experimental:

  - Bugfix in min and max
  - 1 Msps analog sampling example for STM

24.08.2013, Matthias Koch, Mecrisp-Stellaris 0.7 experimental:

  - New target: KL25Z128 on Freescale Freedom FRDM-KL25Z board
  - Deep changes in core:
    - New code generator for M0
    - Improved code generator for M3

10.08.2013, Matthias Koch, Mecrisp-Stellaris 0.7.1 experimental:

  - ADC and DAC examples for KL25Z128
  - Improved code generation for M0

07.11.2013, Matthias Koch, Mecrisp-Stellaris 0.7.2:

  - A lot of testing later: "experimental" is gone !
  - Disassembler for M0 included
  - Two channel 1 Msps sampling example for LM4F120
  - Contributions:
      Random number generator for STM32F4 by Sean Stasiak
      LM4F232H5QC port for Chinese QF-LM4F232 board by 呂明貴 (Albert)

16.11.2013, Matthias Koch, Mecrisp-Stellaris 0.8:

  - Deep changes in core: Opcodings !
    They generate faster code for all targets.

28.11.2013, Matthias Koch, Mecrisp-Stellaris 0.8.1:

  - New target: STM32F100 on STM VL Discovery board

18.12.2013, Matthias Koch, Mecrisp-Stellaris 0.9:

  - Double numbers and s31.32 fixpoint calculations
  - Sine/Cosine Cordic algorithm
  - Two channel 1 Msps oscilloscope for LM4F120

31.12.2013, Matthias Koch, Mecrisp-Stellaris 0.9.1:

  - Partial disassembler for M3/M4 included
  - Small optimisations in core

13.01.2014, Matthias Koch, Mecrisp-Stellaris 0.9.2:

  - Small optimisations in M3/M4 code generator
  - Faster interrupt trampolines for M3/M4
  - Timer interrupts for STM32F407
  - Added rdrop and 2rdrop

06.02.2014, Matthias Koch, Mecrisp-Stellaris 0.9.3:

  - Added for convenience: d/ mod f.n
  - Final testing package for upcoming stable 1.0 release

01.03.2014, Matthias Koch, Mecrisp-Stellaris 1.0:

  Finally the first stable release of Mecrisp-Stellaris !

21.03.2014, Matthias Koch, Mecrisp-Stellaris 1.0.1:

  Bugfix in third loop index "k"

26.03.2014, Matthias Koch, Mecrisp-Stellaris 1.0.2:

  - New target: TM4C1294 on Tiva Connected Launchpad

05.04.2014, Matthias Koch, Mecrisp-Stellaris 1.0.3:

  - New target: STM32F429ZIT6 on STM F429 Discovery
  - Instruction set emulator for Cortex M0 included

23.04.2014, Matthias Koch, Mecrisp-Stellaris 1.0.4:

  - Added Intel Hex style binaries for STM targets
  - Improved code generation for do and ?do
  - Fixed minor issue with arshift when opcoded
      with folding constant >= 32
  - Added bit rotations ror and rol
  - M3/M4 only:
    - Added 12bitencoding
    - Faster opcodes for inline literals,
        calculations, logic and comparisions
    - Included new opcodes into disassembler-m3

01.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.0

  Big tidyup release !
  - Improved readability of chip specific code
  - Factored out a lot of common code
  - Move now behaves well for both directions
  - Added fill and compiletoram?
  - Improved dictionary building macros
  - Fixed flaw in LM4F120 PLL example

02.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.1

  - New target: STM32F051R8 on STM F0 Discovery
  - Tidyup and factoring of common STM terminal code

03.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.2

  - New target: STM32F401RE on STM Nucleo F401RE
  - Variables and <builds does> are now 4-aligned on M3/M4, too
  - Added buffer:
  - Hooks for terminal redirection on TM4C1294

08.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.3

  - Added sp@ sp! rp@ rp!
  - Added hook for inner quit loop
  - ?emit and hooks for terminal redirection on all targets
  - Serial terminal code calls vectorized pause for multitasking
  - Tidyup and factoring of more common code

19.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.4

  - New target: STM32F103C8 on Shenzhen LC Technology board

21.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.5

  - Tab is now recognized as whitespace
  - Added irq-fault

27.05.2014, Matthias Koch, Mecrisp-Stellaris 1.1.6

  - Analog and PLL examples for TM4C1294
  - Enabled Prefetch Buffer in PLL examples for STM32F407
  - Added Forth source for multiline comments
  - Added Bitlog and Bitexp functions
  - Improved code generation for fetch-modify-store shortcuts
  - Testing of LM4F120 binary on TI Tiva Launchpad with TM4C123GH6PM

03.06.2014, Matthias Koch, Mecrisp-Stellaris 1.1.7

  - Added string handling helpers: expect tib >in
  - Contribution by Mark Schweizer:
      MK20DX256VLH7 port for Teensy 3.1 board

26.06.2014, Matthias Koch, Mecrisp-Stellaris 1.1.8

  - Added Loran-C for TM4C1294
  - Contribution by John Huberts:
      Port for Nordic nRF51822
  - Contribution by Bernd Paysan:
      Ethernet drivers for TM4C1294

30.06.2014, Matthias Koch, Mecrisp-Stellaris 2.0.0

  - Big changes in string handling !
    The new core is now a lot more ANS aligned and handles addr-length strings.
  - Renamed ?key in key? and ?emit in emit?
  - Renamed old counted-string handling with c-prefix
  - Create now has default action equivalent to : create <builds does> ;
    Old behaviour is renamed into (create)
  - Added irq-terminal to LM4F120 and TM4C1294 targets
  - Fixed flaw in 16-bit Flash write emulation layer for Freescale targets
  - Changed disassemblers and examples for new string handling

  Simply renamed with same function:
     ?key          --> key?
     ?emit         --> emit?
     serial-?key   --> serial-key?
     serial-?emit  --> serial-emit?
     hook-?key     --> hook-key?
     hook-?emit    --> hook-emit?
     expect        --> cexpect
     create        --> (create)
     type          --> ctype
     s"            --> c"

  Chanced behaviour:
     string,
     find
     compare
     number
     token
     parse
     #>

     s"
     type
     create

  Freshly added:
     cell+
     cells
     align
     aligned
     spaces
     count
     create
     type
     accept
     evaluate
     s"
     current-source
     setsource
     source

02.07.2014, Matthias Koch, Mecrisp-Stellaris 2.0.0a

  - Fixed a flaw in NVIC Forth code
  - Fixed a minor flaw in ethernet driver
  - Added 1Msps analog-digital converter ethernet stream example

08.07.2014, Matthias Koch, Mecrisp-Stellaris 2.0.0b

  - Added comments for nRF51822 in README
  - Fixed flaw in Pascal UDP ethernet terminal code

09.07.2014, Mark Schweizer, Mecrisp-Stellaris 2.0.1

  Following changes added for MK20DX256:

  - terminal.s:  Turned on UART0 RX/TX FIFO
                 Changed code for ensuring UART overrun flag is cleared
		 Added support for hardware flow control
  - vectors.s:   Added UART0_S/E interrupt vektor to permit the possibility
                 of interrupt driven serial (interrupts not enabled by
                 default)
  - interrupt.s: Added "ipsr" word to push Interrupt Program Status Register
                 on stack
                 Added initialization of UART0S / UART0E interrupts
  - README:      Documented serial connection, flashing, etc. (basic info)
  - Forth:       Added more examples, cleaned up code.  Seperate README
                 located in that directory.

  Matthias Koch:
  - Cleaned up core sources to save a few bytes

16.07.2014, Matthias Koch, Mecrisp-Stellaris 2.0.2

  - Added IPSR by Mark Schweizer for all targets
  - Added UNHANDLED as new default for all IRQs
  - irq-fault now catches fault handlers only
  - irq-collection catches all other interrupts
  - Factored common vector tables and interrupts
  - Added dictionarynext to core
  - Removed dump

  - New target: STM32F303VCT6 on STM F3 Discovery
  - New target: STM32L152RE   on STM Nucleo L152RE

23.08.2014, Matthias Koch, Mecrisp-Stellaris 2.0.3

  - Bugfix: Double division
  - Some small optimisations in core
  - Assembler for Cortex M0 added

18.10.2014, Matthias Koch, Mecrisp-Stellaris 2.0.4

  - Optimisations for bit@ hbit@ cbit@
  - Added rdepth rpick
  - Forth code for blocks and trace
  - Ported Ledcomm to Nucleo L152
  - Contribution by John Huberts:
      Nordic nRF51822 radio code

06.11.2014, Matthias Koch, Mecrisp-Stellaris 2.0.5

  - New experimental target: LPC1114FN28 (without Flash write access for now)
  - Unicode block editor added

11.11.2014, Matthias Koch, Mecrisp-Stellaris 2.0.5a

  - Adapted Thumbulator emulator for LPC1114FN28 and
      added Forth code to generate custom binaries for this target
  - Fixed a small flaw in disassemblers

04.12.2014, Matthias Koch, Mecrisp-Stellaris 2.0.6

  - Finally solved compilation into Flash for LPC1114FN28

01.01.2015, Matthias Koch, Mecrisp-Stellaris 2.0.7

  - Delete character 127 is now recognized
  - New target: STM32F030F4
  - Ethernet driver now has support for DHCP and ARP
  - Improved analog stream over ethernet
  - Added Ledcomm for LPC1114FN28
  - Added Real Time Clock for LM4F120 and TM4C1294
  - Added Inertial Sensor code for STM32F3 Discovery
  - Fixed counter rollover issues in systick timer delay
  - Contribution by Terry Porter:
      Register file generator from SVD to Forth with STM examples

08.02.2015, Matthias Koch, Mecrisp-Stellaris 2.0.8

  - Fixed flaw in LPC1114FN28 specific flash buffer handling
    that caused freezes after calling quit
  - Multitasking example for all targets
  - PLL and lowpower terminal code for LPC1114FN28
  - Initial graphics drivers to draw pixels on STM32F429 Discovery
  - Contribution by James Bowmann:
      Forth drivers for Gameduino 2 on STM32F401RE Nucleo
      Marsaglia pseudo random number generator
  - Contribution by Terry Porter:
      Register file generator with individual bitfields

22.02.2015, Matthias Koch, Mecrisp-Stellaris 2.0.9

  - Added eint? and reset
  - Removed obsolete ?dnegate
  - Fixed some documentation flaws in glossary

13.03.2015, Matthias Koch, Mecrisp-Stellaris 2.1.0

  - New target: LPC1115FBD48
  - Contribution by Bert Lohmann:
      I2C, LCD, PWM in and PWM out examples for LPC1114FN28

04.04.2015, Matthias Koch, Mecrisp-Stellaris 2.1.1

  - New target: MSP432P401R on MSP432 Launchpad
  - Eraseflash now performs an hardware Reset on all targets

11.04.2015, Matthias Koch, Mecrisp-Stellaris 2.1.2

  - New target: STM32L053C8 on STM32L053 Discovery
  - E-Paper display example for this new board

18.04.2015, Matthias Koch, Mecrisp-Stellaris 2.1.3

  - Ethernet driver updated to new multitasker
  - Added graphics library for lines, circles, ellipses and bitmap font
  - Contribution by Jean Jonethal:
      New target: Nucleo STM32F411
  - Contribution by Glen Worstell:
      An example for a custom prompt

27.09.2015, Matthias Koch, Mecrisp-Stellaris 2.1.4

  - New experimental target: ARM-Linux and Android
  - Faster implementation of abs function
  - Jean Jonethal fixed UART blocking on overrun for STM32F303
  - Added early experimental bignum implementation
  - Contribution by Ulrich Hoffman:
      Examples for syscall usage in ARM Linux

15.10.2015, Matthias Koch, Mecrisp-Stellaris 2.1.5

  - Contribution by Абдрахимов Илья:
      New target: STM L152 Discovery

22.10.2015, Matthias Koch, Mecrisp-Stellaris 2.2.0 & RA 1.0 experimental

  - Merged the experimental RA branch with the mainstream package

  Changes to the mainstream release are:

  - Replaced align, with halign
  - Removed align4, as it has been identical with align
  - Improved maintainability of the code
  - Small improvements under the hood here and there

28.10.2015, Matthias Koch, Mecrisp-Stellaris 2.1.6

  - Many new examples for Teensy 3.1 by Andreas Wagner
  - Bugfix for STM32L152 vector map and additional interrupt vectors,
    more examples for STM L152 Discovery by Абдрахимов Илья (Ilya Abdrahimov)

31.10.2015, Matthias Koch, Mecrisp-Stellaris RA 1.1

  - Merged news from 2.1.6 into this package
  - Improved tuck

01.11.2015, Matthias Koch, Mecrisp-Stellaris RA 1.2

  - Jean Jonethal added STM32F303-RA and fixed a bug.

05.11.2015, Matthias Koch, Mecrisp-Stellaris RA 1.3

  - Inline-Cache allows register allocation across inlined definitions

08.11.2015, Matthias Koch, Mecrisp-Stellaris RA 1.4

  - Small improvements for negate

14.11.2015, Matthias Koch, Mecrisp-Stellaris RA 1.5

  - Smaller disassemblers
  - Continuous sampling with exponential average for Loran-C
  - RTC examples for STM L152 Discovery by Абдрахимов Илья (Ilya Abdrahimov)
  - Contribution by Jean Jonethal:
      New target: STM L476 Discovery

28.11.2015, Matthias Koch, Mecrisp-Stellaris RA 1.5a

  - Added fast integer square root
  - More examples for STM L152 Discovery by Абдрахимов Илья (Ilya Abdrahimov)
  - Experimental new target: XMC1100 on Infineon XMC2GO board


24.12.2015, Matthias Koch, Mecrisp-Stellaris 2.2.0 - Christmas release !

  My Christmas present for you:
  Mecrisp-Stellaris RA with Register Allocator is ready for mainstream release
  and should already be quite stable after a few months of testing.

  Now you can choose for your projects if you need the smaller classic core
  or the larger RA which includes much stronger optimisations.

  Both should have exactly the same capabilities and behaviours.

  Some hints for the choice:

  If you touch performance barriers with the classic core,
  if you love experiments and if you are curious,
  try the fresh Mecrisp-Stellaris RA core.

  If you have something that already works well with older releases,
  if your project has high demands on stability,
  if space is what you wish to save,
  use the smaller and rock solid classic Mecrisp-Stellaris.

  Changes relative to Mecrisp-Stellaris 2.1.6:

  - Replaced align, with halign
  - Removed align4, as it has been identical with align

01.01.2016, Matthias Koch, Mecrisp-Stellaris 2.2.1 - 32C3 release !

  E-Paper graphics buffer and paint primitives
  New target: Silicon Labs Giant Gecko Starter Kit with EFM32GG990F1024
  Fixed flaw in RA core when inlining empty definitions

  - Contribution by Ilya Abdrahimov: 1-Wire for STM32L152RB
  - Contribution by Jean Jonethal:
      New target: STM F746 Discovery

13.02.2016, Matthias Koch, Mecrisp-Stellaris 2.2.1a

  - LDMIA + Interrupt silicon bug found: KNOWN-ISSUES added
  - Added RA for LPC1115
  - Contribution by Ralph Sahli: Peripheral libraries for STM32F407
  - Contribution by Terry Porter: Register definitions and insight generator
  - Contribution by Igor OM1ZZ: Eight queens bechmark and PLL code

20.02.2016, Matthias Koch, Mecrisp-Stellaris 2.2.2

  - More interrupts in STM32F103
  - Added STM32F103-RA
  - Contribution by Ilya Abdrahimov: Many examples for STM32F429
  - Contribution by Ralph Sahli: Many more examples and libraries for STM32F407

26.03.2016, Matthias Koch, Mecrisp-Stellaris 2.2.3

  - New target: Silicon Labs Happy Gecko Starter Kit with EFM32HG322F64

28.03.2016, Matthias Koch, Mecrisp-Stellaris 2.2.4

  - No line break directly after the "Redefine..." message anymore
  - Graphics driver for Sharp LCD on Happy Gecko
  - New target: KL46Z256 on Freescale Freedom FRDM-KL46Z board

06.04.2016, Matthias Koch, Mecrisp-Stellaris 2.2.5

  - Added ahead and changed control structures to allow more combinations
  - Fixed Forth register constants for PORTE on KL25Z128 and KL46Z256
  - New target: MK64FN1M0 on Freescale Freedom FRDM-K64F board
  - New target: LPC1114FBD48
  - New target: Nordic nRF51822 prepared for Microbit

08.05.2016, Matthias Koch, Mecrisp-Stellaris 2.2.6

  - Scripts for invoking Mecrisp-Stellaris for ARM Linux with qemu-arm-static
  - Contribution by Bernd Paysan:
      New target: STM32F207ZG on Nucleo-F207ZG

14.05.2016, Matthias Koch, Mecrisp-Stellaris 2.2.7

  Linux target got an improving touch:

    - Added cacheflush to solve difficulties with data and instruction cache flushes
    - Welcome message is omitted when command line arguments are specified
    - A check for Ctrl+D and for EOF in serial-key quits Mecrisp-Stellaris for Linux
    - arguments, reset, eraseflash and eraseflashfrom added
    - Now 1 MB for compiletoram and compiletoflash each
    - Smaller binary
    - Forth code for cornerstone added
    - Handling of command line arguments in Forth

19.06.2016, Matthias Koch, Mecrisp-Stellaris 2.2.8

  - Increased stack size for Linux target
  - Mecrisp-Stellaris-Linux now uses software division like the M0,
      as, crazy enough, there is no integer division on large ARMs like A9 and A15.

23.08.2016, Matthias Koch, Mecrisp-Stellaris 2.2.9

  - Contribution by Ralph Sahli:
    New target: STM32F303K8 with many examples.
                "Neopixel" driver for WS2812B LEDs and more.

25.09.2016, Matthias Koch, Mecrisp-Stellaris 2.3.0

  - With a lot of heavy testing out in the wild, now it is time to announce
    the register allocator "RA" as stable and ready for general usage.

  - "Dotstar" driver for APA102 LED strings connected to a LM4F120
  - Profiler written in Forth to count usage of definitions
  - Forth code for conditional compilation
  - Contribution by Ilya Abdrahimov:
      Improved 1-Wire drivers and many new examples for STM32F103 and STM32F411

02.12.2016, Matthias Koch, Mecrisp-Stellaris 2.3.1

  - A bug was found in the register allocator: Fixed abs for all RA targets.
  - Contribution by Terry Porter:
      svd2forth-v2 - A fresh register file generator from SVD to Forth

15.12.2016, Matthias Koch, Mecrisp-Stellaris 2.3.2

  - RA binary for STM32L053C8
  - Contribution by Ronny Suy:
      New experimental target: ATSAME70Q21 on Atmel SAME70 X-plained,
      just still without the possibility to compile into flash.

01.01.2017, Matthias Koch, Mecrisp-Stellaris 2.3.3 - 33C3 release !

  - Added forgetram to all targets
  - Added call trace utility and quotations
  - RA binary for MSP432P401R
  - Added autoerase macro which clears flash dictionary on the first run
  - All EFM32 Gecko and MSP432 targets are now equipped with the autoerase feature
  - Contribution by Ralph Sahli:
      New targets: STM32F303RE on STM Nucleo F303RE
                   STM32L432KC on STM Nucleo L432KC

21.01.2017, Matthias Koch, Mecrisp-Stellaris 2.3.4

  - RA binary for STM32F407
  - Contribution by Ralph Sahli:
      New target: STM32F401CD on Espruino Pico

22.02.2017, Matthias Koch, Mecrisp-Stellaris 2.3.4a

  No changes in binaries, just fixed a documentation flaw and new Forth features:

  - Fixed glossary: c-addr length strings are used by number

  - Jean-Claude Wippler conquered USB: Drivers for STM32F103 and STM32F303 included
  - Direct digital synthesis dual sinewave function generator for STM32F407
  - Very early experimental access to the hardware floating point unit

22.02.2017, Matthias Koch, Mecrisp-Stellaris 2.3.5

  - Found a bug: If the "init" mechanism was used on RA cores, compilation of the first
    definition after a Reset might generate a leading bogus sequence of opcodes due to
    a not properly initialised internal variable.

    Workaround, if you cannot update the core: Type "quit" before doing fresh compilations.

16.03.2017, Matthias Koch, Mecrisp-Stellaris 2.3.6

  - Graphics routines now draw Unicode characters.
    Glyphs for ISO-8859-1 and ISO-8859-15 charset coverage included, you can add more.
  - Contribution by Werner Urech:
      New target: STM32L073RZ on STM Nucleo L073RZ

Distribution Known Issues

\ -----------------------------------------------------------------------------
\  Known issues
\ -----------------------------------------------------------------------------

*********************************
*  LDMIA + Interrupts in M3/M4:
*********************************

  LDMIA and some other opcodes with a register list can be interrupted and
  continued afterwards in M3 and M4 cores.

  Unfortunately, there seems to be a silicon bug in some chips / core revisions
  that causes an interrupted LDMIA opcode to fail.

  The error has already been observed in LM4F120, TM4C1294, STM32F407
  when using the multitasking example. M0 chips and EFM32GG990 are fine.

  It could affect other M4 chips and maybe M3, too.

  So if you get mysterious crashes when using Interrupts om M3/M4,
  try disabling preemption capabilities with this workaround:

  1 $E000E008 !

  Drawback is that this increases interrupt latency.

  Manual snipplets:

  B1.5.10 Exceptions in LDM and STM operations

       In order to allow implementations to have the best possible interrupt response, an interrupt can be taken
       during an LDM or STM and continued after the return from the interrupt. The continuation state of the LDM or
       STM is held in the ICI bits in the EPSR (see The special-purpose program status registers (xPSR) on
       page B1-8). It is IMPLEMENTATION DEFINED when interrupts are recognized, so the use of the ICI bits is
       IMPLEMENTATION DEFINED.
       The ARMv7-M architecture supports continuation of, or restarting from the beginning, an abandoned LDM
       or STM instruction as outlined below. Where an LDM or STM is abandoned and restarted (ICI bits are not
       supported), the instructions should not be used with volatile memory. To support instruction replay, the LDM,
       STM, PUSH and POP instructions are required to restore/maintain the base register when a fault occurs (no base
       register writeback update) during execution.

  M3: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/CHDCBHEE.html
  M4: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDCBHEE.html

  Address     Name   Type  Required privilege  Reset value  Description
  0xE000E008  ACTLR  RW    Privileged          0x00000000   Auxiliary Control Register

  Auxiliary Control Register

  [0]    DISMCYCINT     Disables interruption of multi-cycle instructions.
         This increases the interrupt latency of the processor because load/store and
         multiply/divide operations complete before interrupt stacking occurs.

  M7: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646b/CHDCBHEE.html
  Does not have this bit.


****************************************
* Terminal running on Android / Linux:
****************************************

  The linux port is known to work on both Linux and Android, but on some kernels, pasting into
  the terminal causes problems. Manual typing always works.

  It is still unclear why the terminal fails, as the standard input is used
  exactly the same way in both cases and should be properly buffered by the underlying OS kernel.

  Cache flushing issues due to independent caches for instructions and data may cause the problem.

Table Of Contents

Previous topic

Alternate Functions

Next topic

Undefined Behaviour

This Page