;
;    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/>.
;

; Tools for deep insight into Mecrisp and its Stacks.

writezahl macro Zahl
  pushda Zahl
  call #udot
  endm

writebyte macro Zahl
  decd r4
  clr @r4
  mov.b Zahl, @r4
  call #udot
  endm

;------------------------------------------------------------------------------
  Wortbirne Flag_visible, "words" ; ( -- ) Print list of words with debug information
;------------------------------------------------------------------------------
  push r10
  push &Base
  mov #16, &Base

  ifdef flashdictionaryeinbinden
  cmp #nBacklinkgrenze, &DictionaryPointer
  jhs +
  ; For Ram:
    mov &Fadenende, r10
    jmp ++
+ ; For Flash
    mov #CoreDictionaryAnfang, r10
+
  else ; If there is a Ram-Dictionary only
    mov &Fadenende, r10
  endif

  ; r10 contains beginning of dictionary
  writeln ""

- ; Construction: Flags     Length-of-Name
  ;               Name...   (0 for alignment)
  ;               Link
  ;               Code

  ifdef flashdictionaryeinbinden
  ; If there is $FFFF at the place of flags and length of name, then we found end of dictionary
  cmp #0FFFFh, @r10
  je +
  endif

  ; Found dictionary entry !
  write "Address: "
  writezahl r10
  write " Flags: "
  writebyte @r10
  inc r10

  sub #4, r4     ; Reserve enough space
  mov r10, 2(r4) ; Save address for printing name later

  call #stringueberlesen_r10

  ; Pointer now reached link
  write " Link: "
  mov @r10, @r4
  call #udot

  ; Write code start address
  write " Code: "
  pushda r10
  incd @r4
  call #udot

  ; Write name
  write " Name: "
  call #schreibestringmitlaenge
  writeln "" ; cr

  cmp #0FFFFh, @r10  ; -1 denotes end
  je +

  ; Follow link
  mov @r10, r10
  jmp -

+ pop &Base
  pop r10
  ret

;------------------------------------------------------------------------------
  Wortbirne Flag_visible, ".s"
dotS: ; Prints out data stack, uses unsigned numbers. 
      ; Especially useful for logic, addresses and counters.
;------------------------------------------------------------------------------
  push r10
  push r11
  mov #datenstackanfang, r10  ; Top address of stack
  mov r10, r11                ; Copy it
  sub r4, r11                 ; Calculate fill level

  write " Stack: ["

dotseinsprung:
  clrc
  rrc r11                     ; Divide fill level by two, as stack is organized in words..

  ; Pointer in r10, number of words to print in r11.

  push &Base      ; Print fill level
  mov #10, &Base
    writezahl r11
  pop &Base

  write "] "

  tst r11 ; Reached Zero, finished printing ?
  je +

- decd r10       ; Print content
  writezahl @r10

  dec r11
  jz +
  write ", "
  jmp -

+ writeln " *>"

  pop r11
  pop r10
  ret

;------------------------------------------------------------------------------
  Wortbirne Flag_visible, ".rs"
      ; Prints out return stack, uses unsigned numbers. 
      ; Especially useful for logic, addresses and counters.
;------------------------------------------------------------------------------
  push r10
  push r11
  mov #returnstackanfang, r10 ; Top address of stack
  mov r10, r11                ; Copy it
  sub sp, r11                 ; Calculate fill level
  sub #6, r11                 ; Off by 6 for entry into .rs and saved registers.

  write " Returnstack: ["
  jmp dotseinsprung
