#set CPUID_StrongARM	= &A10
#set CPUID_Iyonix	= &12C3



;detect_CPU
;----------
;Detects ARM2, ARM3, ARM610, ARM710, ARM7500, StrongARM

.detect_CPU
 STMFD   R13!, {R0-R7, R14}
 #if compile_RO == 311			;claim vector on RISC OS <3.5
   MOV     R0, PC
   ORR     R0, R0, #%11 << 26		;disable IRQ/FIQ
   TEQP    R0, #0
   NOP
   MOV     R4, #Vector_UndefinedInstr << 2	;hardware vector address
   LDR     R5, [R4]			;get old value
   ADR     R1, _detected_ARM2 - 12	;get our vector handler,
					;..-12 to correct address
   MOV     R1, R1, LSR #2		;..shift address down
   ORR     R1, R1, #&EA000000		;..set the ARM command
   STR     R1, [R4]			;..and replace the vector
 #endif

 MRC     P15, 0, R0, C0, C0		;this will error on an ARM2

 #if compile_RO == 311
   STR     R5, [R4]			;reset hardware vector on RISC OS <3.5
   MOV     R6, PC
   BIC     R6, R6, #%11 << 26		;enable interrupts
   TEQP    R6, #0
   NOP
 #endif

 AND     R1, R0, #&FF00
 #if compile_RO == 311
   TEQ     R1, #&300			;ARM3
   MOVEQ   R2, #3
 #endif
 #if compile_RO > 311
					;assume no support for subpages
   MOV     R7, #%010101010000 << 16	;and use default AP3..AP1 L2PT mask
   AND     R3, R0, #&00F0		;Add extra bits in for higher processors
   ORR     R1, R1, R3

   TEQ     R1, #&600			;ARM600
   TEQNE   R1, #&610			;ARM610
   TEQNE   R1, #&620			;ARM620
   MOVNE   R1, R1, LSR #4
   MOV     R2, R1
   TEQNE   R1, #&700			;ARM700
   TEQNE   R1, #&710			;ARM710
   TEQNE   R1, #&810			;ARM810
   TEQNE   R1, #&A10			;SA-110
   EORNES  R0, R1, #&A11		;SA-1100
   #if JIT_self_modifying_support == 1 AND compile_IOMD == 1
     ADREQ   R14, _exit			;YES, check for Red Squirrel
     BEQ     _check_for_red_squirrel
   #endif
   ADDNE   R2, R2, #&1000		;&12C3 - Intel 80321 (Iyonix)
					;&1411 - Intel PXA270/272
   EORS    R0, R2, #&12C3		;Iyonix?
   ORREQ   R7, R7, #1			;YES, subpages supported
   MOVNE   R7, #%000000010000 << 16	;NO, subpages not supported, only one
					;AP in L2PT entries
 #endif

 ._exit
 STR     R2, [R12, #cpu_id - VARS]	;store the cpu id

 #if JIT_self_modifying_support == 1
   ADR     R1, subpages_supported
   STR     R7, [R1]
 #endif
LDMFD   R13!, {R0-R7, PC}


#if JIT_self_modifying_support == 1 AND compile_IOMD == 1
;_check_for_red_squirrel
;-----------------------
;Red Squirrel doesn't implement Aborts on subpages correctly, so we need
;to force subpage support off

._check_for_red_squirrel
 STMFD   R13!, {R0-R5, R14}

 MOV     R0, #0
 SWI     XHostFS_GetDeviceName		;Running under Red Squirrel?
 ORRVS   R7, R7, #1			;NO, subpages are supported
LDMFD   R13!, {R0-R5, PC}
#endif


#if compile_RO == 311
 ._detected_ARM2
 MOV     R2, #2				;ARM2 / 250
 STR     R5, [R4]			;reset hardware vector

 BIC     R0, R14, #&FC000003
 TEQP    PC, #%11			;SVC, interrupts enabled
 NOP
B       _exit
#endif



#if compile_IOMD == 1
;Entry:
; R12 - pointer to VARS

.detect_VIDC20
 STMFD   R13!, {R0-R6, R14}
 LDR     R6, [R12, #os_version - VARS]
 CMP     R6, #&350 << 8			;are we on RISC OS lower than 3.5?
 MOVLO   R1, #0				;YES
 MOVHS   R0, #9				;NO
 MOVHS   R1, #3 << 8			;get VIDC20 address
 SWIHS   XOS_Memory			;PRM5a-70
 STR     R1, [R12, #VIDC20_addr - VARS]	;store the VIDC20 address
LDMFD   R13!, {R0-R6, PC}




;Entry:
; R12 - pointer to VARS

.detect_IOMD
 STMFD   R13!, {R0-R6, R14}
 LDR     R6, [R12, #os_version - VARS]
 CMP     R6, #&500 << 8			;are we on RISC OS 5.0+
 LDRLO   R1, [R12, #IOMD_addr - VARS]	;NO, assume IOC at normal address
 BLO     _P1				; |+ skip RO 5.0 code

 MOV     R0, #9
 MOV     R1, #4 << 8			;get IOMD address
 SWI     XOS_Memory			;PRM5a-70
 TEQ     R1, #0				;do we have the IOC address?
 LDMEQFD R13!, {R0-R6, PC}		;NO, exit
 STR     R1, [R12, #IOMD_addr - VARS]

 ._P1					;Get IOC address from RISCOS
 LDRB    R0, [R1, #IOMD_ID1]		;get IOMD chip ID high byte

 TEQ     R0, #&5B			;ARM7500?
 TEQNE   R0, #&AA			;ARM7500FE?
 MOVEQ   R0, #A7000_reference_clock	;YES, change VIDC20 clock rate
 STREQ   R0, [R12, #VIDC20_clock - VARS]

LDMFD   R13!, {R0-R6, PC}
#endif
