;store or restores various machine settings, which may have been changed
;by a game running under the JIT

STRUCT Machine_State
{
 .OS_Memory20		DCD 0
 #if compile_RO == 500
  .cpu_control_register	DCD 0	;previous state of CPU C1 used by JIT
 #endif
 .VSync_Event		DCB 0
 .Output_Streams	DCB 0
 .Key_Repeat_Delay	DCB 0
 .Key_Repeat_Rate	DCB 0
 .Break			DCB 0
 .Keyboard_State	DCB 0
 .Escape_Char		DCB 0
 .Buffer_Codes		DCB 0, 0, 0, 0, 0, 0, 0, 0
 .Tab_Key		DCB 0
 .Escape_State		DCB 0
 .Escape_Effect		DCB 0
 .Break_Action		DCB 0
 .Mouse_Step		DCB 0
 .Shadow		DCB 0
 .DesktopState		DCB 0
 .WimpTask		DCB 0
 .Size
}


;Entry
; R12 - pointer to VARS

.store_machine_state
 STMFD   R13!, {R0-R2, R11, R14}
 ADD     R11, R12, #Current_Machine_State - VARS

 MOV     R0, #14
 MOV     R1, #4
 SWI     XOS_Byte			;Enable VSync
 STRB    R1, [R11, #Machine_State.VSync_Event]
 MOV     R0, #13
 MOV     R1, #4
 SWI     XOS_Byte			;Disable again

 MOV     R0, #3				;Output streams
 MOV     R1, #%1000100			;Disable printer, Enable
 SWI     XOS_Byte			;set to get current value
 STRB    R1, [R11, #Machine_State.Output_Streams]
 SWI     XOS_Byte			;reset

 MOV     R0, #196			;Keyboard auto-repeat delay
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Key_Repeat_Delay]

 MOV     R0, #197			;Keyboard auto-repeat rate
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Key_Repeat_Rate]

 MOV     R0, #200			;reset break key
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-910
 STRB    R1, [R11, #Machine_State.Break]

 MOV     R0, #201			;keyboard state
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-912
 STRB    R1, [R11, #Machine_State.Keyboard_State]

 MOV     R0, #220			;escape character
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-920
 STRB    R1, [R11, #Machine_State.Escape_Char]

 MOV     R0, #221			;reset function key interpretation
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes]

 MOV     R0, #222
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+1]

 MOV     R0, #223
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+2]

 MOV     R0, #224
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+3]

 MOV     R0, #225
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+4]

 MOV     R0, #226
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+5]

 MOV     R0, #227
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+6]

 MOV     R0, #228
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte
 STRB    R1, [R11, #Machine_State.Buffer_Codes+7]

 MOV     R0, #219
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte                       ;PRM1-918
 STRB    R1, [R11, #Machine_State.Tab_Key]

 MOV     R0, #229			;enable ESC
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-925
 STRB    R1, [R11, #Machine_State.Escape_State]

 MOV     R0, #230			;enable escape effect
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-927
 STRB    R1, [R11, #Machine_State.Escape_Effect]

 MOV     R0, #247			;reset Break key action
 MOV     R1, #0
 MOV     R2, #255
 SWI     XOS_Byte			;PRM1-933
 STRB    R1, [R11, #Machine_State.Break_Action]

 MOV     R0, #161			;read CMOS
 MOV     R1, #194			;Mouse Step
 SWI     XOS_Byte			;PRM1-369
 STRB    R2, [R11, #Machine_State.Mouse_Step]

 MOV     R0, #114			;set shadow state so we can read it
 MOV     R1, #1
 SWI     XOS_Byte			;PRM1-664
 STRB    R1, [R11, #Machine_State.Shadow]
 SWI     XOS_Byte			;and then set back

 MOV     R0, #WimpSysInfo_DesktopState
 SWI     XWimp_ReadSysInfo		;PRM3-216
 STRB    R0, [R11, #Machine_State.DesktopState]

 MOV     R0, #0
 STRB    R0, [R11, #Machine_State.WimpTask]
LDMFD   R13!, {R0-R2, R11, PC}




;Entry
; R12 - pointer to VARS

.restore_machine_state
 STMFD   R13!, {R0-R3, R11, R14}
 ADD     R11, R12, #Current_Machine_State - VARS

 LDRB    R0, [R11, #Machine_State.WimpTask]
 TEQ     R0, #0				;was Wimp_Initialise called?
 BNE     _wimp_task			;YES
 MVN     R0, #0
 SWI     XWimp_CommandWindow		;hide command window
 LDRB    R0, [R11, #Machine_State.DesktopState]
 TEQ     R0, #0				;at CLI?
 SWIEQ   XOS_WriteI+4			;YES
 SWI     XOS_WriteI+6			;Enable VDU output

 MOV     R0, #20			;reset system font
 SWI     XOS_Byte			;PRM1-654
 ._wimp_task

 MOV     R0, #14			;Enable VSync event, before we can disable
 MOV     R1, #4
 SWI     XOS_Byte			;PRM1-152
 MOV     R3, R1				;previous state
 ._disable_VSync_L1
   MOV     R0, #13			;Disable the VSync event
   MOV     R1, #4			;PRM1-147 VSync
   SWI     XOS_Byte			;PRM1-150

   SUBS    R3, R3, #1			;repeat until fully disabled
 BPL     _disable_VSync_L1

 LDRB    R3, [R11, #Machine_State.VSync_Event]
 ._set_VSync_L1
   TEQ     R3, #0			;was VSync Event enabled?
   MOVNE   R0, #14			;YES
   MOVNE   R1, #4
   SWINE   XOS_Byte
   SUBS    R3, R3, #1
 BGT     _set_VSync_L1

 MOV     R0, #3
 LDRB    R1, [R11, #Machine_State.Output_Streams]
 SWI     XOS_Byte			;PRM1-520

 MOV     R0, #15
 MOV     R1, #0				;flush all buffers
 SWI     XOS_Byte			;PRM1-167

 MOV     R0, #196			;set keyboard auto-repeat delay
 LDRB    R1, [R11, #Machine_State.Key_Repeat_Delay]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-886

 MOV     R0, #197			;set keyboard auto-repeat rate
 LDRB    R1, [R11, #Machine_State.Key_Repeat_Rate]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-888

 MOV     R0, #200			;reset break key
 LDRB    R1, [R11, #Machine_State.Break]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-910

 MOV     R0, #201			;enable the keyboard
 LDRB    R1, [R11, #Machine_State.Keyboard_State]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-912

 MOV     R0, #218			;reset VDU queue
 MOV     R1, #0
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-694

 MOV     R0, #220			;reset the escape character
 LDRB    R1, [R11, #Machine_State.Escape_Char]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-920

 MOV     R0, #221			;reset function key interpretation
 LDRB    R1, [R11, #Machine_State.Buffer_Codes]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #222
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+1]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #223
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+2]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #224
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+3]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #225
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+4]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #226
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+5]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #227
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+6]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #228
 LDRB    R1, [R11, #Machine_State.Buffer_Codes+7]
 MOV     R2, #0
 SWI     XOS_Byte

 MOV     R0, #219                       ;TAB key
 LDRB    R1, [R11, #Machine_State.Tab_Key]
 MOV     R2, #0
 SWI     XOS_Byte                       ;PRM1-918

 MOV     R0, #229			;enable ESC
 LDRB    R1, [R11, #Machine_State.Escape_State]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-925

 MOV     R0, #230			;enable escape effect
 LDRB    R1, [R11, #Machine_State.Escape_Effect]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-927

 MOV     R0, #247			;reset Break key action
 LDRB    R1, [R11, #Machine_State.Break_Action]
 MOV     R2, #0
 SWI     XOS_Byte			;PRM1-933

 SWI     XOS_RestoreCursors

 LDRB    R2, [R11, #Machine_State.Mouse_Step]
 MOV     R0, #2
 ORR     R0, R0, R2, LSL #8
 ORR     R0, R0, R2, LSL #16
 STR     R0, [R13, #-4]!
 MOV     R0, #21			;PRM1-714
 MOV     R1, R13
 SWI     XOS_Word			;reset MouseStep
 ADD     R13, R13, #4

 MOV     R0, #114			;reset shadow state
 LDRB    R1, [R11, #Machine_State.Shadow]
 SWI     XOS_Byte			;PRM1-664

 MOV     R0, #0				;turn off forced VSync
 STRB    R0, [R12, #force_vsync - VARS]
LDMFD   R13!, {R0-R3, R11, PC}
