#multipass on
; Module
; ~~~~~~
; Miscellaneous module code (Init, final, service etc)


.Module_ServiceTable
	equd	0			; flags word
	equd	Module_ServiceKnown	; code to process a known call
	equd	Service_FSReinit	; list of service calls
	equd	Service_IdentifyDisc
	equd	0			; zero terminator

	equd	Module_ServiceTable
.Module_Service
	mov	r0,r0			; magic word
	cmp	r1,#Service_IdentifyDisc	; &69
	teqne	r1,#Service_FSReinit		; &40
	movnes	pc,r14
	ldr	r12,[r12]
	bcs	Image_IdentifyDisc

.FS_Declare
	FNfunction("r0-r3")
FNdt(">>> FS_Declare")
	mov	r0,#FSC_DeclareImageFS
	adr	r1,Module_Base
	mov	r2,#FS_Info
	mov	r3,r12
	swi	"XOS_FSControl"
FNdt("<<< FS_Declare")
	FNreturn

.Module_ServiceKnown
	ldr	r12,[r12]
	teq	r1,#Service_IdentifyDisc
	beq	Image_IdentifyDisc
	b	FS_Declare


.Module_Initialise
	FNfunction("")
;------------------------
; init workspace and memory
	MOV	r0,#0
	SWI	X+MAlloc_Vectors
	ADDVC	r3,r1,#len_workspace%
	MOVVC	r0,#6
	SWIVC	"XOS_Module"
	STRVC	r2,[r12]
	MOVVC	r12,r2
	ADDVC	r0,r2,#malloc_tabbase%
	SWIVC	X+MAlloc_Vectors
	FNpcreturn("VS")
	MOV	r0,#0
	MOV	r1,#len_workspace%
._lp
	SUBS	r1,r1,#4
	STR	r0,[r12,r1]
	BGT	_lp
#if debug%
	stmfd	r13!,{r0-r2,r14}
	mov	r0,#&80
	adr	r1,DebugFilename%
	swi	"XOS_Find"
	movvs	r0,#0
	str	r0,[r12,#DebugHandle%]
	mov	r0,#0
	str	r0,[r12,#DebugIndent%]
	mov	r0,#1
	str	r0,[r12,#DebugFlags%]
	ldmfd	r13!,{r0-r2,r14}
#endif
FNdt(">>> Module_Initialise (debugging just started)")
	BL	Memory_Initialise
;P Cache-line optimisation for memory block #1, which can use the 1024byte
;P optimised memory copy.
	FNmovc(3,len_buffer%+len_buffer2%+32)
	BL	Memory_Claim
	AND	r3,r2,#31
	RSB	r3,r3,#32
	ADD	r2,r2,r3
	STR	r2,[r12,#buffer]	; this is cache-line aligned
	ADD	r2,r2,#len_buffer%
	STR	r2,[r12,#buffer2]	; so is this, but is small
;	MOV	r3,#len_buffer%		; this is all I need for now
;	BL	Memory_Claim
;	STR	r2,[r12,#buffer]
;	MOV	r3,#len_buffer2%
;	BL	Memory_Claim
;	STR	r2,[r12,#buffer2]
	ADR	r1, _newfilecore
	SWI	"XOS_SWINumberFromString"
	MOVVC	r0,#0			; 0 => new filecore
	MOVVS	r0, #1<<31		; 1 => old filecore
	STR	r0,[r12,#debug]
;------------------------
; init filing system and cache
	bl	FS_Declare
	bl	Cache_Initialise
;------------------------
; Initialise random number generator.
	eor	r0,r0,r1
	eor	r1,r0,r2,lsr #3
	swi	"OS_ReadMonotonicTime"
	eor	r0,r0,r1
	str	r0,[r12,#random_seed]
FNdt("<<< Module_Initialise")
	FNreturn

._newfilecore
	equs	"FileCore_SectorOp"+CHR$0
	align

.DebugFilename%
	equs	config_dbg_file$+CHR$0
	align



.Module_Finalise
	FNfunction("")
	LDR	r12,[r12]
FNdt(">>> Module_Finalise")
;------------------------
; remove filing system
	MOV	r0,#FSC_RemoveImageFS
	MOV	r1,#filetype%
	SWI	"XOS_FSControl"
;------------------------
; remove memory and workspace
	BL	Memory_Finalise
FNdt("Closing debug filehandle")
FNdt("%f")
#if debug%
	stmfd	r13!,{r0-r2,r14}
	mov	r0,#0
	ldr	r1,[r12,#DebugHandle%]
	swi	"XOS_Find"
	ldmfd	r13!,{r0-r2,r14}
#endif
	MOV	r2,r12
	MOV	r0,#7
	SWI	"XOS_Module"
	FNreturn



.FS_Info
	EQUD	0		; FS information word
	EQUD	filetype%	; Image filing system file type
	EQUD	File_Open	- Module_Base
	EQUD	File_GetBytes	- Module_Base
	EQUD	0		; IE_PutBytes	- Module_Base
	EQUD	IE_Args		- Module_Base
	EQUD	File_Close	- Module_Base
	EQUD	IE_File		- Module_Base
	EQUD	IE_Func		- Module_Base
