;References:
;swi - vector_handler_forward

;os_byte_113
;-----------
;Write display hardware screen bank
;forces VSyncs if required
;
;Exit:
; R2 - corrupt

.os_byte_113
 #if compile_GPU == 1
   LDR     R12, vsync_trigger_enabled	;are we generating VSync
 #else
   LDR     R12, force_vsync		;are we forcing VSyncs?
 #endif
 TEQ     R12, #0
 BEQ     vector_handler_forward		;NO, pass to OS

 ADR     R12, _SPSR			;buffer for C/SPSR (pre_swi_veneer)

 #if compile_GPU == 1
   BL      pre_SWI_veneer		;call SWI that follows
   SWI     XOS_Byte
   BL      post_SWI_veneer
   STR     R1, _tmp_R1			;preserve R1

   #if compile_GPU == 1 AND JIT_debug == 1
     LDR     R0, [R12, #0]
     MSR     SPSR_all, R0		;ensure JIT debug reports CPU mode
   #endif

   #if PLL_vsync == 0
     LDR     R14, vsync_trigger_enabled
     TEQ     R14, #0			;are we triggering VSyncs?
     BEQ     _GPU_50hz
     SWI     XOS_ReadMonotonicTime
     LDR     R14, force_vsync
     TEQ     R14, #0			;are we forcing VSyncs?
     ADDNE   R0, R0, R14		;YES
     SUBNE   R0, R0, #1			; |+ correct value
     ADDEQ   R0, R0, #4 * 2		;NO, force frame update in 4 frames
     TEMP    R14
     STR     R0, force_dirty_at
     LOCK    R14

     BL      blit_DA2_frame		;force a frame blit
     ._GPU_50hz
   #endif

   #if compile_GPU == 1 AND JIT_debug == 1 AND PLL_vsync == 1
     ADR     R14, blitter_counter	;increase the FPS counter
     LDR     R0, [R14, #0]
     ADD     R0, R0, #1
     STR     R0, [R14, #0]
   #endif

   LDR     R0, force_vsync
   TEQ     R0, #0			;are we forcing VSyncs?
   BEQ     _P1				;NO, exit

   LDR     R0, os_byte_19_happened
   TEQ     R0, #0			;do we need to frame pace?
   MOVEQ   R0, #19			;YES, force a VSync to add delay
   SWIEQ   XOS_Byte
 #else
   STR     R1, _tmp_R1			;preserve R1
   LDR     R2, os_byte_19_happened	;do we need to force a Vsync?
   TEQ     R2, #0
   BEQ     _delay_frame_change		;YES, don't change frame until end

					;we've seen a VSync, so change frame
					;immediately
   BL      pre_SWI_veneer		;call SWI that follows
   SWI     XOS_Byte
   BL      post_SWI_veneer
   STR     R1, _tmp_R1			;preserve R1
   B       _P1

   ._delay_frame_change			;not seen a VSync since the last
   MOV     R0, #19			;force a VSync
   BL      hv_pre_SWI_veneer		;call SWI that follows
   SWI     XOS_Byte			;wait for next VSync

   MOV     R0, #113			;change frames
   LDR     R1, _tmp_R1			;preserve R1
   BL      pass_SWI_on
   SWI     XOS_Byte			;do the frame change
   BL      post_SWI_veneer
   STR     R1, _tmp_R1			;preserve R1
 #endif
 ._P1
 #if compile_IOMD == 1
   BL      get_screen_start
   #if compile_IOMD == 1 AND JIT_debug == 1
     TEMP    R0
     STR     R14, report_JIT_IOMD_occurred
     LOCK    R0
     BL      report_JIT
   #endif
 #endif

 MOV     R0, #0
 STR     R0, os_byte_19_happened	;look for a vsync
 LDR     R1, _tmp_R1			;preserve R1
 MOV     R0, #113			;preserve R0
B       exit_SWI_veneer

 ._tmp_R1			DCD 0
 ._SPSR				DBD 4
