#
#    Mecrisp-Quintus - A native code Forth implementation for RISC-V
#    Copyright (C) 2018  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/>.
#

# Terminal redirection hooks.

#------------------------------------------------------------------------------
  Definition Flag_visible|Flag_variable, "hook-emit" # ( -- addr )
  CoreVariable hook_emit
#------------------------------------------------------------------------------
  pushdaaddrf hook_emit
  ret
  .word serial_emit  # Serial communication for default

#------------------------------------------------------------------------------
  Definition Flag_visible|Flag_variable, "hook-key" # ( -- addr )
  CoreVariable hook_key
#------------------------------------------------------------------------------
  pushdaaddrf hook_key
  ret
  .word serial_key  # Serial communication for default

#------------------------------------------------------------------------------
  Definition Flag_visible|Flag_variable, "hook-emit?" # ( -- addr )
  CoreVariable hook_qemit
#------------------------------------------------------------------------------
  pushdaaddrf hook_qemit
  ret
  .word serial_qemit  # Serial communication for default

#------------------------------------------------------------------------------
  Definition Flag_visible|Flag_variable, "hook-key?" # ( -- addr )
  CoreVariable hook_qkey
#------------------------------------------------------------------------------
  pushdaaddrf hook_qkey
  ret
  .word serial_qkey  # Serial communication for default

#------------------------------------------------------------------------------
  Definition Flag_visible|Flag_variable, "hook-pause" # ( -- addr )
  CoreVariable hook_pause
#------------------------------------------------------------------------------
  pushdaaddrf hook_pause
  ret
  .word nop_vektor  # No Pause defined for default

#------------------------------------------------------------------------------
  Definition Flag_visible, "nop" # ( -- )
nop_vektor:
#------------------------------------------------------------------------------
  ret

#------------------------------------------------------------------------------
  Definition Flag_visible, "emit" # ( c -- )
emit:
#------------------------------------------------------------------------------
  laf x5, hook_emit
  lw x5, 0(x5)
  .ifdef mipscore
  jr x5
  .else
  jalr zero, x5, 0
  .endif

#------------------------------------------------------------------------------
  Definition Flag_visible, "key" # ( -- c )
key:
#------------------------------------------------------------------------------
  laf x5, hook_key
  lw x5, 0(x5)
  .ifdef mipscore
  jr x5
  .else
  jalr zero, x5, 0
  .endif

#------------------------------------------------------------------------------
  Definition Flag_visible, "emit?" # ( -- ? )
#------------------------------------------------------------------------------
  laf x5, hook_qemit
  lw x5, 0(x5)
  .ifdef mipscore
  jr x5
  .else
  jalr zero, x5, 0
  .endif

#------------------------------------------------------------------------------
  Definition Flag_visible, "key?" # ( -- ? )
#------------------------------------------------------------------------------
  laf x5, hook_qkey
  lw x5, 0(x5)
   .ifdef mipscore
  jr x5
  .else
  jalr zero, x5, 0
  .endif

#------------------------------------------------------------------------------
  Definition Flag_visible, "pause" # ( -- ? )
pause:
#------------------------------------------------------------------------------
  laf x5, hook_pause
  lw x5, 0(x5)
  .ifdef mipscore
  jr x5
  .else
  jalr zero, x5, 0
  .endif



.macro Debug_Terminal_Init

  # A special initialisation sequence intended for debugging
  # Necessary when you wish to use the terminal before running catchflashpointers.

  # Initialize register file
  addi x1, zero, 0           # Return address register, holds link back and is also used to compose long calls with auipc and jalr
  laf   x2, returnstackanfang # Stack pointer x2 (sp) is initialized by reset to end of RAM... We may choose another location.
  addi x3, zero, 42          # TOS
  laf   x4, datenstackanfang  # PSP Set data stack pointer
  addi x5, zero, 0           # Free scratch register, not saved across calls.
  addi x6, zero, 0           # Free scratch register, not saved across calls.
  addi x7, zero, 0           # Scratch register, needs to be saved.
  addi x8, zero, 0           # Loop index
  addi x9, zero, 0           # Loop limit
  addi x10, zero, 0          # Scratch register, needs to be saved.
  addi x11, zero, 0          # Scratch register, needs to be saved.
  addi x12, zero, 0          # Scratch register, needs to be saved.
  addi x13, zero, 0          # Scratch register, needs to be saved.
  addi x14, zero, 0          # Scratch register, needs to be saved.
  addi x15, zero, 0          # Scratch register, needs to be saved.

#  addi x16, zero, 0          # x16-x31: Unused.
#  addi x17, zero, 0
#  addi x18, zero, 0
#  addi x19, zero, 0
#  addi x20, zero, 0
#  addi x21, zero, 0
#  addi x22, zero, 0
#  addi x23, zero, 0
#  addi x24, zero, 0
#  addi x25, zero, 0
#  addi x26, zero, 0
#  addi x27, zero, 0
#  addi x28, zero, 0
#  addi x29, zero, 0
#  addi x30, zero, 0
#  addi x31, zero, 0

   la x5, serial_emit
   laf x6, hook_emit
   sw x5, 0(x6)

   la x5, serial_qemit
   laf x6, hook_qemit
   sw x5, 0(x6)

   la x5, serial_key
   laf x6, hook_key
   sw x5, 0(x6)

   la x5, serial_qkey
   laf x6, hook_qkey
   sw x5, 0(x6)

   la x5, nop_vektor
   laf x6, hook_pause
   sw x5, 0(x6)

.endm

