;Module init
;-----------
;Entry:
; R10 - pointer to initialisation parameters
; R11 - instantiation number
; R12 - pointer to private word

.Entry_init
 STMFD   R13!, {R1-R11, R14}
 TEMP    R14
 ADR     R0, VARS
 STR     R0, [R12, #0]			;and point it at VARS
 STR     R0, [R0, #0]			;and update its own pointer
 MOV     R12, R0

 BL      init_crc32			;initialise the CRC32 table
 BVS     _fatal_error

 #if compile_RO > 311
   BL      get_domainID_address
 #endif
 BL      detect_CPU			;detect chipset

 MOV     R0, #Module_Lookup		;check OS version
 ADR     R1, UtilityModule		;..via UtilityModule version
 SWI     XOS_Module			;PRM1-249
 MOV     R0, #Module_EnumerateROM	;request Module version
 MVN     R2, #0
 SWI     XOS_Module			;PRM1-252
 AND     R2, R6, #&FF00 << 8
 #if compile_RO == 400
   BIC     R3, R6, #&FF
   TEQ     R3, #&380 << 8		;treat RO3.8 as RO4 for next check
   TEQNE   R3, #&390 << 8
   MOVEQ   R2, #&400 << 8
 #endif
 TEQ     R2, #&600 << 8			;RO6.x?
 SUBEQ   R6, R6, #&200 << 8		;YES, drop it to 4.x
 #if compile_RO == 400
   TEQNE   R2, #&400 << 8		;RO 4.x?
   LDREQ   R7, [R12, #cpu_id - VARS]
   TEQEQ   R7, #CPUID_StrongARM		;StrongARM?
   MOVEQ   R7, #0			;YES
   STREQB  R7, [R12, #riscos6 - VARS]
 #endif
 STR     R6, [R12, #os_version - VARS]	;store the OS version

 #if compile_IOMD == 1
   BL      detect_VIDC20
   BL      detect_IOMD

   MOV     R0, #8 + (2 << 8)		;get amount of VRAM
   SWI     XOS_Memory			;PRM5a-69
   MUL     R0, R1, R2
   STR     R0, [R12, #vram_available - VARS]	;store the amount of VRAM

   MOV     R0, #161			;read *TV x,y value from CMOS
   MOV     R1, #10			;PRM1-362
   SWI     XOS_Byte			;PRM1-369
   AND     R2, R2, #%111 << 5
   MOV     R2, R2, LSL #24		;shift to sign value
   MOV     R2, R2, ASR #32 - 6		;shift back down and multply by 8
   STRB    R2, [R12, #TV_offset - VARS]
 #endif

 SUB     R13, R13, #8
 ADR     R0, Read_FileSizeLimitVal	;read ADFFS$FileSizeLimit
 MOV     R1, R13			;used this as a tmp buffer
 MOV     R2, #8
 MOV     R3, #0
 MOV     R4, #0
 SWI     XOS_ReadVarVal			;PRM1-314
 TEQ     R4, #1				;is ADFFS$FileSizeLimit a number?
 LDREQ   R3, [R1]			;...YES
 MOVEQ   R3, R3, LSL #10		;convert from KB to bytes
 STREQ   R3, [R12, #File_Size_Limit - VARS]	;...store our file size limit
 ADD     R13, R13, #8

 #if compile_RO > 400
   LDR     R0, [R12, #os_version - VARS]
   MOV     R1, #&523 << 8
   CMP     R0, R1			;RO 5.23+
   BLO     _pre_RO523			;NO

   MOV     R0, #33			;request cache line size
   MOV     R1, #0			;..for L1 cache
   SWI     XOS_PlatformFeatures		;see ROOL wiki
   CMP     R1, R3			;R1=D-cache line, R3=I-cache line
   MOVLO   R1, R3			;R1 hopefully now covers both caches
   STR     R1, L1_CACHE_LINE_SIZE	;store for all cache aligned ops
   SUB     R1, R1, #1
   STR     R1, L1_CACHE_LINE_MASK

   ._pre_RO523
 #endif

 #if Managed_ChannelHandler == 0
   BL      Claim_SWI_Vector		;hook onto the SWI hardware vector
   BVS     _fatal_error
 #endif

 SWI     XOS_ReadMemMapInfo			;read the current page size PRM1-391
 STR     R0, [R12, #current_PageSize - VARS]	;store page size
 SUB     R1, R0, #1				;mask = page size - 1
 STR     R1, [R12, #DA_mask - VARS]		;store mask

 #if compile_RO >= 450
   MVN     R2, #0			;work out page size as a shift
   ._L2
     MOVS    R0, R0, LSR #1
     ADD     R2, R2, #1
   BNE     _L2
   STR     R2, [R12, #current_PageSizeSH - VARS]
 #endif

 BL      Create_DynamicAreas		;create our Dynamic Areas
 BVS     _fatal_error			;exit on error
 #if Managed_ChannelHandler == 1
   BL      claim_ChannelHandler		;take over the RISCOS Channel Handler
   BL      Claim_SWI_Vector		;hook onto the SWI hardware vector
   BVC     _ok
   STR     R0, [R13, #-4]!              ;failed to claim SWI vector
   BL      release_ChannelHandler	;reinstate the RISCOS ChannelHandler
   MOV     R0, #1<<31
   ADDS    R0, R0, R0			;set V
   LDR     R0, [R13], #4
   B       _fatal_error
   ._ok
 #endif

 #if compile_RO <= 400
   MOV     R3, #(8 * 1024) - 1
   ADD     R2, R13, R3			;work out top of SVC26 stack
   BIC     R2, R2, R3
   STR     R2, [R12, #SVC_stack_init - VARS]
 #endif
 #if compile_RO == 400
   MOV     R0, #13			;SVC26 stack
   SWI     XOS_ReadDynamicArea
   ADDVC   R0, R0, R1
   STRVC   R0, [R12, #SVC_stack_init - VARS]

   MOV     R0, #14			;IRQ26 stack
   SWIVC   XOS_ReadDynamicArea
   ADDVC   R0, R0, R1
   STRVC   R0, [R12, #IRQ_stack_init - VARS]
   BVC     _riscos6

   ._not_riscos6
   MRS     R0, CPSR
   BIC     R1, R0, #%11011111
   ORR     R1, R1, #%11000010		;IRQ26 IRQ/FIQ disabled
   MSR     CPSR_c, R1
   NOP
   STR     R13, [R12, #IRQ_stack_init - VARS]	;stack might not be aligned
   MSR     CPSR_c, R0
   NOP
   ._riscos6
 #endif
 #if compile_RO > 311
   MOV     R0, #6
   MOV     R1, #0
   MOV     R2, #14			;L2PT
   SWI     XOS_ReadSysInfo		;riscosopen.org
   STRVC   R2, L2PT_addr

   MOV     R0, #6
   MOV     R2, #13			;L1PT
   SWI     XOS_ReadSysInfo		;riscosopen.org
   STRVC   R2, L1PT_addr

   MOV     R0, #6
   MOV     R2, #16			;SVC stack
   SWI     XOS_ReadSysInfo		;riscosopen.org
   STRVC   R2, [R12, #SVC_stack_init - VARS]
 #endif
 #if compile_RO == 400
   MOV     R0, #6
   MOV     R2, #25			;IRQ26 stack base
   SWI     XOS_ReadSysInfo		;riscosopen.org
   TEQ     R2, #0
   TEQNE   R2, #25
   STRNE   R2, [R12, #IRQ_stack_init - VARS]
 #endif
 #if compile_RO > 400
   MOV     R0, #6
   MOV     R2, #67			;IRQ stack base
   SWI     XOS_ReadSysInfo		;riscosopen.org
   STR     R2, [R12, #IRQ_stack_init - VARS]

   MOV     R2, #69			;IRQsema
   SWI     XOS_ReadSysInfo
   STR     R2, [R12, #IRQsema - VARS]	;pointer to IRQsema, used in SWI handler
 #endif

 #if compile_RO > 311
   MOV     R2, #0
   MOV     R1, #1			;calculate shift to get page
   ._L1					;..count
     MOVS    R0, R0, ROR #1
     ADDCC   R2, R2, #1
   BCC     _L1
   STR     R2, DA_mask_shift

   BL      setup_error_handler		;setup error handler for JIT
   BVS     _fatal_error

   BL      SETUP_MMUControl2
   #if ARMv3_support == 1
     BL      detect_ARMv3		;optimizations for ARMv3 CPUs
   #endif
 #endif

 #if compile_GPU == 1
   BL      claim_GraphicsV_Vector	;start the GraphicsV driver
   BVS     _fatal_error
 #endif

 MOV     R0, #Module_InsertFromMemoryToRMA
 ADR     R1, MemAlloc_Module
 MOV     R2, #MemAlloc_End - MemAlloc_Module
 SWI     XOS_Module			;load MemAlloc stub Module

 ADR     R0, Set_RunTypes_entry		;set the runtypes
 SWI     XOS_CLI

 BL      reinit_ADFS			;Reinit ADFS to get it's DiscOp / MiscOp
 SUBS    R0, R0, R0			;clear V
 LOCK    R14
 ._fatal_error
LDMFD   R13!, {R1-R11, PC}




;Entry_kill
;----------
;Terminates the Module

.Entry_kill
 STMFD   R13!, {R1-R11, R14}
 LDR     R12, [R12, #0]

 ADD     R0, R12, #crc32_table - VARS	;free the CRC32 table
 BL      release_RMA

 MOV     R1, #0
 BL      Entry_ADFJoystickKeys		;release key mapper
 BLVC    Entry_ADFJoystickMouse		;release mouse mapper
 LDMVSFD R13!, {R1-R11, PC}

 #if compile_GPU == 1
   BL      release_GraphicsV_Vector
 #endif
 #if compile_RO > 311
   MOV     R1, #1
   STR     R1, [R12, #jit_task_count - VARS]	;force JIT shutdown
   MOV     R1, #0
   BL      Entry_GOARM3JIT		;shutdown JIT
   LDMVSFD R13!, {R1-R11, PC}
   MOV     R1, #0
   BL      Entry_ADFRemapVideoMemory	;stop remapping video memory
   LDMVSFD R13!, {R1-R11, PC}
 #endif
 #if compile_IOMD == 1 AND No_Frame_Pacing == 0
   BL      release_event_4		;stop generating VSync events
 #endif
 #if Managed_ChannelHandler == 1
   BL      release_ChannelHandler	;reinstate the RISCOS ChannelHandler
 #endif
 MOV     R0, #0
 BL      Entry_ADFEject			;Dismount current disc
 #if compile_RO > 311
   BL      release_fscontrol_filename
 #endif
 BL      Remove_DynamicAreas		;Remove our DAs

 ADD     R0, R12, #recording_addr - VARS	;free DiscOp recoding memory
 BL      release_RMA

 MOV     R0, #Module_Delete
 ADR     R1, MemAlloc_Title
 SWI     XOS_Module                     ;PRM1-235

 #if JIT_instruction_trace == 1
   LDR     R1, [R12, #our_IT_DA_number - VARS]
   TEQ     R1, #0
   MOVNE   R0, #1			;remove the DA
   SWINE   XOS_DynamicArea		;PRM5a-53
 #endif

 #if compile_RO > 311
   LDR     R2, [R12, #Error_handler_buffer - VARS]
   TEQ     R2, #0
   BEQ     _P1
   MOV     R0, #0			;ADFFS dead, okay to remove
   STR     R0, [R2, #Error_Exit_Handler.ADFFS_alive]
   LDR     R0, [R2, #Error_Exit_Handler.use_count]
   TEQ     R0, #0			;are the handlers in use?
   MOVEQ   R0, #Module_Free		;NO, release the claim
   SWIEQ   XOS_Module
   ._P1
 #endif

 BL      Entry_ADFStop			;close recording file

 ADR     R0, Set_RunTypes_exit		;set the runtypes back to defaults
 SWI     XOS_CLI

 SUBS    R0, R0, R0			;clear V
 LDMFD   R13!, {R1-R11, R14}		;clear down stack
B       Release_SWI_Vector		;release SWI which will RMKill us
