;Entry_EmulateRISCOS
;-------------------
;Switch behaviour to a particular version of RISCOS:
; Arthur	softFont loaded at 36C0
;  to 4.99	Sound_Configure,1,&D0,&30 is issued
;  to 2.00	MRC CP15,0,Rx,C2,C0 is an Undefined instruction
;  to 3.49	OS_ReadMemMapInfo returns R0=32768, R1=256
; 2.00		OS_Byte 129,0,255 returns &A1
;		Hardware vectors Reset, SWI, IRQ are B x
;		                 Undefined, Prefetch, Data abort, Address exception are LDR PC,x
; 2.00..3.49	OS_ReadSysInfo return R0=0 R1=0 R2=0
;		OS_ClaimProcessorVector returns an error
; 2.00..3.80	OS_SpriteOp 36 changes R7 to 0 if it's -1
;		OS_SpriteOp 36 changes R6 to 0 if it's -1
; 2.00..4.99	OS_Byte 14 does nothing when the event already disabled
;		softFont loaded at 3700
; 2.01		OS_Byte 129,0,255 returns &A2
; 2.01..3.49	"ARM3Support" Module present
;		MRC CP15,0,Rx,C2,C0 returns ARM3
; 3.00		OS_Byte 129,0,255 returns &A3
;		Hardware vectors Reset, Undefined, SWI, IRQ are B x
;		                 Prefetch, Data abort, Address exception are LDR PC,x
; 3.10..3.49	OS_Byte 129,0,255 returns &A4
;		OS_Word 21,0 returns after the next VSync
;		(JIT) OS_Memory returns an error
;		IRQv instruction at &18 is changed to B &xxx if host
;		  RISCOS < 5.00 and not running on a StrongARM
;		Sound_Configure will use the previous sample period if R2=0 and
;		  VIDC1 Sound Frequency Register has been altered directly
;		OS_SpriteOp 3 turns the cursor off (*ScreenLoad)
;		OS_Memory return SWI not known
;		Sound_Mode returns SWI not known
; 3.50		OS_Byte 129,0,255 returns &A5
;		to 4.99 (JIT) OS_Memory 9,&300 returns &3500000 if host RISCOS >= 5.00
;		Sound_Mode returns 8bit only
; 3.50..3.80	OS_ReadSysInfo return R0=&1010100 R1=1 R2=0
; 3.50..4.99	"ARM" Module present
;		OS_ReadMemMapInfo returns R0=4096, R1=JIT max/4096
; 3.50+		Hardware vectors are LDR PC,x
; 3.60		OS_Byte 129,0,255 returns &A6
; 3.70		OS_Byte 129,0,255 returns &A7
; 3.80		OS_Byte 129,0,255 returns &A8
;
;Entry:
; R0 - Command tail
; R12 = pointer to module private word

.Entry_EmulateRISCOS
 STMFD   R13!, {R0-R4, R11, R14}
 LDR     R12, [R12, #0]

 TEQ     R1, #1				;is there a parameter?
 BEQ     _read_version			;YES

 MVN     R0, #0
 STR     R0, [R12, #emulate_RISCOS - VARS]	;switch to current OS behaviour

 #if compile_RO == 400
   LDR     R0, [R12, #IRQ_vector - VARS]
   TEQ     R0, #0
   BEQ     _skip_page_zero

   MOV     R1, #0
   MRS     R2, CPSR
   MSR     CPSR_c, #%11010011		;SVC32 IRQ/FIQ disabled
   NOP
   STR     R1, [R12, #IRQ_vector - VARS]
   STR     R0, [R1, #page_zero_IRQ]
   MSR     CPSR_c, R2			;back to original mode
   NOP
   ._skip_page_zero
 #endif

 #if compile_RO > 400
 ; ref. www.riscosopen.org/wiki/documentation/show/Sound_Tuning
   MOV     R0, #&4F545541		;"AUTO"
   MOV     R1, #2			;Enable auto tuning
   SWI     XSound_Tuning
 #endif

 BL      remove_this_taskID_if_no_JIT	;stop tracking this task
 LDMFD   R13!, {R0-R4, R11, PC}


 ;store the OS version in emulate_RISCOS
 ._read_version
 MOV     R11, #0
 LDRB    R2, [R0]			;check for Arthur
 BIC     R2, R2, #32
 TEQ     R2, #ASC("A")			;is it Arthur?
 BEQ     _Arthur			;YES, version=0

 MOV     R3, #5				;read "X.YY"
 ._L1
   LDRB    R2, [R0], #1			;get byte
   CMP     R2, #ASC(".")		;ignore "."
   SUBHI   R2, R2, #ASC("0")		;NO, convert to BCD value
   ORRHI   R11, R2, R11, LSL #4
   SUBHI   R3, R3, #1
 BHS     _L1
					;end up as XYY00
 ._L2
   SUBS    R3, R3, #1
   MOVPL   R11, R11, LSL #4
 BPL     _L2

 ._Arthur
 STR     R11, [R12, #emulate_RISCOS - VARS]

 BL      check_JIT_and_taskID		;is the JIT running
 BNE     _no_JIT

 BL      load_softFont			;load softFont if JIT running
 BL      init_hardware_vectors

 ._no_JIT
 CMP     R11, #&500<<8			;RISCOS 5.00 or above?
 LDMHSFD R13!, {R0-R4, R11, PC}		;YES, exit

 BL      get_taskID			;need to track the taskID
 #if compile_RO > 450
					;set default sound settings
   MOV     R0, #1			;no. channels
   MOV     R1, #&D0			;RISCOS 3.1 default sample length
   MOV     R2, #&30			;RISCOS 3.1 default sample period
   MOV     R3, #0			;channel handler
   MOV     R4, #0			;scheduler
   SWI     XSound_Configure		;PRM4-18
 #endif

 #if compile_RO > 400
  ; ref. www.riscosopen.org/wiki/documentation/show/Sound_Tuning
   LDR     R0, _AUTO			;"AUTO"
   MOV     R1, #1			;Disable auto tuning
   SWI     XSound_Tuning
 #endif

 #if compile_RO == 400
					;3.11 EAE00CE7 B &38033BC
					;3.50 E59FF31C LDR PC, &33C (038039CC)
					;3.71 E59FF39C LDR PC, &3BC (03803EC0)
					;4.02 E59FF400 LDR PC, &420 (038008A0)
					;5.21 E59FF2B8 LDR PC, &2D8 (FC012300)
   MOV     R1, #0
   LDR     R4, [R1, #page_zero_IRQ]	;copy IRQ vector
   AND     R3, R4, #&FF << 24		;mask instruction
   TEQ     R3, #&E5 << 24		;is it LDR PC?
   BNE     _skip_IRQ_change		;NO, leave as is
   STR     R4, [R12, #IRQ_vector - VARS]	;store for later reset

   MOV     R4, R4, LSL #32 - 12
   MOV     R4, R4, LSR #32 - 12		;R4=offset to address
   ADD     R5, R4, #4
   MOV     R5, R5, LSR #2
   ORR     R5, R5, #&EA000000

   MRS     R2, CPSR
   MSR     CPSR_c, #%11010011		;SVC32 IRQ/FIQ disabled
   NOP
   LDR     R0, _LDR_PC_minus_4
   STR     R0, [R4, #&24]		;store LDR PC, &33C at &340 (RO3.5)
   STR     R5, [R1, #page_zero_IRQ]	;change IRQv to B &340 (RO3.5)
   MSR     CPSR_c, R2			;back to original mode
   NOP

   ._skip_IRQ_change
 #endif
 SUBS     R0, R0, R0			;clear V
LDMFD   R13!, {R0-R4, R11, PC}


#if compile_RO == 400
 ._LDR_PC_minus_4	LDR     PC, [PC, #-12]
#endif
#if compile_RO > 400
 ._AUTO			DCB     "AUTO"
#endif




;load_softFont
;-------------
;builds the softFont table in Page Zero

;Entry
; R12 - pointer to VARS

.load_softFont
 STMFD   R13!, {R0-R3, R14}

 BL      task_page_zero_R2		;redirect to our page zero
 LDR     R0, [R12, #emulate_RISCOS - VARS]
 TEQ     R0, #0				;is it Arthur?
 MOVEQ   R1, #page_zero_Arthur_SoftFont	;YES
 MOVNE   R1, #page_zero_SoftFont	;NO

 ADD     R0, R2, R1			;R2=SoftFont in our page zero
 ADD     R1, R0, #page_zero_SoftFont_size
 BL      ZeroBlock			;clear whole area

 MOV     R1, R0
 MOV     R2, #32			;build font table
 MOV     R0, #10
 ._L2
   LDRB    R3, [R1, #-1]!
   STRB    R2, [R1]
   SWI     XOS_Word			;PRM1-702
   STRB    R3, [R1], #9
   ADD     R2, R2, #1
   TEQ     R2, #127
   ADDEQ   R2, R2, #1
   ADDEQ   R1, R1, #9
   TEQ     R2, #256
 BNE      _L2
LDMFD   R13!, {R0-R3, PC}




;init_hardware_vectors
;---------------------
;set the JIT hardware vectors to be appropriate to the OS version

; 2.00		OS_Byte 129,0,255 returns &A1
;		Hardware vectors Reset, SWI, IRQ are B x
;		Undefined, Prefetch, Data abort, Address exception are LDR PC,x
; 3.00		OS_Byte 129,0,255 returns &A3
;		Hardware vectors Reset, Undefined, SWI, IRQ are B x
;		Prefetch, Data abort, Address exception are LDR PC,x
;Entry:
; R12 - pointer to VARS

.init_hardware_vectors
 STMFD   R13!, {R0-R6, R12, R14}
 LDR     R3, [R12, #emulate_RISCOS - VARS]
 CMN     R3, #1				;are we defaulting
 MOVEQ   R3, #&300 << 8			;YES, assume RO 3.1x
 
 CMP     R3, #&350 << 8
; 0=LDR  1=Branch
;              +------ IRQ
;              |+----- Address exception
;              ||+---- Data abort
;              |||+--- Prefetch abort
;              ||||+-- SWI
;              |||||+- Undefined instruction
;              ||||||+ Reset
 MOVHS   R2, #%0000000
 MOVLO   R2, #%1000111			;RO 3.00-3.49
 CMP     R3, #&300 << 8
 MOVLO   R2, #%1000101			;<RO 3.00

 BL      task_page_zero_R0		;R0=JIT page zero
 ADD     R5, R12, #hypervised_vectors - VARS	;R5=our copy of the vectors
 MOV     R6, #jit_code_start		;R6=JIT code
 MOV     R1, #0
 ._L1
   MOVS    R2, R2, LSR #1		;B or LDR?
   BCC     _ldr				;its an LDR

   LDR     R3, [R12, #jit_managed_ldr_pc_r13_2 - VARS]
   SUB     R3, R3, R1			; |+ (fixes Lotus Turbo Challenge 2)
   SUB     R3, R3, #8
   BIC     R3, R3, #%111111 << 26
   MOV     R3, R3, LSR #2
   ORR     R3, R3, #&EA000000		;B <address>

   ._P1
   STR     R3, [R6, R1]			;JIT instruction
   STR     R3, [R0, R1]			;instruction game sees
   STR     R3, [R5, R1]			;our copy, to check if its changed

   ADD     R1, R1, #4
   TEQ     R1, #&1C
 BNE     _L1
LDMFD   R13!, {R0-R6, R12, PC}

 ._ldr
 ADD     R4, R0, #page_zero_hardware_vectors
 LDR     R3, [R12, #jit_managed_os_exit - VARS]	;branch to SWI OS_Exit
 STR     R3, [R4, R1]
 LDR     R3, _ldr_instruction
 B       _P1

 ._ldr_instruction  LDR PC, [PC, #page_zero_hardware_vectors-8]
