.outputHex
 STMFD   R13!, {R0-R3, R14}

 MOV     R2, #28
 .outputHex_MainLoop
   MOV     R3 ,R1, LSR R2
   AND     R3, R3, #&F
   CMP     R3, #&A
   ADDHS   R0, R3, #ASC("A")-10
   ADDLO   R0, R3, #ASC("0")
   SWI     XOS_WriteC

   SUBS    R2, R2, #4
 BHS     outputHex_MainLoop
LDMFD   R13!, {R0-R3, PC}




.outputHexByte
 STMFD   R13!, {R0-R3, R14}
B       outputHex_MainLoop




.outputHexTruncated
 STMFD   R13!, {R0-R3, R14}

 MOV     R2, R1
 BEQ     outputHex_MainLoop

 MOV     R2, #28
 ._L1
   MOVS    R3, R1, LSR R2
   SUBEQ   R2, R2, #4
 BEQ     _L1
B       outputHex_MainLoop






#if JIT_debug == 1
.debug_screen_addr	DCD 0		;offset from MEMC_Vinit of next CHR
.debug_screen_1_line	DCD 0
.debug_screen_1_CHR	DCD 0
.debug_screen_8_lines	DCD 0
.debug_screen_next_line	DCD 0
.debug_screen_next_CR	DCD 0

.debug_writeDecimal
 STMFD   R13!, {R2-R3, R5-R8, R14}
 MOV     R14, R1
 MRS     R5, CPSR
 CMP     R0, #0
 MOVEQ   R0, #ASC("0")
 BLEQ    our_XOS_WriteC
 BEQ     _wd_end

 MOV     R1, #0
 STRB    R1, [R4, #-1]!
 RSBMI   R0, R0, #0

 MOV     R8,     #&00000099
 ORR     R8, R8, #&00009900
 ORR     R8, R8, #&00990000
 ORR     R8, R8, #&19000000
 ._wd_loop
   MOV     R7, R0
   MOV     R1, R8

   MOV     R6, R0, LSR #16
   MOV     R3, R1, LSR #16
   BIC     R0, R0, R6, LSL #16
   BIC     R1, R1, R3, LSL #16
   MUL     R2, R0, R1
   MUL     R1, R6, R1
   MUL     R0, R3, R0
   MUL     R3, R6, R3
   ADDS    R0, R0, R1
   ADDCS   R3, R3, #1 << 16
   ADDS    R2, R2, R0, LSL #16
   ADC     R3, R3, R0, LSR #16

   SUB     R2, R7, R3, LSL #3
   SUB     R2, R2, R3, LSL #1

   CMP     R2, #9
   SUBHI   R2, R2, #10
   ADDHI   R3, R3, #1
   ADD     R1, R2, #ASC("0")
   STRB    R1, [R4, #-1]!

   SUBS    R14, R14, #1		;end of buffer?
   BEQ     _wd_loop2		;YES
   MOVS    R0, R3
 BNE     _wd_loop
 CMP     R2, #9
 MOVHI   R1, #ASC("1")
 STRHIB  R1, [R4, #-1]!

 ._wd_loop2
   LDRB    R0, [R4], #1
   TEQ     R0, #0
   BLNE    our_XOS_WriteC
 BNE     _wd_loop2

 ._wd_end
 MSR     CPSR_f, R5
LDMFD   R13!, {R2-R3, R5-R8, PC}




.debug_outputHex
 STMFD   R13!, {R0-R3, R14}

 MOV     R2, #28
 .debug_outputHex_MainLoop
   MOV     R3 ,R1, LSR R2
   AND     R3, R3, #&F
   CMP     R3, #&A
   ADDHS   R0, R3, #ASC("A")-10
   ADDLO   R0, R3, #ASC("0")
   BL      our_XOS_WriteC

   SUBS    R2, R2, #4
 BHS     debug_outputHex_MainLoop
LDMFD   R13!, {R0-R3, PC}

.debug_outputHexByte
 STMFD   R13!, {R0-R3, R14}
B       debug_outputHex_MainLoop




.debug_outputHexTruncated
 STMFD   R13!, {R0-R3, R14}

 MOVS    R2, R1
 BEQ     debug_outputHex_MainLoop

 MOV     R2, #28
 ._L1
   MOVS    R3, R1, LSR R2
   SUBEQ   R2, R2, #4
 BEQ     _L1

B       debug_outputHex_MainLoop




.our_VDU30
 STMFD   R13!, {R3-R5, R14}
 MOV     R3, #0
 STR     R3, debug_screen_addr			;0 moves to top/left of screen

 #if compile_IOMD == 1 AND JIT_debug == 1
   ADR     R3, vidc20_regs - (VIDC20_HCR << 2)
   LDR     R4, [R3, #VIDC20_HDSR << 2]
   LDR     R5, [R3, #VIDC20_HDER << 2]
   SUB     R4, R5, R4
   LDR     R3, current_screen_mode		;IOMD, use current bpp
   LDRB    R3, [R3, #6 * 4]			;R3 = bpp
 #endif
 #if compile_GPU == 1 AND JIT_debug == 1
   LDR     R4, HAL_vidc_list + (5 * 4)		;R4 = screen width
   ADD     R4, R4, #32 - 1			;screen is DIV 32 on Pi
   BIC     R4, R4, #32 - 1
   MOV     R3, #5				;Pi, use 32bpp
 #endif

 MOV     R5, #1
 MOV     R5, R5, LSL R3				;R5 = bytes for 1 CHR
 STR     R5, debug_screen_1_CHR
 #if compile_IOMD == 1 AND JIT_debug == 1
   RSB     R3, R3, #3
   MOV     R4, R4, LSR R3			;R4 = bytes for 1 line
 #endif
 #if compile_GPU == 1 AND JIT_debug == 1
   MOV     R4, R4, LSL #2
 #endif

 STR     R4, debug_screen_1_line
 STR     R4, debug_screen_next_line
 MOV     R4, R4, LSL #3				;add 8 lines
 STR     R4, debug_screen_8_lines
 STR     R4, debug_screen_next_CR
 LDMFD   R13!, {R3-R5, PC}




.our_XOS_NewLine
 STMFD   R13!, {R3, R14}
 LDR     R3, debug_screen_next_CR
 LDR     R14, debug_screen_1_line
 STR     R3, debug_screen_addr
 ADD     R14, R3, R14
 STR     R14, debug_screen_next_line
 LDR     R14, debug_screen_8_lines
 ADD     R14, R3, R14
 STR     R14, debug_screen_next_CR
LDMFD   R13!, {R3, PC}




.our_XOS_WriteS
 STMFD   R13!, {R0-R2}

 MRS     R2, CPSR
 #if compile_RO > 311 AND compile_RO < 450 AND JIT_debug == 1
   BIC     R1, R14, #&FC000003		;26bit, clear flags
 #endif
 #if compile_RO > 400 AND JIT_debug == 1
   MOV     R1, R14
 #endif
 ._L1
   LDRB    R0, [R1], #1
   TEQ     R0, #0
   BLNE    our_XOS_WriteC
 BNE     _L1

 ADD     R14, R1, #%11
 BIC     R14, R14, #%11
 MSR     CPSR_f, R2
 LDMFD   R13!, {R0-R2}
MOV     PC, R14




;our_XOS_WriteN
;--------------
;print string at pointer
;
;Entry:
; R1 - pointer to string
; R2 - string length

.our_XOS_WriteN
 STMFD   R13!, {R0-R3, R14}

 MRS     R3, CPSR
 ._L1
   SUBS    R2, R2, #1
   LDRPLB  R0, [R1], #1
   BLPL    our_XOS_WriteC
 BPL     _L1

 ADD     R14, R1, #%11
 BIC     R14, R14, #%11
 MSR     CPSR_f, R3

LDMFD   R13!, {R0-R3, PC}




;our_XOS_WriteC
;--------------
;print a char direct to screen memory
;
;Entry:
; R0 - char

.our_XOS_WriteC						;PRESERVES FLAGS
 STMFD   R13!, {R0-R6, R14}
 MRS     R5, CPSR				;R5 = CPU flags

 LDR     R1, debug_screen_addr
 LDR     R14, debug_screen_1_CHR
 LDR     R3, debug_screen_next_line
 ADD     R2, R1, R14
 CMP     R2, R3
 STRNE   R2, debug_screen_addr
 BLEQ    our_XOS_NewLine
 LDREQ   R2, debug_screen_addr

 #if compile_IOMD == 1 AND JIT_debug == 1
   LDR     R2, MEMC_Vinit			;IOMD, and below use DA2
 #endif
 #if compile_GPU == 1 AND JIT_debug == 1
   LDR     R4, current_GPU_bank
   ADR     R2, logical_VDU_start		;Pi, use GPU buffer
   LDR     R2, [R2, R4, LSL #2]
 #endif
 ADD     R1, R1, R2				;R1 = screen address

 SUB     R0, R0, #ASC(" ")			;go to char in table (CHR * 8)
 ADR     R2, charSet
 ADD     R2, R2, R0, LSL #3			;R2 = CHR

 LDR     R4, debug_screen_1_line		;R4 = bytes for 1 line

 MOV     R14, #8				;R14 = vloop

 #if compile_GPU == 1 AND JIT_debug == 1
   MOV     R3, #3				;Pi, use 8bpp
 #endif
 #if compile_IOMD == 1 AND JIT_debug == 1
   LDR     R3, current_screen_mode		;IOMD, use current bpp
   LDRB    R3, [R3, #6 * 4]			;R3 = bpp

   CMP     R3, #2
   BHI     _8bpp
   BEQ     _4bpp
   TEQ     R3, #0
   BNE     _2bpp

  ._1bpp
     LDRB    R0, [R2], #1
     STRB    R0, [R1], R4
     SUBS    R14, R14, #1
   BNE     _1bpp

  ._2bpp
   MSR     CPSR_f, R5
  LDMFD   R13!, {R0-R6, PC}


  ._4bpp
     LDRB    R0, [R2], #1
     MOV     R0, R0, LSL #23
     MOV     R3, #3
     ._4bpp_L1
       MOVS    R0, R0, LSL #2			;shift to top bit
       MOVCS   R6, #&80
       MOVCC   R6, #0
       ORRMI   R6, R6, #&08

       STRB    R6, [R1, R3]
       SUBS    R3, R3, #1
     BPL     _4bpp_L1
     ADD     R1, R1, R4
     SUBS    R14, R14, #1
   BNE     _4bpp

   MSR     CPSR_f, R5
  LDMFD   R13!, {R0-R6, PC}


  ._8bpp
     LDRB    R0, [R2], #1
     MOV     R0, R0, LSL #23
     MOV     R3, #7
     ._8bpp_L1
       MOV     R0, R0, LSL #1			;shift to top bit
       MOVS    R6, R0, ASR #31
;       #if debug_overlay == 1 AND compile_DEBUG == 1
;         STRNEB   R6, [R1, R3]
;       #endif
;       #if debug_overlay == 0 AND compile_DEBUG == 1
         STRB    R6, [R1, R3]
;       #endif
       SUBS    R3, R3, #1
     BPL     _8bpp_L1
     ADD     R1, R1, R4
     SUBS    R14, R14, #1
   BNE     _8bpp

   MSR     CPSR_f, R5
  LDMFD   R13!, {R0-R6, PC}
 #endif

 #if compile_GPU == 1 AND JIT_debug == 1
  ._32bpp
     LDRB    R0, [R2], #1
     MOV     R0, R0, LSL #23
     MOV     R3, #7 * 4
     ._32bpp_L1
       MOV     R0, R0, LSL #1			;shift to top bit
       MOV     R6, R0, ASR #31
       MOVS    R6, R6, LSR #8			;00BBGGRR
       #if debug_overlay == 1 AND compile_GPU == 1 AND JIT_debug == 1
         STRNE   R6, [R1, R3]
       #endif
       #if debug_overlay == 0 AND compile_GPU == 1 AND JIT_debug == 1
         STR     R6, [R1, R3]
       #endif
       SUBS    R3, R3, #4
     BPL     _32bpp_L1
     ADD     R1, R1, R4
     SUBS    R14, R14, #1
   BNE     _32bpp

   MSR     CPSR_f, R5
  LDMFD   R13!, {R0-R6, PC}
 #endif

.charSet
INCBIN "<Tmp$Dir>.debug.font"
ALIGN
#endif
