;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

.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

 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

;@@@ for debugging purposes
#if JIT_debug == 1
 TEQ     R2, #&0B			;F11
 BLEQ    reset_appspace_L2PT		;YES, make appspace read/write
; BEQ     toggle_recording		;YES, toggle recording
; BEQ     _force_exit			;YES, force exit to OS
#endif

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

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

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

 ADR     R4, disk_swap_pending
 LDRB    R0, [R4, #0]
 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, [R4, #0]			;NO, store disc number

 ._exit_claimed
 LDMFD   R13!, {R0-R4, R14}
LDR     PC, [R13], #4			;claim the event

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

 ._keystate DCD 0
 ._time     DCD 0


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

 LDR     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
 STR     R14, [R12, #force_vsync - VARS]
B       _exit_claimed


#if compile_RO > 311
._quit_to_desktop
 LDR     R0, [R12, #jit_code - VARS]
 TEQ     R0, #0				;is the JIT running?
 BEQ     _exit				;NO, exit

 BL      check_and_return_taskID	;is this a task we support?
 TEMP    R1
 STREQ   R0, terminate_task		;YES, mark for termination
 LOCK    R1
 B       _exit
#endif


;._force_exit
; MOV     R12, #1
; ADR     R0, _try_os_exit
; MOV     R1, #0
; SWI     XOS_AddCallBack
; B       _exit_claimed
;
; ._try_os_exit
; SWI     OS_Exit


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

._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
 LDRNE   R1, [R12, #privateWord - VARS]	; |  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

 TEMP    R0
 STR     R1, force_mono			;store current status
 LOCK    R0
 ADR     R2, stereo_position		;current stereo positions
 MOV     R0, #7
 ._mono_stereo_L1
   LDRB    R1, [R2, 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
 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




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

.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
 ADR     R2, VARS
 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
;--------------

.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
 ADR     R2, VARS
 SWI     XOS_Release			;PRM1-66
LDMFD   R13!, {R0-R2, PC}
