;Entry:
; R0  - instruction
; R7  - original instruction address + 8
; R14 - re-interpreted instruction address + 8
;
;Exit:
;
; R8-R14 - preserved

ALIGN   32, 4
.i_SWI
 TST     R0, #swi_OS_bits		;another OS?
 BNE     i_copy_and_exit		;YES, leave as it is

 BIC     R1, R0, #swi_X_bit		;clear X bit
 MOV     R1, R1, LSL #12		;shift SWI# to top bits

 TEMP    R2
 TEQ     R1, #1 << 12			;OS_WriteS
 BEQ     i_OS_WriteS

 TEQ     R1, #&11 << 12			;OS_Exit
 TEQNE   R1, #&2B << 12			;OS_GenerateError
 TEQNE   R1, #&50 << 12			;OS_ExitAndDie
 BEQ     i_copy_and_exit		;copy and exit JIT

#if JIT_debug == 1
 LDR     R3, jit_joysticks		;PJSRA
 TEQ     R1, #&CFFC0 << 12		;Joy_Read
 ORREQ   R3, R3, #%01000
 TEQ     R1, #&81540 << 12		;VTJoystick_Status
 ORREQ   R3, R3, #%00100
 TEQ     R1, #&43F40 << 12		;Joystick_Read
 ORREQ   R3, R3, #%00001
 TEQ     R1, #&42EC0 << 12		;Parallel_HardwareAddress
 TEQNE   R1, #&42EC1 << 12		;Parallel_Op
 ORREQ   R3, R3, #%10000
 STR     R3, jit_joysticks
#endif

#if swi_flag_preservation == 0
 TEQ     R1, #&01 << 12			;OS_WriteS
 TEQNE   R1, #&0C << 12			;OS_GBPB
 TEQNE   R1, #&0F << 12			;OS_Control
 TEQNE   R1, #&10 << 12			;OS_GetEnv
 TEQNE   R1, #&12 << 12			;OS_SetEnv
 TEQNE   R1, #&15 << 12			;OS_CallBack
 TEQNE   R1, #&18 << 12			;OS_BreakCtrl
 #if swi_flag_preservation == 0 AND compile_RO > 400
   TEQNE   R1, #&0E << 12		;OS_ReadLine
   TEQNE   R1, #&1D << 12		;OS_Heap
 #endif
 TEQNE   R1, #&1E << 12			;OS_Module
 TEQNE   R1, #&1F << 12			;OS_Claim
 TEQNE   R1, #&20 << 12			;OS_Release
 TEQNE   R1, #&29 << 12			;OS_FSControl
 TEQNE   R1, #&30 << 12			;OS_ServiceCall
 #if swi_flag_preservation == 0 AND compile_GPU == 1
   TEQNE   R1, #&35 << 12		;OS_ReadModeVariable
 #endif
 TEQNE   R1, #&3B << 12			;OS_CallAfter
 TEQNE   R1, #&3C << 12			;OS_CallEvery
 TEQNE   R1, #&3D << 12			;OS_RemoveTickerEvent
 TEQNE   R1, #&40 << 12			;OS_ChangeEnvironment
 TEQNE   R1, #&41 << 12			;OS_ClaimScreenMemory
 TEQNE   R1, #&42 << 12			;OS_ReadMonotonicTime
 TEQNE   R1, #&47 << 12			;OS_AddToVector
 TEQNE   R1, #&4B << 12			;OS_ClaimDeviceVector
 TEQNE   R1, #&4C << 12			;OS_ReleaseDeviceVector
 TEQNE   R1, #&4F << 12			;OS_HeapSort
 TEQNE   R1, #&51 << 12			;OS_ReadMemMapInfo
 TEQNE   R1, #&54 << 12			;OS_AddCallBack
 TEQNE   R1, #&58 << 12			;OS_ReadSysInfo
 TEQNE   R1, #&5F << 12			;OS_RemoveCallBack
 TEQNE   R1, #&68 << 12			;OS_Memory
 TEQNE   R1, #&69 << 12			;OS_ClaimProcessorVector
 TEQNE   R1, #&6D << 12			;OS_PlatformFeatures
 TEQNE   R1, #&6F << 12			;OS_CallASWI
 TEQNE   R1, #&71 << 12			;OS_CallASWIR12
 TEQNE   R1, #&400DE << 12		;Wimp_StartTask
 TEQNE   R1, #&400EC << 12		;Wimp_SlotSize
 TEQNE   R1, #&400EE << 12		;Wimp_ClaimFreeMemory
 TEQNE   R1, #&40144 << 12		;Sound_Mode
 TEQNE   R1, #&40145 << 12		;Sound_LinearHandler
 TEQNE   R1, #&40183 << 12		;Sound_InstallVoice
 TEQNE   R1, #&40184 << 12		;Sound_RemoveVoice
 TEQNE   R1, #&401C1 << 12		;Sound_QSchedule
 TEQNE   R1, #&42701 << 12		;Squash_Decompress
 TEQNE   R1, #ADFFS_UnSqueeze << 12	;ADFFS_UnSqueeze
 BEQ     i_SWI_Hypervised
#endif

 TEQ     R1, #&17 << 12			;OS_BreakPt
 MOVEQ   R1, #2				;ADFF5002
 BEQ     JIT_report_unimplemented
 LOCK    R2

 SUBS    R2, R1, #&80680 << 12		;SharedCLibrary_LibInitAPCS_A
 ORREQ   R0, R0, #1 << 18		;force to our modified CLib
 BEQ     i_SWI_Hypervised
 TEQ     R2, #1 << 12			;SharedCLibrary_LibInitAPCS_R
 TEQNE   R2, #3 << 12			;SharedCLibrary_LibInitAPCS_32
 ORREQ   R0, R0, #1 << 18		;force to our modified CLib
 ORREQ   R0, R0, #1 << 6		;SWI base
 BEQ     i_SWI_Hypervised
 TEQ     R2, #2 << 12			;SharedCLibrary_LibInitModule
 MOVEQ   R1, #8				;YES, ADFF5008
 BEQ     JIT_report_unimplemented

#if JIT_prevent_OS_EnterOS == 1
 TEQ     R1, #&16 << 12			;OS_EnterOS
 MOVEQ   R1, #&0E
 BEQ     JIT_report_unimplemented	;ADFF500E
#endif
#if JIT_prevent_OS_EnterOS > 1
 TEQ     R1, #&16 << 12			;OS_EnterOS
 MOVEQ   R0, #%1101 << 21		;YES, NOP it
 BEQ     i_copy_instruction
#endif

#if swi_flag_preservation == 1		;these must be mirrored in
 TEMP    R2				;hv_OS_CallASWI_check_SWI
 TEQ     R1, #&5 << 12			;OS_CLI
 TEQNE   R1, #&13 << 12			;OS_IntOn
 TEQNE   R1, #&14 << 12			;OS_IntOff
 TEQNE   R1, #&16 << 12			;OS_EnterOS
 TEQNE   R1, #&7C << 12			;OS_LeaveOS
 TEQNE   R1, #&400C7 << 12		;Wimp_Poll
 TEQNE   R1, #&400E1 << 12		;Wimp_PollIdle
 LOCK    R2
 BEQ     i_copy_instruction		;YES

; fallthru to i_SWI_Hypervised
#endif
#if swi_flag_preservation == 0
B       i_copy_instruction
#endif


.i_SWI_Hypervised
 ADD     R0, R0, #JIT_SWI_OS_Flag	;trigger our SWI handler
B       i_copy_instruction_handled



.i_OS_WriteS
 ADD     R0, R0, #JIT_SWI_OS_Flag	;trigger our SWI handler
 STR     R0, [R14, #-8]

 SUB     R7, R7, #4			;go to next instruction
 ._L1					;find next instruction
   LDRB    R0, [R7], #1
   ADD     R14, R14, #1
   TEQ     R0, #0
 BNE     _L1				;R14 = next instruction + 8
 ADD     R14, R14, #3			;make sure we go to the next word
 BIC     R14, R14, #%11			;and align it
B       i_instruction_handled_no_codelet
