; > &.Hdr.NdrDebug
;

OldOpt  SETA    {OPT}
        OPT     OptNoList+OptNoP1List

; ***********************************
; ***    C h a n g e   L i s t    ***
; ***********************************

; Date       Name  Description
; ----       ----  -----------
;
; 25-Sep-89  NDR   First version written
;  3-May-90  NDR   File debugging added
; 30-Aug-90  NDR   Changed so if file can't be opened, no debugging is output
;  1-Nov-90  NDR   Neil_NewLine flushes data to file
;  6-Nov-90  NDR   Neil_NewLine also puts out end-of-file marker and resets PTR
;  2-Jan-91  NDR   Ensure Debug macro still works if V set on entry
;  3-Jan-91  NDR   Ensure debug_flush deals correctly when no debug output
;  4-Jan-91  NDR   Preserve R2 in Neil_Write0 and Neil_Newline
; 10-Apr-91  OSS   Changed all macros, particularly InsertNDRDebugRoutines,
;                  to not put any code in if the debug flag is not set. This
;                  is because too many modules are cocking things up and
;                  are putting debugging code into the ROM!

        GBLL    debug
        GBLL    debug_flush
        GBLL    true
        GBLL    false

true    SETL    1=1
false   SETL    1=0

debug_flush     SETL    false   ; default - can be altered before InsertNDRDebugRoutines


; NB: All s preserve the flags and all registers.
;     However, they do require the stack to be set up.

        MACRO
$lab    Debug_Open $filename
$lab
      [ debug
        Push    "R1,LR"
        ADR     R1, %FT00
        BL      Neil_OpenFile
        B       %FT01
00
        DCB     "$filename", 0
        ALIGN
01
        Pull    "R1,LR"
      ]
        MEND

        MACRO
$lab    Debug_Close
$lab
      [ debug
        Push    "LR"
        BL      Neil_CloseFile
        Pull    "LR"
      ]
        MEND

        MACRO
        Debug1  $dbg,$string
      [ debug$dbg
        Debug   $dbg,"$string"
      ]
        MEND

        MACRO
        Debug2  $dbg,$p1,$p2,$p3,$p4,$p5,$p6,$p7
      [ debug$dbg
        Debug   $dbg,"",$p1,$p2,$p3,$p4,$p5,$p6,$p7
      ]
        MEND

        MACRO
        Debug2a $dbg,$p1,$p2,$p3,$p4,$p5,$p6,$p7
      [ debug$dbg
        Debuga  $dbg,"",$p1,$p2,$p3,$p4,$p5,$p6,$p7
      ]
        MEND

        MACRO
        DebugS  $dbg,$string,$reg,$max
      [ debug:LAND:debug$dbg
        Push    "R0-R12,LR,PC"
      [ hostvdu
        BL      Neil_HostVdu
      ]
        ADR     R0, %FT00
        BL      Neil_Write0
        B       %FT01
00
        DCB     "$string",0
        ALIGN
01
        MOV     R0,#"'"
        BL      Neil_WriteC
      [ $reg > sp
        LDR     R0,[sp,#:INDEX:$reg * 4 - 4]    ; R13 is not stacked
      |
        LDR     R0,[sp,#:INDEX:$reg * 4]
      ]
      [ "$max"=""
        BL      Neil_Write0
      |
        MOV     R2,#$max
        BL      Neil_Write0_R2max
      ]
        MOV     R0,#"'"
        BL      Neil_WriteC
        BL      Neil_NewLine
      [ hostvdu
        BL      Neil_TubeVdu
      ]
        Pull    "R0-R12"
        LDR     LR,[sp,#4]
        TEQP    LR,#0                   ; restore flags
        LDR     LR,[sp],#8              ; correct stack
      ]
        MEND

        MACRO
        Debug   $dbg,$string,$p1,$p2,$p3,$p4,$p5,$p6,$p7
      [ debug:LAND:debug$dbg
        Push    "R0-R12,LR,PC"
      [ hostvdu
        BL      Neil_HostVdu
      ]
        ADR     R0, %FT00
        BL      Neil_Write0
        B       %FT01
00
        DCB     "$string",0
        ALIGN
01
      [ "$p1"<>""
        Dreg    $p1
      ]
      [ "$p2"<>""
        Dreg    $p2
      ]
      [ "$p3"<>""
        Dreg    $p3
      ]
      [ "$p4"<>""
        Dreg    $p4
      ]
      [ "$p5"<>""
        Dreg    $p5
      ]
      [ "$p6"<>""
        Dreg    $p6
      ]
      [ "$p7"<>""
        Dreg    $p7
      ]
        BL      Neil_NewLine
      [ hostvdu
        BL      Neil_TubeVdu
      ]
        Pull    "R0-R12"
        LDR     LR,[sp,#4]
        TEQP    LR,#0                   ; restore flags
        LDR     LR,[sp],#8              ; correct stack
      ]
        MEND

        MACRO
        Debuga  $dbg,$string,$p1,$p2,$p3,$p4,$p5,$p6,$p7
      [ debug:LAND:debug$dbg
        Push    "R0-R12,LR,PC"
      [ hostvdu
        BL      Neil_HostVdu
      ]
        ADR     R0, %FT00
        BL      Neil_Write0
        B       %FT01
00
        DCB     "$string",0
        ALIGN
01
      [ "$p1"<>""
        Dreg    $p1
      ]
      [ "$p2"<>""
        Dreg    $p2
      ]
      [ "$p3"<>""
        Dreg    $p3
      ]
      [ "$p4"<>""
        Dreg    $p4
      ]
      [ "$p5"<>""
        Dreg    $p5
      ]
      [ "$p6"<>""
        Dreg    $p6
      ]
      [ "$p7"<>""
        Dreg    $p7
      ]
      [ hostvdu
        BL      Neil_TubeVdu
      ]
        Pull    "R0-R12"
        LDR     LR,[sp,#4]
        TEQP    LR,#0                   ; restore flags
        LDR     LR,[sp],#8              ; correct stack
      ]
        MEND

        MACRO
        Dreg    $reg
 [ debug
     [ "$reg":LEFT:1 = "#"
        LCLS    locn
locn    SETS    "$reg":RIGHT:(:LEN:"$reg"-1)
      [ :BASE:($locn) = sp
        LDR     R0,$locn + 15*4         ; allow for 15 stacked registers
      |
        LDR     R0,$locn
      ]
     |
      [ $reg > sp
        LDR     R0,[sp,#:INDEX:$reg * 4 - 4]    ; R13 is not stacked
      |
        LDR     R0,[sp,#:INDEX:$reg * 4]
      ]
     ]
        BL      Neil_ConvertHex8
 ] ; End debug
        MEND

        MACRO
$lab    DebugE  $dbg,$mess
      [ debug:LAND:debug$dbg
$lab    BVC     %ft0
        ADD     R0,R0,#4
        DebugS  $dbg,"$mess",R0
        SUB     R0,R0,#4
0
      ]
        MEND

        MACRO
        InsertNDRDebugRoutines
 [ debug

Neil_ConvertHex8                        ; prints number in R0
        Push    "R0,LR"
;
        MOV     R0, #" "
        BL      Neil_WriteC
        Pull    "R0"
        SUB     sp,sp,#12
        MOV     R1,sp
        MOV     R2,#9                   ; includes room for terminator
        SWI     XOS_ConvertHex8
        ADDVS   R0,R0,#4                ; print error message if there was one
        BL      Neil_Write0
        ADD     sp,sp,#12
;
        Pull    "PC"

Neil_HostVdu
        Push    "LR"

        ADR     R0,%FT01
        SWI     XOS_CLI
        SWI     XOS_WriteI+4              ; VDU 4 mode in case no HostVdu

        Pull    "PC",,^
01
        DCB     "HostVdu",0
        ALIGN

Neil_TubeVdu
        Push    "LR"

        ADR     R0,%FT01
        SWI     XOS_CLI

        Pull    "PC",,^
01
        DCB     "TubeVdu",0
        ALIGN

Neil_Write0
        Push    "R2,LR"
        MOV     R2,#&10000000   ; no limit on string length
        BL      Neil_Write0_R2max
        Pull    "R2,PC",,^

Neil_Write0_R2max
        Push    "R0,LR"
        MOV     R1,R0           ; R1 -> string, R2 = max length (unsigned)
01      LDRB    R0,[R1],#1
        CMP     R0,#32          ; terminate on any ctrl-char
        SUBCSS  R2,R2,#1
        BLCS    Neil_WriteC
        BCS     %BT01
02
        Pull    "R0,PC",,^

Neil_WriteC
        Push    "R0,R1,LR"
        LDR     R1, Neil_FileHandle
        CMP     R1, #0          ; 0 => writec, -1 => none, >0 => file
        SWIEQ   XOS_WriteC
        SWIGT   XOS_BPut
        Pull    "R0,R1,PC",,^

Neil_NewLine
        Push    "R0-R2,LR"
        LDR     R14, Neil_FileHandle
        CMP     R14, #0
        MOVEQ   R0, #13                 ; only write CR if not to a file
        BLEQ    Neil_WriteC
        MOV     R0, #10
        BL      Neil_WriteC
      [ debug_flush
        LDR     R1, Neil_FileHandle     ; ensure bytes to the media after each line
        CMP     R1, #0
        BLE     %FT00
        MOV     R0, #"E"
        BL      Neil_WriteC
        MOV     R0, #"O"
        BL      Neil_WriteC
        MOV     R0, #"F"
        BL      Neil_WriteC
        MOV     R0, #255                ; ensure bytes to media
        SWI     XOS_Args
        MOV     R0, #0                  ; read PTR in R2
        SWI     XOS_Args
        SUB     R2,R2,#3
        MOV     R0, #1                  ; write PTR in R2
        SWI     XOS_Args
00
      ]
        Pull    "R0-R2,PC",,^

Neil_OpenFile
        Push    "R0-R1,LR"
        MOV     R0, #&8C                ; open for output
        SWI     XOS_Find                ; should warn you!
        MOVVS   R0,#-1                  ; -1 => no file debugging
        STR     R0, Neil_FileHandle
        Pull    "R0-R1,PC",,^

Neil_CloseFile
        Push    "R0-R1,LR"
        MOV     R0, #0                  ; close file
        LDR     R1, Neil_FileHandle
        CMP     R1, #0
        STRGT   R0, Neil_FileHandle     ; back to writec debugging
        SWIGT   XOS_Find
        Pull    "R0-R1,PC",,^

Neil_FileHandle DCD     0               ; default state => writec debugging

 ] ; End debug

        MEND

        END
