;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
 STR     R12, privateWord		;Store our private word pointer
 ADR     R0, VARS
 STR     R0, [R12, #0]			;and point it at VARS
 MOV     R12, R0

 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
 TEQ     R2, #&600 << 8			;RO6?
 SUBEQ   R6, R6, #&200 << 8		;YES, drop it to 4.x
 #if compile_RO == 400
   STREQ   R6, [R12, #riscos6 - VARS]
 #endif
 STR     R6, [R12, #os_version - VARS]	;store the OS version

 #if compile_RO > 311
   BL      get_domainID_address
 #endif
 BL      detect_CPU			;detect chipset
 #if ARMv3_support == 1
   BL      detect_ARMv3			;optimizations for ARMv3 CPUs
 #endif
 #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
   STR     R2, [R12, #TV_offset - VARS]
 #endif

 ADR     R0, Read_FileSizeLimitVal	;read ADFFS$FileSizeLimit
 ADR     R1, Current_File_Mounted + 4	;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

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

   #if MMUControl2_support == 1 AND compile_RO > 400
     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
   #endif

   ._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, DA_mask			;store mask

 #if compile_RO >= 450
   MOV     R2, #0			;work out page size as a shift
   ._L2
     MOVS    R0, R0, LSR #1
     ADD     R2, R2, #1
   BCC     _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
   LDR     R0, [R12, #riscos6 - VARS]
   TEQ     R0, #0
   BEQ     _not_riscos6

   MOV     R0, #13			;SVC26 stack
   SWI     XOS_ReadDynamicArea
   ADDVC   R0, R0, R1
   STRVC   R0, [R12, #SVC_stack_init - VARS]

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

   ._not_riscos6
   MRS     R0, CPSR
   BIC     R1, R0, #%11011111
   ORR     R1, R1, #%11000010		;IRQ26 IRQ/FIQ disabled
   MSR     CPSR_all, R1
   NOP
   ADD     R2, R13, R3			;work out top of IRQ26 stack
   BIC     R2, R2, R3
   STR     R2, [R12, #IRQ_stack_init - VARS]
   MSR     CPSR_all, 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
 #endif

 #if MMUControl2_support == 1
   BL      SETUP_MMUControl2
 #endif

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

 MOV     R0, #Module_ReInit
 ADR     R1, ADFS_Module
 SWI     XOS_Module			;Reinit ADFS to get it's DiscOp / MiscOp

 ADR     R0, Alias_RunType_FCE		;point the RunType alias back at ADFFS
 ADR     R1, Alias_RunType_FCE_val
 MOV     R2, #Alias_RunType_FCE_valE - Alias_RunType_FCE_val
 MOV     R3, #0
 MOV     R4, #4
 SWI     XOS_SetVarVal			;PRM1-316
 ADR     R0, Alias_RunType_FE3		;point the RunType alias back at ADFFS
 MOV     R3, #0
 MOV     R4, #4
 SWI     XOS_SetVarVal			;PRM1-316

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

 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-R12, R14}
 
 MOV     R1, #0
 BL      Entry_ADFJoystickKeys		;release key mapper
 BL      Entry_ADFJoystickMouse		;release mouse mapper

 LDR     R12, [R12, #0]

 #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-R12, PC}
   MOV     R1, #0
   BL      Entry_ADFRemapVideoMemory	;stop remapping video memory
   LDMVSFD R13!, {R1-R12, 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
 BL      Remove_DynamicAreas		;Remove our DAs

 LDR     R2, [R12, #recording_addr - VARS]	;free DiscOp recoding memory
 TEQ     R2, #0
 MOVNE   R0, #Module_Free
 SWINE   XOS_Module			;PRM1-238

 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

 LDMFD   R13!, {R1-R12, R14}		;clear down stack
B       Release_SWI_Vector		;releaseSWI will kill us
