;#if JIT_debug == 1 AND compile_IOMD == 1
;ZZZ
;  .report_JIT_IOMD_occurred DCD 0
;
;  .report_JIT_IOMD			;only report if OS_Byte 113 not called
;  STR     R14, [R13, #-4]!
;  LDR     R14, report_JIT_IOMD_occurred
;  TEQ     R14, #0
;  MOVNE   R14, #0
;  STRNE   R14, report_JIT_IOMD_occurred
;  LDRNE   PC, [R13], #4
;  LDR     R14, [R13], #4
;  ;fall-thru to report_JIT
;#endif

#if JIT_debug == 1
;report_JIT
;----------
;displays statistics from the JIT
;
;Exit:
; Registers preserved

.report_JIT_in_progress	DCD 0

.report_JIT
 #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 1
   STMFD   R13!, {R12, R14}
   LDR     R12, closest_screen_mode
   CMN     R12, #1			;are we blitting?
   #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 1 AND use_overlay == 0
     LDMEQFD R13!, {R12, PC}
   #endif
   #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 1 AND use_overlay == 1
     BNE     _keep_it
     BL      check_JIT_and_taskID	;NO, is the task mapped in?
     LDMNEFD R13!, {R12, PC}		;NO, exit
     ._keep_it
   #endif

   #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 1 AND use_overlay == 0
     ADR     R12, report_JIT_blitter_return
     EORS    R12, R12, R14
     LDRNE   R12, blit_in_progress
     TEQNE   R12, #0
     LDMNEFD R13!, {R12, PC}
   #endif
   STMFD   R13!, {R0-R11}
 #endif
 #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 0
   STMFD   R13!, {R0-R12, R14}
   #if JIT_debug == 1 AND compile_GPU == 1 AND JIT_report_immediate == 0 AND use_overlay == 1
     LDR     R12, closest_screen_mode
     CMN     R12, #1			;are we blitting?
     BNE     _keep_it
     BL      check_JIT_and_taskID	;NO, is the task mapped in?
     LDMNEFD R13!, {R0-R12, PC}		;NO, exit
     ._keep_it
   #endif
 #endif
 #if JIT_debug == 1 AND compile_IOMD == 1
   STR     R14, [R13, #-4]!
;   LDRB    R14, is_screen_remapped	;is the screen remapped?
   LDR     R14, current_screen_mode	;do we know the mode?
   TEQ     R14, #0
   LDREQ   PC, [R13], #4		;NO, exit

   LDR     R14, dbg_pause
   SUBS    R14, R14, #1
   STRPL   R14, dbg_pause
   LDRPL   PC, [R13], #4
   STMFD   R13!, {R0-R12}
 #endif

 LDR     R0, report_JIT_in_progress
 TEQ     R0, #0
 LDMNEFD R13!, {R0-R12, PC}
 #if JIT_debug == 1 AND use_overlay == 1
   BL      our_VDU16
   LDMEQFD R13!, {R0-R12, PC}		;exit if the debug overlay hasn't been created yet
 #endif
 STR     R13, report_JIT_in_progress
 MRS     R11, CPSR
 ORR     R0, R11, #%10 << 6		;disable IRQ
 MSR     CPSR_c, R0

 BL      our_VDU30			;go to top left of screen
 ADR     R12, VARS
 our_writeS  ""
 #if JIT_debug == 1 AND JIT_report_registers == 1
   our_writeS "R0       R1       R2       R3       R4       R5       R6       R7"
   our_writeS ""
   ADR     R0, DAV_r0
   MOV     R2, #16
   .report_registers_L1
     LDR     R1, [R0], #4
     our_writeD R1
     TEQ     R2, #9
     our_writeSEQ ""
     our_writeSNE " "
     SUBS    R2, R2, #1
   BNE     report_registers_L1
   our_writeS "R8       R9       R10      R11      R12      R13      R14      PC"
   our_writeS ""
   our_writeS ""
 #endif
 #if JIT_debug == 1 AND JIT_detailed_debug == 1
   BL      check_JIT_and_taskID
   BNE     report_JIT_skip_disassemble

   LDR     R0, jit_disassemble_last
   LDR     R1, jit_disassemble_last + 4

   MRS     R5, CPSR			;R5=entry CPU mode
   #if JIT_debug == 1 AND JIT_detailed_debug == 1 AND compile_RO == 400
     MSR     CPSR_c, #%10000011		;SVC26 IRQ disabled
   #endif
   #if JIT_debug == 1 AND JIT_detailed_debug == 1 AND compile_RO > 400
     MSR     CPSR_c, #%10010011		;SVC32 IRQ disabled
   #endif
   #if JIT_debug == 1 AND compile_IOMD == 1
     NOP
   #endif
   MRS     R6, SPSR			;preserve SVC SPSR and R14
   MOV     R7, R14

   SUB     R1, R1, #8			;correct for prefetch
   BL      pass_SWI_on
   SWI     XDebugger_Disassemble	;PRM4-225

   MOV     R14, R7
   MSR     SPSR_all, R6
   MSR     CPSR_c, R5			;back into entry CPU mode
   #if JIT_debug == 1 AND  compile_IOMD == 1
     NOP
   #endif

   MVN     R3, #0
   ._report_JIT_find_end		;find end or ";"
     ADD     R3, R3, #1
     LDRB    R0, [R1, R3]
     TEQ     R0, #ASC(";")
     TEQNE   R3, R2
   BNE     _report_JIT_find_end
					;R3 points to end of string or ";"
   TEQ     R0, #ASC(";")		;is there a ";"
   BNE     _report_JIT_no_work_back	;NO
   ._report_JIT_work_back		;YES, remove spaces
     LDRB    R0, [R1, R3]
     TEQ     R0, #ASC(" ")
     SUBEQ   R3, R3, #1
   BEQ     _report_JIT_work_back

   ._report_JIT_no_work_back		;R3=instruction end
   CMP     R3, #39
   MOVHI   R2, #39			;cap to 39 chars
   MOVLS   R2, R3			;or use new length

   our_writeN R1, R2			;display on screen

   LDR     R1, jit_disassemble_len	;previous instruction length
   STR     R2, jit_disassemble_len

   MOV     R0, #ASC(" ")		;blank previous instruction text
   .report_JIT_clear_L1
     CMP     R2, R1
     BLLO    our_XOS_WriteC		;overwrite old text with spaces
     ADD     R2, R2, #1
   BLT     report_JIT_clear_L1


   .report_JIT_skip_disassemble
 #endif
 our_writeS  ""
 LDR     R0, blitter_FPS
 our_writeDecimal R0, dbtext_buffer, 7
 our_writeS  "fps "
 LDR     R1, jit_prev_instrL		;penultimate entry instruction
 our_writeD_n  R1, 6
 our_writeS  " "
 LDR     R1, jit_last_instrR		;last instruction seen
 our_writeD_n  R1, 6

 our_writeS  " PC:"
 LDR     R0, user_PC			;last known PC

 MOV     R1, #jit_26bit_exits		;is it within a 26bit managed return
 LDR     R2, [R12, #jit_managed_ldr_pc_r13_2 - VARS]
 ADD     R2, R2, #jit_code_start
 CMP     R0, R2
 CMPHS   R1, R0
 BHI     _not_Abort_address		;YES
 
 LDR     R4, [R12, #first_codelet - VARS]
 CMP     R0, #lastfree_codelet		;above last codelet?
 CMPLO   R4, R0				;possibly, below first codelet?
 BHI     _not_codelet_address		;NO
					;an Abort occurred in a codelet
 BIC     R1, R0, #codelet_alignment - 1	;find codelet header
 #if JIT_debug == 1 AND (JIT_codelet_reuse == 0 AND Unaligned_Support == 0)
  ._aborted_codelet_L1
    LDR     R3, [R1, #-codelet_struct.codelet]!		;get .next value
    SUB     R3, R3, #jit_appspace_end
    CMP     R3, #jit_code_start - jit_appspace_end	;in codelet space?
  BHI     _aborted_codelet_L1
 #endif
 #if  JIT_debug == 1 AND (JIT_codelet_reuse == 1 OR Unaligned_Support == 1)
  ADD     R1, R1, #codelet_struct.validation
  MOV     R5, #CODELET_validation
  ._aborted_codelet_L1
    LDR     R3, [R1, #-codelet_struct.codelet]!		;get .next value
    CMP     R1, #jit_appspace_end			;check for codelet find fail
    BLO     _not_codelet_address
    TEQ     R3, R5					;EQ if codelet header
  BNE     _aborted_codelet_L1
  SUB     R1, R1, #codelet_struct.validation
 #endif
 LDR     R0, [R1, #codelet_struct.source]

 ._not_codelet_address
 SUB     R2, R0, #jit_code_start
 CMP     R2, #jit_appspace_end		;in JIT space?
 MOVLO   R0, R2				;YES, correct address
 ._not_Abort_address
 our_writeD R0

 LDR     R3, user_SPSR
 AND     R0, R3, #%1111
 ADD     R1, PC, R0, LSL #2
 B       _skip_CPU_modes
 DCB " USR FIQ IRQ SVC -4- -5- -6- ABT -8- -9- -A- UND -C- -D- -E- -F-"
 ._skip_CPU_modes
 MOV     R2, #4
 our_writeN R1, R2
 #if JIT_debug == 1 AND compile_IOMD == 1
   TST     R3, #%10000
   our_writeSEQ  "26"
 #endif

 TST     R3, #%10000000			;IRQ enabled?
 our_writeSNE " I"
 our_writeSEQ "  "
 TST     R3, #%01000000			;FIQ enabled?
 our_writeSNE "F "
 our_writeSEQ "  "

 LDR     R1, jit_code
 TEQ     R1, #0				;is the JIT running?
 BEQ     no_JIT1			;NO
 our_writeS  ""
 our_writeS  "A:"
 LDR     R0, jit_write_aborts
; our_writeD R0
 our_writeDecimal R0, dbtext_buffer, 7
 our_writeS  " >"
 LDR     R0, jit_entry_count
 our_writeDecimal R0, dbtext_buffer, 7
 our_writeS  " I:"
 LDR     R0, jit_instr_count
 our_writeDecimal R0, dbtext_buffer, 7
 our_writeS  " R:"
 LDR     R0, jit_instr_interpreted
 our_writeDecimal R0, dbtext_buffer, 7
 #if JIT_debug == 1 AND Unaligned_Support == 1
   LDR     R0, jit_unaligned
   TEQ     R0, #0
   BEQ     db_P1
   our_writeS  " U:"
   our_writeDecimal R0, dbtext_buffer, 7
   LDR     R1, jit_unaligned+8
   BL      core_debug_display_address
   LDR     R1, jit_unaligned+4
   our_writeS  " ("
   our_writeDT  R1
   our_writeS  ")"
   .db_P1
 #endif

 LDR     R0, jit_page_zero_aborts
 TEQ     R0, #0
 BEQ     db_P3
 our_writeS  " 0:"
 our_writeDecimal R0, dbtext_buffer, 7
 LDR     R1, jit_page_zero_aborts+8
 BL      core_debug_display_address
 LDR     R1, jit_page_zero_aborts+4
 our_writeS  " ("
 our_writeDT  R1
 our_writeS  ")"
 B       db_P4
 .db_P3
 our_writeS "    "
 .db_P4
 our_writeS  ""
 #if JIT_debug == 1 AND High_Vectors == 0
   our_writeS  "L:"
   LDR     R0, jit_LDR_interpreted
   our_writeDecimal R0, dbtext_buffer, 7
   our_writeS  " C:"
 #endif
 #if JIT_debug == 1 AND High_Vectors == 1
   our_writeS  "C:"
 #endif
 LDR     R1, jit_cache_flushes
 MOV     R0, R1, LSR #8			;complete cache flushes
 our_writeDecimal R0, dbtext_buffer, 7
 AND     R0, R1, #31			;cache line flushes
 ADD     R0, R0, #ASC("}") + 1
 BL      our_XOS_WriteC
 our_writeS  " "
 LDR     R1, screen_borders
 LDR     R0, [R12, #VIDC20_width - VARS]		;display width
 ADD     R3, R1, R1, LSL #8
 SUB     R0, R0, R3, LSR #24		;reduce by left/right border
 our_writeDecimal R0, dbtext_buffer, 7
 our_writeS  "x"
 LDR     R0, [R12, #VIDC20_height - VARS]		;display height
 AND     R3, R1, #&FF << 8
 SUB     R0, R0, R3, LSR #8		;reduce by top/bottom border
 our_writeDecimal R0, dbtext_buffer, 7
 LDRB    R1, [R12, #current_mode_bitdepth - VARS]	;get MODE bpp
 ADR     R0, _bpp_table
 LDRB    R0, [R0, R1]
 B       _skip_bpp_table
 ._bpp_table
 DCB     1,2,4,8,16,32,24,48
 ALIGN
 ._skip_bpp_table
 our_writeS  "x"
 our_writeDecimal R0, dbtext_buffer, 2
 #if JIT_debug == 1 AND compile_GPU == 1
   LDR     R0, monitor_hz
   our_writeS  " "
   our_writeDecimal R0, dbtext_buffer, 7
   our_writeS  "hz"
   .report_JIT_P4
 #endif
 our_writeS  " "
 LDR     R0, jit_joysticks			;PJSRA
 TST     R0, #%0001
 our_writeSNE "A"
 TST     R0, #%1000
 our_writeSNE "J"
 TST     R0, #%0100
 our_writeSNE "S"
 TST     R0, #%0010
 our_writeSNE "R"
 TST     R0, #%10000
 our_writeSNE "P"

 our_writeS  ""
 our_writeS  "LF:"
 MOV     R1, #lastfree_codelet
 LDR     R5, user_PC
 LDR     R6, user_SPSR
 LDR     R0, [R1, #codelet_struct.previous]	;this will trigger PMP and corrupt everything collected so far
 our_writeD_n  R0, 7
 our_writeS  " LC:"
 MOV     R1, #jit_appspace_end
 LDR     R2, [R1, #codelet_struct.size]
 STR     R5, user_PC
 STR     R6, user_SPSR
 ADD     R1, R1, R2
 our_writeD_n  R1, 7
 our_writeS  " #:"
 LDR     R1, jit_codelet_count
 MOV     R0, R1, LSR #8			;remove the recycle indicator
 our_writeDecimal R0, dbtext_buffer, 7
 AND     R0, R1, #31			;cache line flushes
 ADD     R0, R0, #ASC("}") + 1
 BL      our_XOS_WriteC

 our_writeS ""
 our_writeS "Vi:"
 LDR     R0, [R12, #MEMC_Vinit - VARS]
 our_writeD R0
 our_writeS " Vs:"
 LDR     R0, [R12, #MEMC_Vstart - VARS]
 our_writeD R0
 LDR     R0, [R12, #MEMC_Vend - VARS]
 CMN     R0, #129
 our_writeSNE " Ve:"
 our_writeDNE R0

 #if JIT_debug == 1 AND compile_GPU == 1
   our_writeS ""
   our_writeS "B:"
   LDR     R0, screen_borders
   our_writeD R0

   BL      task_page_zero_R3		;R3=Page Zero pointer
   LDR     R1, [R12, #hypervised_Undefined - VARS]
   LDR     R0, [R3, #page_zero_Undefined]	;Undefined vector
   TEQ     R0, R1			;was IRQv claimed?
   our_writeSNE " Undefined"
   LDR     R1, [R12, #hypervised_IRQ - VARS]
   LDR     R0, [R3, #page_zero_IRQ]	;IRQ vector
   TEQ     R0, R1			;was IRQ claimed?
   our_writeSNE " IRQ"
   LDR     R1, [R12, #hypervised_IRQ1V - VARS]
   LDR     R0, [R3, #page_zero_IRQ1V]
   TEQ     R0, R1			;was IRQ1V claimed?
   our_writeSNE " IRQ1V"

   ADD     R1, R12, #IOC_registers - VARS
   LDRB    R0, [R1, #IOC_IRQA_mask >> 2]
   LDRB    R3, [R1, #IOC_IRQB_mask >> 2]
   ADD     R2, R12, #DeviceVectors + device_table.entry_code - VARS

   LDR     R1, [R2, #IOC_VSync_Pulse * device_table.size]
   TEQ     R1, #0			;VSync claimed?
   TSTNE   R0, #1 << IOC_VSync_Pulse	;YES, is it active?
   our_writeSNE " VSync"		;YES

   LDR     R1, [R2, #IOC_Timer_0 * device_table.size]
   TEQ     R1, #0			;T0 claimed?
   our_writeSNE " T0"			;YES

   LDR     R1, [R2, #IOC_Timer_1 * device_table.size]
   TEQ     R1, #0			;T1 claimed?
   our_writeSNE " T1"			;YES

   LDR     R1, [R2, #IOC_SSBC * device_table.size]
   TEQ     R1, #0			;SSBC claimed?
   TSTNE   R3, #1 << (IOC_SSBC - 8)	;YES, is it active?
   our_writeSNE " SSBC"			;YES

   LDR     R0, T0_value
   TEQ     R0, #&10000000		;is it set?
   SUBNES  R1, R0, #20000		;is it the init value?
   our_writeSNE " T0:"			;YES
   our_writeDTNE R0
   our_writeSNE " "

   LDR     R0, T1_value
   TEQ     R0, #&10000000		;is it set?
   our_writeSNE " T1:"			;YES
   our_writeDTNE R0
   our_writeSNE " "
   LDRNE   R0, jit_T1_ticks
   our_writeDecimalNE R0, dbtext_buffer, 2
 #endif

 .no_JIT1
 MOV     R0, #0
 STR     R0, report_JIT_in_progress
 MSR     CPSR_c, R11
LDMFD   R13!, {R0-R12, PC}



;Entry: R1 - address
;Exit: all registers corrupt
.core_debug_display_address
 STMFD   R13!, {R14}		; figure out if its in a 26bit Module
 
 our_writeS  " @ "
 SUB     R9, R1, #jit_code_start		;R9=aborting address
 SUB     R2, R1, #jit_code_start+jit_RMA_heap
 CMP     R2, #jit_RMA_size
 BLO     cdda_in_rma				;its in the RMA
 CMP     R9, #jit_allocate_memory
 MOVLO   R1, R9					;its in Appspace
 our_writeDT  R1
 LDMFD   R13!, {PC}

 .cdda_in_rma
 MOV     R1, #0
 MOV     R2, #0					;instantiation number
 MOV     R0, #Module_ExtractInfo
 ._next_module
   SWI     XOS_Module				;PRM1-243
   BVS     cdda_P1				;no more Modules

   LDR     R4, [R3, #Module_Header.ADFFS]	;check it's one of ours
   EORS    R4, R4, #Module_Validation
   BNE     _next_module

   LDR     R4, [R3, #Module_Header.Address]	;get start and size
   LDR     R5, [R3, #Module_Header.Size]	;so we can kill vector claims

   SUB     R6, R9, R4
   CMP     R6, R5				;is it within the Module?
 BHI     _next_module

 our_writeS  "+"
 MOV     R1, R6
 our_writeDT R1
 our_writeS  " "
 LDR     R1, [R3, #Module_Header.Title]
 ADD     R1, R1, R3
 MOV     R2, #32
 our_writeN R1, R2
 LDMFD   R13!, {PC}

 .cdda_P1
 SUB     R1, R9, #jit_allocate_memory
 our_writeDT R1
 our_writeS  " in RMA"
LDMFD   R13!, {PC}


 .dbtext_buffer	DCB "9999999", 0
 ALIGN
 .jit_last_instrR	DCD 0
 .jit_prev_instrL	DCD 0
 .jit_instr_count	DCD 0
 .jit_instr_interpreted	DCD 0
 .jit_cache_flushes	DCD 0
 .jit_write_aborts	DCD 0,0,0
 .jit_page_zero_aborts	DCD 0,0,0
 #if JIT_debug == 1 AND Unaligned_Support == 1
   .jit_unaligned	DCD 0,0,0
 #endif
 .jit_codelet_count	DCD 0
 .jit_LDR_interpreted	DCD 0
 .jit_entry_count	DCD 0
 .jit_T1_ticks		DCD 0
 #if JIT_debug == 1 AND compile_IOMD == 1
   .dbg_pause		DCD dbg_pause_default
 #endif
 .user_PC		DCD 0
 .user_SPSR		DCD 0
 .screen_borders	DCD 0
 #if JIT_debug == 1 AND JIT_detailed_debug == 1
  .jit_disassemble_len	DCD 0		;length of the last inst.
  .jit_disassemble_last	DBD 2
 #endif
 .jit_joysticks		DCD 0		;PJSRA
#endif


#if JIT_debug == 1 AND JIT_trap_pz_code == 1
.JIT_page_zero_code
 LDMFD   R13!, {R0-R1}			;clear the stack
 STMFD   R13!, {R0-R7, R14}
 ADD     R14, R14, #8
 MOV     R1, #&1E			;ADFF501E
B       JIT_report_unimplemented_debug
#endif



;our_writeDecimal<CC> Rx, buffer, buffer_size
;output 123456
MACRO our_writeDecimal$cc n:R, buffer:I, size:I		;PRESERVES FLAGS
{
 STM$cc#FD R13!, {R0-R1, R4, R14}
 #if n <> 0
   MOV$cc    R0, n
 #endif
 MOV$cc    R1, #size
 ADR$cc    R4, buffer + size + 1
 BL$cc     debug_writeDecimal
 LDM$cc#FD R13!, {R0-R1, R4, R14}
}




;our_writeS<CC> string
;output - string or CR/LF if ""
MACRO our_writeS$cc s:S					;PRESERVES FLAGS
{
 #if LEN(s) == 0
   STR$cc  R14, [R13, #-4]!
   BL$cc   our_XOS_NewLine
   LDR$cc  R14, [R13], #4
 #endif
 #if LEN(s) == 1
   STM$cc#FD R13!, {R0, R14}
   MOV$cc  R0, #ASC(s)
   BL$cc   our_XOS_WriteC
   LDM$cc#FD R13!, {R0, R14}
 #endif
 #if LEN(s) > 1
   #if LEN(s) > 1 AND cc<>&E
     ADD$cc  PC, PC, #0
     ._start
     ADD     PC, PC, #_end - _start - 8
   #endif
   STR     R14, [R13, #-4]!
   BL      our_XOS_WriteS
   DCB     s, 0
   ALIGN
   LDR     R14, [R13], #4
   ._end
 #endif
}




;our_writeN<CC> addr, length
;output - string
MACRO our_writeN$cc addr:R, len:R			;PRESERVES FLAGS
{
   #if cc<>&E
     ADD$cc  PC, PC, #0
     ._start
     ADD     PC, PC, #_end - _start - 8
   #endif
   STMFD   R13!, {R1-R2, R14}
   #if addr <> 1
     MOV     R1, addr
   #endif
   #if len <> 2
     MOV     R2, len
   #endif
   BL      our_XOS_WriteN
   LDMFD   R13!, {R1-R2, R14}
   ._end
}





;our_writeB<CC> Rx
;output FF
MACRO our_writeB$cc n:R					;PRESERVES FLAGS
{
 STM$cc#FD R13!, {R1-R2}
 #if n <> 1
   MOV$cc    R1, n
 #endif

 MOV$cc    R2, #4
 BL$cc     debug_outputHexByte
 LDM$cc#FD R13!, {R1-R2}
}





;our_writeD<CC> Rx
;output FFFFFFFF
MACRO our_writeD$cc n:R					;PRESERVES FLAGS
{
 #if n <> 1
   STR$cc  R1, [R13, #-4]!
   MOV$cc  R1, n
 #endif

 BL$cc   debug_outputHex

 #if n <> 1
   LDR$cc  R1, [R13], #4
 #endif
}





;our_writeDT<CC> Rx
;output Double with leading 0's removed
MACRO our_writeDT$cc n:R				;PRESERVES FLAGS
{
 #if n <> 1
   STR$cc  R1, [R13, #-4]!
   MOV$cc  R1, n
 #endif

 BL$cc   debug_outputHexTruncated

 #if n <> 1
   LDR$cc  R1, [R13], #4
 #endif
}




;our_writeD_n<CC> Rx, N
;output N chars of Rx
MACRO our_writeD_n$cc n:R s:I				;PRESERVES FLAGS
{
 STM$cc#FD R13!, {R1-R2, R14}
 #if n <> 1
   MOV$cc     R1, n
 #endif
 MOV$cc    R2, #(s << 2) - 4
 BL$cc     debug_outputHexByte
 LDM$cc#FD R13!, {R1-R2, R14}
}
