
;------------------------------------------------------------------------------
A glossary with short descriptions of function
of all included definitions in Loran-C receiver:
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
  Assembly definitions included in Mecrisp-Stellaris-STM32F4-Loran core:

        loran-register-init ( -- ) Initialise special registers

        sample>address  ( u -- address ) Get location of given sample in memory
                                         Each sample is stored in 16 Bits.

        sign16          ( n16 -- n32 ) Sign extend 16 Bits to 32 Bits

       pulseconvolution ( sample# -- intensity ) Calculate one point of convolution
                                       with pulse shape starting on given sample#

        gri@            ( -- u ) Fetch current GRI in us units
        gri!            ( u -- ) Set GRI. Maximum is 81000 (us).

        offset@         ( -- u ) Fetch offset currently in use
        offset!         ( u -- ) Set   offset for capture

        samples@        ( -- u ) Fetch samples still to do
        samples!        ( u -- ) Set   samples to capture

        sampleno@       ( -- u ) Fetch circular buffer pointer
        sampleno!       ( u -- ) Set   circular buffer pointer

        tack@           ( -- u ) Get Tack value, do "$FFFF and" with it.
                                 Low 16 Bits contain Tack, high halfword 
                                 contains current tack counter.
        tack!           ( u -- ) Set Tack value

        avg2h!          ( x 16-addr -- )  Store with exponential average over two 16 bit samples
        avg4h!          ( x 16-addr -- )    for 4 samples
        avg8h!          ( x 16-addr -- )    for 8 samples
        avg16h!         ( x 16-addr -- )    for 16 samples

        avg2!           ( x addr -- )    Store with exponential average over two 32 bit samples
        avg4!           ( x addr -- )      for 4 samples
        avg8!           ( x addr -- )      for 8 samples
        avg16!          ( x addr -- )      for 16 samples

  Interrupt handlers:

        exact-crystal-loran-handler ( -- )  Simply capture...
         fast-crystal-loran-handler ( -- )    with slow-down switch cycles
         slow-crystal-loran-handler ( -- )    with hurry-up  switch cycles

  Copy them into RAM before use because execution from Flash needs
  waitstates for 120 MHz CPU clock and simply is too slow for capturing. 


;------------------------------------------------------------------------------
  Definitions available in Forth source - loran.txt

  There are lots of IO port definitions for hardware access, which I skip here.
  
  Hardware initialisation:

        120MHz-2Msps    ( -- )  Setup PLL for 120 MHz CPU clock and 2 MHz sample rate for ADC.
                                The higher ADC sample rate is necessary to be able to hurry up
                                in case of a too slow crystal.
        init-timer      ( -- )  Setup timer running on 60 MHz for switch-cycle frequency calibration.
        init-analog     ( -- )  Setup ADC

        ram-exact-crystal-loran-handler  ( -- addr ) Variables for the locations of interrupt
        ram-slow-crystal-loran-handler   ( -- addr ) handlers copied into RAM for faster
        ram-fast-crystal-loran-handler   ( -- addr ) execution without waitstates

        init            ( -- )  Init is the turnkey. It performs all hardware initialisations and 
                                copies interrupt handlers into RAM.

  Sampling setup:

        gricycle        ( -- )    1 MHz sampling for GRIs (default)
        fricycle        ( -- )  500 kHz sampling for FRIs

        exact-xtal      ( -- ) Switch handler for crystal type
        slow-xtal       ( -- )   needed for manual fiddling with
        fast-xtal       ( -- )   handlers and Tack values.

        t               ( u -- ) Abbrevation for tack!

        khz             ( f -- ) Manual frequency calibration (recommended method)

  Capture helpers:

        clearbuffer     ( -- ) Zero out buffer
        latestgris      ( -- ) Variable that contains number of GRIs that have been sampled,
                               this is necessary for buffer signal amplitude scaling
        samplegris      ( n -- ) Sample and sum up given number of GRIs into buffer
        getsample       ( sample# -- n ) Read sample from buffer
        puffermaximum   ( -- n ) Gives absolute maximum amplitude in buffer
        printbuffer     ( -- )   Prints the whole signal buffer contents
        offsetmeasurement ( -- ) Determine current signal offset and set on-the-fly offset subtraction 
                                 accordingly in ordet to not overflow 16 bit buffer with large summed offsets

        griscapture      ( -- addr ) Variable to set how many GRIs are summed up for a signal capture
        griscalibration  ( -- addr)  Variable to set how many GRIs are summed up for a clock calibration

        capture          ( -- ) Capture a signal, not much info

  Amplitude based frequency calibration (not recommended, available just in case)

        calfreq          ( -- ) Try to finely adjust frequency on summed amplitude
        coarse           ( -- ) Try to coarsely determine local crystal frequency - 
                                both needs lot of time, good SNR and rock solid amplitude levels

        calibrationtack      ( -- addr )  Internal usage  
        calibrationamplitude ( -- addr )  Internal usage
        calibrationrange     ( -- addr )  Range of tack values to scan


;------------------------------------------------------------------------------
  Definitions available in Forth source - signalprocessing.txt

  Small Helpers:

        f.n             ( ncomma nwhole ndigits ) Print fixpoint number with n fractional digits
        d/              ( d1 d2 -- d3 ) 64 Bit division

  Signal quality estimations:

        vcc             ( -- addr ) Fixpoint variable of current Vcc - set with "2,96 vcc 2!"
        voltage.        ( u -- ) Print ADC sample as voltage value
        adc+voltage.    ( u -- ) Print ADC sample as sampled integer and voltage value
        offset-double   ( -- Offset ) Calculate overall buffer offset with 64 bit intermediate value
        signedmax       ( -- n ) Search for maximum value in buffer
        signedmin       ( -- n ) Search for minimum value in buffer

        noiseoffset     ( -- addr) Variable for current buffer offset, needed for noise amplitude calculation
        noiselevel      ( -- amplitude ) Calculate noise amplitude

        signalquality   ( -- ) Prints current signal specifications


  Convolve the buffer contents with Loran-C pulse shape:

        offsetcorrection ( -- ) Subtract any remaining small offset from buffer

        convolution      ( -- ) Find pulses with help of filter implemented in assembly for speed.
                                Irreversible step, overwrites signal in buffer.


  Find pulse trains and calculate TDs:

        wrap-sample>address ( sample# -- address ) Get address of sample in buffer with circular wrap over

        getmastertrain  ( sample -- value )  Sum up pulse train at given sample position with pulse polarity + - + +
        getslavetrain   ( sample -- value )  Sum up pulse train at given sample position with pulse polarity + + + -
        inside          ( x low high -- flag ) Is value inside of the borders ?
        notinenvironment ( x location -- flag ) Is sample x far enough distant (7000us) from the given location ?

        stations        ( -- addr ) Variable for numers of stations in use.
                                      Default: 3 stations M, X, Y as for Sylt chain. 
                                      Change to 4 for Lessay chain which has M, X, Y, Z.

        findpulsetrains ( -- ) Search for pulse trains and update the following variables:

              location1     Where is the pulse train ?
              amplitude1    How strong ?
              type1         Master (-1) or slave (0) ?

              location2     Pulse trains are searched in decreasing amplitude order.
              amplitude2
              type2

              location3
              amplitude3
              type3

              location4
              amplitude4
              type4


        timedelay ( master slave -- td ) Calculate delay with GRI wrap over
        calculatetds ( -- )  Calculate all Time Delays with pulse trains given in variables of findpulsetrains


  Where I am:

        capture-advanced ( -- ) Capture signal with signal level and quality info
        locate           ( -- ) Do everything to calculate TDs from captured signal
        l                ( -- ) Abbrevation for both capture-advanced and locate


;------------------------------------------------------------------------------
  Definitions available in Forth source - convolution-adjust.txt:

  Search for and lock to a strong pulse train:

        findstrongestpulsetrain ( -- location ) Find most intense pulse train in buffer
        insearchrange ( x location -- flag ) Is x within a 1500 us range of location ?
        findagain-strongestpulsetrain ( -- location ) 
                                          Find most intense pulse train within
                                          a 1500 us range around the capture before to make
                                          sure to lock to the same pulse train again.
                                          This should be suifficient to handle +-150 ppm crystals
                                          and is necessary if different pulse trains have same amplitude

        location-max    ( -- addr )       Some internal variables to lock
        amplitude-max   ( -- addr )       to the same pulse train
        calibration-location ( -- addr )  again in the second run.


  A small 32 Bit stopwatch running at 60 MHz:

        init-counting   ( -- )  Prepare Timer 5 for stop watch function
        start-clock     ( -- )  Start counting
        stop-clock      ( -- elapsedcycles ) Stop counting and give elapsed cycles at 60 MHz


  Frequency calculation helpers:


        s>f             ( n -- f )  32 Bit integer to Fixpoint conversion
        getsignedtack   ( -- n )  Fetch current tack with sign for frequency calculations
        readkhz         ( -- f )  Determine which assumed frequency for crystal is currently in use.

        shift-in-time-to-frequency-offset ( u-elapsedcycles n-timedifference -- f-frequencyoffset )
                                  Calculate frequency offset from sampling shift over an elapsed time

        timeshift ( location-old location-new -- n-timeshift ) 
                                  Gives the signed time shift between two locations in buffer.

  Frequency calibration (recommended):

       grisconvolutionadjust ( -- addr ) Variable to set how many GRIs are summed up for a convolution frequency adjust

       convolution-adjust ( -- ) Calibrate frequency by position shift in buffer of a strong pulse train over time

       cold-ca          ( -- ) Initial cold-boot frequency calibration with 4 GRIs only
       ca               ( -- ) Abbrevation for convolution-adjust


  Detect presence of a intermittent signal:

     transmissiondetector ( -- ) Let red LED shine if a Loran-C signal is on air on GRI configured before
     detectorlevel        ( -- addr ) Variable to adjust detector limit to your actual signal strengths


  Final measuring loop:
 
     measure-convolution ( -- ) Does everything a Loran-C receiver should do: Lock frequency, capture and calculate TDs.




;------------------------------------------------------------------------------
  This is the whole core glossary which is not specific to Loran-C:



;------------------------------------------------------------------------------
; Terminal-IO
;------------------------------------------------------------------------------

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

;------------------------------------------------------------------------------
; 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 -- )

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 -- )

;------------------------------------------------------------------------------
; 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
        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
        clz             ( x1 -- u ) Count leading zeros
        false           ( --  0 ) False-Flag
        true            ( -- -1 ) True-Flag

;------------------------------------------------------------------------------
; 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
        /               ( 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
        */              ( 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 n -- d2 ) Negate d1 if n is negative
        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

        number          ( Counted-String-Address -- 0 )
                          cstr-addr              -- 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
                        Caution with overlapping areas, as for now it moves
                        in forward direction only.

        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

        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 (subtle differences to ANS)
;------------------------------------------------------------------------------

String routines:
        compare         ( cstr-addr-1 cstr-addr-2 -- flag )
                        Compares two counted strings

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

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

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

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

        bl              ( -- 32 ) ASCII code for Space
        space           ( -- ) Emits space
        cr              ( -- ) Emits line feed

Pictured numerical output:
        .digit          ( u -- char ) Converts a digit to a char
        digit           ( char -- u ) 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              ( u1|n1 -- 0 0 ) Add all remaining digits
                        from the single length number to output buffer
        #               ( u1|n1 -- u2|n2 ) Add one digit from the
                        single length number to output buffer
        #>              ( u|n -- cstr-addr )
                        Drops number and finishes
                        pictured numeric output ready for type
        <#              ( -- ) Prepare pictured number output buffer
        u.              ( u -- ) Print unsigned single number
        .               ( n -- ) Print single 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
        dump            ( addr -- ) Dumps a bit of memory
        hex.            ( u -- ) Prints 32 bit unsigned in hex base,
                                 needs emit only.
                                 This is independent of number subsystem.

;------------------------------------------------------------------------------
; User input and its interpretation (more FIG style, speciality!)
;------------------------------------------------------------------------------

        query           ( -- ) Fetches user input to input buffer
        token           ( -- cstr-addr ) Cuts one token out of input buffer
        parse           ( char -- cstr-addr )
                        Cuts anything delimited by char out of input buffer

        interpret       ( any -- any ) Execute, compile, fold, optimize...
        quit            ( many -- ) (R: many -- ) Resets Stacks

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

        ,               ( 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
        string,         ( cstr-addr -- ) Inserts a string 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
        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
        dictionarystart ( -- a-addr ) Current entry point for dictionary search

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

  
    Available depending on chip capabilities:

        c,              ( char -- ) Appends a byte to dictionary
        align,          ( -- ) Makes Dictionary Pointer even, if uneven.
        align4,         ( -- ) Aligns on 4. M0 only

        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

;------------------------------------------------------------------------------
; 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 !
        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            ( cstr-addr -- 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.
        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.

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
;------------------------------------------------------------------------------
        dint            ( -- ) Disables Interrupts
        eint            ( -- ) Enables  Interrupts
        nop             ( -- ) No Operation. Hook for unused IRQs !

        irq-systick     ( -- a-addr ) Memory locations for IRQ-Hooks

;------------------------------------------------------------------------------
; Specials for STM32F4:
;------------------------------------------------------------------------------

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
