;
;    Mecrisp - A native code Forth implementation for MSP430 microcontrollers
;    Copyright (C) 2011  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/>.
;

; Initialisiert die Pointer und Flash-Variablen nach dem Neustart.
; Wird direkt eingefügt und nur einmal beim Start benutzt,
; deshalb werden Register hier nicht gesichert.


  ; Registerbelegung:
  ; r10 Adresshangelzeiger
  ; r11 Flags
  ; r12 Belegtes Ram.
  ; r13 SucheFadenende...
  ; r14 Kopie von r10 für Variableninitialisierung
  ; r15 Kopie von r12 für Variableninitialisierung

  ifdef ramverwaltungeinbinden
    mov #nRamDictionaryEnde, r12 ; Fürs Abzählen des Variablenplatzes
  endif

  mov #CoreDictionaryAnfang, r10 ; Hier fängt es an.

  ; Die Struktur der Wörter ist so:
  ; Flags | Namenslänge  oder $FFFF
  ; Namen
  ; Namen (|0)
  ; Link Richtung Fadenanfang
  ; Link Richtung Fadenende bzw. $FFFF falls noch nicht gesetzt

  ; Zwei Möglichkeiten: Vorwärtslink ist $FFFF --> Ende gefunden
  ; Oder Vorwärtslink gesetzt, aber an der Stelle liegt $FFFF. Dann ist das Ende auch da.
  ; Diese Variante tritt auf, wenn nichts hinzugetan wurde, denn im festen Teil ist der Vorwärtslink
  ; immer gesetzt und zeigt auf den Anfang des Schreib/Löschbaren Teils.

SucheFlashPointer_Hangelschleife:
  mov r10, r13 ; Es könnte das Fadenende sein !
  ; Hier ist r10 direkt auf das Flagfeld gerichtet.

  ifndef ramverwaltungeinbinden
    inc r10 ; Flags überlesen
    call #stringueberlesen_r10
  else
    mov.b @r10+, r11 ; Hole die Flags und überlese sie !
    call #stringueberlesen_r10

    ; Prüfe, ob die Flags FF sind. In diesem Fall ignorieren.
    cmp #0FFh, r11
    je +

    ; Prüfe, ob dieses Wort Speicherplatz belegt.
    bit #Flag_ramallot, r11
    jnc + ; Wenn nicht, bin ich fertig.

    ; Ja, das Wort belegt Speicher.
    and #0Fh, r11 ; Low-Nibble maskieren
    rla r11       ; mit zwei Malnehmen
    sub r11, r12  ; und den Zeiger wandern lassen.

  ifdef initialisiereflashvariablen
    tst r11
    je + ; Bei Null Bytes brauche ich nichts zu kopieren.
    ; An dieser Stelle kann ich nun die Variablen initialisieren, wenn ich das möchte.

    mov r10, r14 ; r14: Hangelzeiger kopieren
    mov r12, r15 ; r15: Ram-Variablen-Pointer kopieren

    incd r14 ; Linkfeld überlesen
-   incd r14 ; Rücke um ein Word vor.
    cmp #4130h, -2(r14) ; Ist dort an der letzten Stelle Ret ? Dann habe ich nun die Adresse des Opcodes.
    jne -

    ; Habe nun in r14 den Zeiger auf den Initialisierungsinhalt.
    ; Kopiere ihn an die richtige Stelle ! r11 gibt Zahl der Bytes an.
-   mov.b @r14+, @r15
    inc r15
    dec r11
    jnz -

+   ; Fertig mit der Initialisierung.
  endif ; ifdef  initialisiereflashvariablen
  endif ; ifndef ramverwaltungeinbinden

  cmp #0FFFFh, @r10  ; Ist der Vorwärtslink gesetzt ?
  je +

  mov @r10, r10
  cmp #0FFFFh, @r10  ; Ist dort etwas anderes als $FFFF ?
  je +

  jmp SucheFlashPointer_Hangelschleife

+ ifdef ramverwaltungeinbinden
    mov r12, &VariablenPointer
  endif

  ifdef flashkompilationsstart
    mov r13, &Fadenende
    mov #CoreDictionaryAnfang, &ZweitFadenEnde
  else
    mov r13, &ZweitFadenende
    mov #CoreDictionaryAnfang, &FadenEnde
  endif

  ; Suche jetzt gleich noch den DictionaryPointer.

  mov #nFlashDictionaryEnde, r10 ; Kann eigentlich an der Stelle DictionaryEnde etwas liegen ?
  ; Gehe Rückwärts, bis ich aus dem $FFFF-Freigebiet in Daten komme.
- cmp #nFlashDictionaryAnfang, r10 ; Wenn ich am Anfang angelangt bin, ist das der DictionaryPointer.
  je +

  decd r10
  cmp #0FFFFh, @r10
  je - ; Wenn es nicht gleich ist, habe ich eine Füllung gefunden.

  incd r10

+ ; DictionaryPointer gefunden.

  ifdef flashkompilationsstart
    mov r10, &DictionaryPointer
    mov #nRamDictionaryAnfang, &ZweitDictionaryPointer
  else
    mov r10, &ZweitDictionaryPointer
    mov #nRamDictionaryAnfang, &DictionaryPointer
  endif
