;
; stub.s
;
; Stub loader for dynamically linked Sapphire
;
;  1994-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sapphire library.
;
; Sapphire is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sapphire is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sapphire.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		GET	libs:stream

;----- External dependencies ------------------------------------------------

		IMPORT	sapphire_doInit
		IMPORT	sapphire_doLibInit
		IMPORT	sapphire_doDisable
		IMPORT	except_init
		IMPORT	except_atExit

		IMPORT	|DLL$$ExternalTable$$Base|,WEAK
		IMPORT	|DLL$$ExternalTable$$Limit|,WEAK

		IMPORT	|Image$$RW$$Limit|,WEAK

		IMPORT	|Sapphire$$LibData$$Base|,WEAK
		IMPORT	|Sapphire$$LibData$$Limit|,WEAK
		IMPORT	|Sapphire$$ClientData$$Base|,WEAK
		IMPORT	|Sapphire$$ClientData$$Limit|,WEAK
		IMPORT  |Sapphire$$ExtTable$$Base|,WEAK
		IMPORT  |Sapphire$$ExtTable$$Limit|,WEAK

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

		EXPORT	|_dll_findall|
|_dll_findall|	EQU	0

; --- sapphire_init ---
;
; On entry:	R0 == pointer to application name
;		R1 == client workspace size
;		R2 == requested size of stack
;
; On exit:	R10 == pointer to heap
;		R11 == pointer to scratchpad and environment information
;		R12 == pointer to client workspace
;		R13 == stack pointer
;		Other registers corrupted
;
; Use:		Initialises the Sapphire library.

		EXPORT	sapphire_init
sapphire_init	ROUT

		; --- Save arguments in high registers ---

		STR	R14,sapph__space	;Save return address
		MOV	R8,R0			;Keep application name ptr
		MOV	R9,R1			;Keep workspace size value
		MOV	R10,R2			;Keep stack size too

		; --- Load in requested DLLs ---

		ADR	R0,sapph__dllTable	;Point to DLL table thing
		LDMIA	R0,{R0,R1}		;Load the base and limit
		SWI	DLL_FindFromTable	;Load the DLLs I want

		; --- Set up application name ---

		MOV	R0,R8			;Point to client app name
		SWI	DLL_NameApp		;Register application name

		; --- Initialise the library ---

		MOV	R0,R8			;Point to the name again
		MOV	R1,R9			;Get workspace size wanted
		MOV	R2,R10			;Get the stack size
		ADR	R3,sapph__initTable	;Point to initialisation tbl
		BL	sapphire_doInit		;Do the main initialisation

		; --- Now add in atexit routine ---

		LDR	R14,sapph__space	;Load the return address
		STMFD	R13!,{R14}		;Save it on the stack
		SWI	DLL_SaveHandle		;Find my application handle
		BL	except_init		;Initialise exception handler
		MOV	R1,R0			;Pass this value in R12
		ADR	R0,sapph__closeDown	;Point to shutdown routine
		BL	except_atExit		;Register my routine
		LDMFD	R13!,{PC}^		;And return to caller

sapph__dllTable	DCD	|DLL$$ExternalTable$$Base|
		DCD	|DLL$$ExternalTable$$Limit|

sapph__initTable
		DCD	|Image$$RW$$Limit|
		DCD	|Sapphire$$LibData$$Base|
		DCD	|Sapphire$$LibData$$Limit|
		DCD	|Sapphire$$ClientData$$Base|
		DCD	|Sapphire$$ClientData$$Limit|
		DCD	-1
		DCD	|Sapphire$$ExtTable$$Base|
		DCD	|Sapphire$$ExtTable$$Limit|

sapph__space	DCD	0

		LTORG

; --- sapph__closeDown ---
;
; On entry:	R12 == application handle
;
; On exit:	--
;
; Use:		Deregisters the application with the DLLManager module.

sapph__closeDown ROUT

		STMFD	R13!,{R0,R14}		;Save some registers
		MOV	R0,R12			;Get application handle
		SWI	DLL_RestoreHandle	;Find the handle again
		SWI	DLL_AppDying		;Deregister this application
		LDMFD	R13!,{R0,PC}^		;And return to caller

		LTORG

; --- sapphire_libInit ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Initialises all library sections.

		EXPORT	sapphire_libInit
sapphire_libInit
		STMFD	R13!,{R0,R14}		;Save a register
		ADR	R0,sapph__initTable	;Point to initialisation tbl
		BL	sapphire_doLibInit	;Actually do this job
		LDMFD	R13!,{R0,PC}^		;And return to caller

		LTORG

; --- sapphire_disable ---
;
; On entry:	R0 == pointer to list of initialise routines.
;
; On exit:	--
;
; Use:		Inactivates Sapphire units.

		EXPORT	sapphire_disable
sapphire_disable
		STMFD	R13!,{R1,R14}		;Save a register
		ADR	R1,sapph__initTable	;Point to initialisation tbl
		BL	sapphire_doDisable	;Actually do this job
		LDMFD	R13!,{R1,PC}^		;And return to caller

		LTORG

;----- That's all, folks ----------------------------------------------------

		END
