;eventV_handler
;--------------
;Watches for keys being pressed and schedules disc changes
;ref PRM1-158 for event and key values
;
;Entry:
; R0 - event (11 for key press/release)
; R1 - 0 key released or for 1 key pressed
; R2 - key
; R3 - keyboard driver ID
; R12 - VARS pointer

.eventV_handler
 TEQ     R0, #11
 MOVNE   PC, R14

 STMFD   R13!, {R0-R4, R14}

 LDR     R0, _keystate
 TEQ     R2, #&61			;CTRL
 TEQNE   R2, #&3B
 BNE     _not_CTRL

#if compile_RO == 311
 MOV     R4, PC				;on RO3.11 switch to SVC and save state
 ORR     R3, R4, #%11
 TEQP    R3, #0
 NOP
 STR     R14, [R13, #-4]!
#endif
#if compile_RO > 311
 MRS     R4, CPSR			;on RO3.5+ switch to SVC and save state
 ORR     R3, R4, #%11
 MSR     CPSR_all, R3
 NOP
 STR     R14, [R13, #-4]!
 MRS     R14, SPSR
 STR     R14, [R13, #-4]!
#endif

 TEQ     R1, #1				;key down?
 BNE     _CTRL_up			;NO

 ORR     R0, R0, #%01
 MOV     R3, R0
 SWI     XOS_ReadMonotonicTime		;get the current time
 STR     R0, _time

 MOV     R0, #196			;read the keyboard repeat rate
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-904

 LDR     R0, _time			;add the repeat rate to time
 ADD     R0, R0, R2
 STR     R0, _time
 MOV     R0, R3
 BNE     _CTRL_up

#if compile_RO == 311
 LDR     R14, [R13], #4
 TEQP    R4, #0
 NOP
#endif
#if compile_RO > 311
 LDR     R14, [R13], #4
 MSR     SPSR_all, R14
 LDR     R14, [R13], #4
 MSR     CPSR_all, R4
 NOP
#endif
 B       _CTRL

 ._CTRL_up
 MOV     R3, R0
 SWI     XOS_ReadMonotonicTime		;get the current time

#if compile_RO == 311
 LDR     R14, [R13], #4
 TEQP    R4, #0
 NOP
#endif
#if compile_RO > 311
 LDR     R14, [R13], #4
 MSR     SPSR_all, R14
 LDR     R14, [R13], #4
 MSR     CPSR_all, R4
 NOP
#endif

 LDR     R14, _time

 CMP     R0, R14			;has enough time passed?
 MOV     R0, R3
 BLO     _exit				;NO, ignore key-up

 BIC     R0, R0, #%01
 B      _CTRL

 ._not_CTRL
 TEQ     R2, #&58			;SHIFT
 TEQNE   R2, #&4C
 BICEQ   R0, R0, #%10
 ORREQ   R0, R0, R1, LSL #1

 ._CTRL
 STR     R0, _keystate
 TEQ     R0, #%11
 TEQEQ   R1, #1				;key down?
 BNE     _exit				;NO

#if use_overlay == 1 AND JIT_debug == 1
 TEQ     R2, #&3E			;D
 BEQ     _debug_overlay
#endif

 TEQ     R2, #&21
 TEQNE   R2, #&36			;Page Down?
 BEQ     _alter_frame_rate		;YES, alter frame rate

 TEQ     R2, #&0A			;F10
 BEQ     _stop_recording		;YES, we need to stop the recording

#if compile_RO > 311
 TEQ     R2, #&0C			;F12
 BEQ     _quit_to_desktop		;YES, quit to desktop

 TEQ     R2, #&39			;up arrow
 BEQ     _volume_up
#endif

 TEQ     R2, #&62			;left arrow
 TEQNE   R2, #&63			;down arrow
 TEQNE   R2, #&64			;right arrow
 BEQ     _mono_or_stereo

 TEQ     R2, #0				;ESC
 BEQ     _exit				;YES, exit
 CMP     R2, #&09			;F1-F9
 BHI     _exit				;NO, exit

 LDRB    R0, [R12, #disk_swap_pending - VARS]
 TEQ     R0, #0				;are we dealing with a disc change?
 ADDEQ   R2, R2, #ASC("1") - 1		;convert key to ASCII "1" to "9"
 STREQB  R2, [R12, #disk_swap_pending - VARS]	;NO, store disc number

._exit_claimed
LDMFD   R13!, {R0-R4, R14, PC}		;claim the event

._exit
LDMFD   R13!, {R0-R4, PC}

 ._keystate DCD 0
 ._time     DCD 0


#if use_overlay == 1 AND JIT_debug == 1
._debug_overlay
 ADR     R0, debug_overlay_on
 LDR     R2, [R0, #0]
 EOR     R2, R2, #1
 STR     R2, [R0, #0]
 B       _exit_claimed
#endif


._alter_frame_rate
 TEQ     R2, #&36			;up or down?

 LDRB    R14, [R12, #force_vsync - VARS]
 BNE     _up
 SUBS    R14, R14, #1			;Down
 MOVMI   R14, #0			;fix if negative
 B       _alter_frame_rate_exit

 ._up
 ADD     R14, R14, #1			;NO, must be up
 CMP     R14, #20
 MOVHI   R14, #20			;cap to 20

 ._alter_frame_rate_exit
 STRB    R14, [R12, #force_vsync - VARS]
B       _exit_claimed


#if compile_RO > 311
._quit_to_desktop
 BL      check_and_return_taskID	;is this a task we support?
 BNE     _exit				;NO
 TEMP    R1
 STR     R0, terminate_task		;YES, mark for termination
 LOCK    R1
 B       _exit_claimed
#endif


;stop_recording
;--------------
;Stop recording DiscOp's and saves the file

;Entry:
; R12 - pointer to VARS

._stop_recording
#if Recording_immediate == 0
 LDR     R0, [R12, #recording_addr - VARS]
 TEQ     R0, #0				;are we actually recording?
 ADRNE   R0, Entry_ADFStop		;NO, setup callback to stop recording
 MOVNE   R1, R12			; |  R12 value
 MOVNE   R12, #1			; |  force CallBack
 SWINE   XOS_AddCallBack		; |+ PRM1-324
#else
 MOV     R0, #0
 STR     R0, [R12, #recording_addr - VARS]
#endif
B       _exit_claimed



;_mono_or_stereo
;---------------
;force audio to left/right channel or normal stereo

._mono_or_stereo
#if compile_RO == 311
 MOV     R4, PC				;on RO3.11 switch to SVC and save state
 ORR     R3, R4, #%11
 TEQP    R3, #0
 NOP
 STR     R14, [R13, #-4]!
#endif
#if compile_RO > 311
 MRS     R4, CPSR			;on RO3.5+ switch to SVC and save state
 ORR     R3, R4, #%11
 MSR     CPSR_all, R3
 NOP
 STR     R14, [R13, #-4]!
 MRS     R14, SPSR
 STR     R14, [R13, #-4]!
#endif

 CMP     R2, #&63			;down arrow
 MOVLO   R1, #-127			;left channel
 MOVEQ   R1, #0
 MOVHI   R1, #127			;right channel

 STRB    R1, [R12, #force_mono - VARS]	;store current status
 ADD     R3, R12, #stereo_position - VARS	;current stereo positions
 MOV     R0, #7
 ._mono_stereo_L1
   LDRB    R1, [R3, R0]			;get previous stereo position
   ADD     R0, R0, #1			;correct as channels are 1..8
   SWI     XSound_Stereo		;PRM4-22
   SUBS    R0, R0, #2
 BPL      _mono_stereo_L1

#if compile_RO > 311
 TEQ     R2, #&63			;down arrow
 BLEQ    _volume_down
#endif

#if compile_RO == 311
 LDR     R14, [R13], #4
 TEQP    R4, #0
 NOP
#endif
#if compile_RO > 311
 LDR     R14, [R13], #4
 MSR     SPSR_all, R14
 LDR     R14, [R13], #4
 MSR     CPSR_all, R4
 NOP
#endif
B       _exit_claimed


#if compile_RO > 311
._volume_down
 ADR     R1, sound_volume
 LDR     R0, [R1]
 ADD     R0, R0, #1
 CMP     R0, #8
 MOVHI   R0, #8
 STR     R0, [R1]
 MOV     PC, R14

._volume_up
 ADR     R1, sound_volume
 LDR     R0, [R1]
 SUBS    R0, R0, #1
 MOVMI   R0, #0
 STR     R0, [R1]
 B       _exit_claimed
#endif




;claim_EventV
;------------
;Claims the EventV vector, so we can detect key presses

;Entry:
; R12 - pointer to VARS

.claim_EventV
 STMFD   R13!, {R0-R2, R14}

 MOV     R0, #14			;enable key event
 MOV     R1, #11			;PRM1-147
 SWI     XOS_Byte			;PRM1-152
 MOV     R0, #Vector_EventV		;PRM1-78
 ADR     R1, eventV_handler
 MOV     R2, R12
 SWI     XOS_Claim			;PRM1-66
LDMFD   R13!, {R0-R2, PC}




;reclaim_EventV
;--------------
;Reclaims the EventV vector, ensuring we're at the top of the queue
;(fixes CTRL-SHIFT-F12 in Chequered Flag and The Last Ninja
; and disk swapping in The Crystal Maze)

;Entry: in SVC26 on ARM2/3 and SVC32 on ARM600+

.reclaim_EventV
 STMFD   R13!, {R0-R2, R14}

 MOV     R0, #Vector_EventV		;PRM1-78
 ADR     R1, eventV_handler
 ADR     R2, VARS
 BL      pass_SWI_on			;call SWI that follows
 SWI     XOS_Claim			;PRM1-66
LDMFD   R13!, {R0-R2, PC}




;release_EventV
;--------------

;Entry:
; R12 - pointer to VARS

.release_EventV
 STMFD   R13!, {R0-R2, R14}

 MOV     R0, #13			;disable key event
 MOV     R1, #11			;PRM1-147
 SWI     XOS_Byte			;PRM1-150
 MOV     R0, #Vector_EventV		;PRM1-78
 ADR     R1, eventV_handler
 MOV     R2, R12
 SWI     XOS_Release			;PRM1-66
LDMFD   R13!, {R0-R2, PC}
