; >Debug
; StrongED$Mode = ObjAsm
; StrongED$WrapWidth = 96

        ; Condition code symbols

Cond_EQ *       0  :SHL: 28
Cond_NE *       1  :SHL: 28
Cond_CS *       2  :SHL: 28
Cond_HS * Cond_CS
Cond_CC *       3  :SHL: 28
Cond_LO * Cond_CC
Cond_MI *       4  :SHL: 28
Cond_PL *       5  :SHL: 28
Cond_VS *       6  :SHL: 28
Cond_VC *       7  :SHL: 28
Cond_HI *       8  :SHL: 28
Cond_LS *       9  :SHL: 28
Cond_GE *       10 :SHL: 28
Cond_LT *       11 :SHL: 28
Cond_GT *       12 :SHL: 28
Cond_LE *       13 :SHL: 28
Cond_AL *       14 :SHL: 28
Cond_   * Cond_AL
Cond_NV *       15 :SHL: 28

;--------------------------------------------------------------------------------
;DEF FN_Debug(pass%,A$)
;= FN_db(pass%,A$)

        MACRO
$label  FN_Debug  $cc,$str,$flags
;        [ DEBUG

        FN_db2     $cc,$str,$flags

;        ]
        MEND


;--------------------------------------------------------------------------------
        MACRO
$label  FN_db   $str,$flags
;        [ DEBUG
        LCLS    newcc
newcc   SETS    ""
	LCLS    ccstr
ccstr   SETS    "$str" :LEFT: 4
	[ ((ccstr :LEFT: 1) = "<") :LAND: ((ccstr :RIGHT: 1) = ">")
ccstr   SETS    ccstr :RIGHT: 3 :LEFT: 2 ; MID$(ccstr,2,2)
        [ ccstr = "eq"
newcc   SETS    "ne"
        ]
        [ ccstr = "ne"
newcc   SETS    "eq"
        ]
        [ ccstr = "cs" :LOR: ccstr = "hs"
newcc   SETS    "cc"
        ]
        [ ccstr = "cc" :LOR: ccstr = "lo"
newcc   SETS    "cs"
        ]
        [ ccstr = "mi"
newcc   SETS    "pl"
        ]
        [ ccstr = "pl"
newcc   SETS    "mi"
        ]
        [ ccstr = "vs"
newcc   SETS    "vc"
        ]
        [ ccstr = "vc"
newcc   SETS    "vs"
        ]
        [ ccstr = "hi"
newcc   SETS    "ls"
        ]
        [ ccstr = "ls"
newcc   SETS    "hi"
        ]
        [ ccstr = "ge"
newcc   SETS    "lt"
        ]
        [ ccstr = "lt"
newcc   SETS    "ge"
        ]
        [ ccstr = "gt"
newcc   SETS    "le"
        ]
        [ ccstr = "le"
newcc   SETS    "gt"
        ]
        ;]
        ! 2 - :LEN: newcc, "Unknown condition code"
        [ newcc <> ""
        B$newcc %FT01
        ]
        ]
        STMFD   R13,{R12,R13,LR,PC}             ; no r13 writeback to avoid problems
        BL      dbpf_Rep                        ; output format string with substitution
        B       %FT01                           ; branch over flags and format string
        DCD     $flags                          ; flags for Report_Registers SWI call
        DCSZA   $str                            ; format string goes here, (r14 + 8)
01
;        ]
        MEND


;--------------------------------------------------------------------------------
        MACRO
$label  FN_db2   $str,$cond,$flags
;        [ DEBUG
        STM$cond.FD   R13,{R12,R13,LR,PC}             ; no r13 writeback to avoid problems
        BL$cond       dbpf_Rep                        ; output format string with substitution
        B       %FT01                           ; branch over flags and format string
        DCD     $flags                          ; flags for Report_Registers SWI call
        DCSZA   $str                            ; format string goes here, (r14 + 8)
01
;        ]
        MEND


;-------------------------------------------------------------------------------
        MACRO
$label  dbpf_Rep
dbpf_Rep
        ;------ r14 is return address, r14 + 4 points to string to printf
        ;       old r12,r13,r14 are on stack, plus 'pc' above it

        SUB     R13,R13,#4*4                    ; adjust r13 manually for caller's stmfd
        STMFD   R13!,{R0-R12}                   ; keep the r0-r12 register values safe

        MRS     R9,CPSR                         ; keep 32-bit psr safe (nop on 26-bit)
        MOV     R8,R14                          ; return address (+psr if 26-bit)
        TEQ     R0,R0                           ; ready Z-flag for test below
        TEQ     PC,PC                           ; EQ if 32-bit, NE if 26-bit
        BICNE   R8,R14,#&FC000003               ; if 26-bit, remove flags from ptr
        ANDNE   R9,R14,#&FC000003               ; if 26-bit, isolate flags from ptr

        ;------- We need to construct, on the stack, the register save area required by
        ;        Report_Registers. This needs to look as follows; r0-r15,psr. Right now
        ;        we have r0-r12,r12-r15 (r12 is pushed twice so we have room for the psr).
        ;        We need to move r13-r15 down one word and add the psr at the end.

        ADD     R0,R13,#14*4                    ; -> r13,lr,pc
        ADD     R1,R13,#13*4                    ; -> r12,r13,lr,pc
        LDMIA   R0,{R2-R4}                      ; read r13,lr,pc
        STMIA   R1,{R2-R4,R9}                   ; write r13,lr,pc,psr

        ;------ Okay we have our register save area we can now call Report_Registers

        ADD     R0,R8,#8                        ; ptr -> string to printf
        MOV     R1,R13                          ; ptr -> register save area
        LDR     R2,[R8,#4]                      ; flags, b16 set => no pc/psr line
        SWI     XReport_Registers               ; get Reporter to parse & output string

        ;------ We need to restore the original psr content

        TEQ     R0,R0                           ; ready Z-flag for test below
        TEQ     PC,PC                           ; EQ if 32-bit, NE if 26-bit
        TEQNEP  R9,#&0                          ; if 26-bit, restore 26-bit psr
        MSR     CPSR_f,R9                       ; restore 32-bit psr (nop on 26-bit)

        ;------ Now restore the registers and return to caller

        STR     R8,[R13,#16*4]                  ; overwrite psr with return address
        LDMFD   R13!,{R0-R12}                   ; restore the r0-r12 register values
        LDR     R14,[R13,#4]                    ; restore the r14 register value
        ADD     R13,R13,#12                     ; skip over stacked r13,lr,pc
        LDMFD   R13!,{PC}                       ; return to caller

        MEND

;-------------------------------------------------------------------------------

        END
