;
; sapphire.sh
;
; Initialise a Sapphire application and libraries
;
;  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.

;----- Overview -------------------------------------------------------------
;
; Functions provided:
;
;  sapphire_init
;  sapphire_libInit
;  sapphire_disable
;  sapphire_doInit
;  sapphire_doLibInit
;  sapphire_doDisable
;  sapphire_heapAddr
;  sapphire_appName
;  sapphire_resetStack
;  sapphire_global
;
; Macros provided:
;
;   WSPACE

		[	:LNOT::DEF:sapphire__dfn
		GBLL	sapphire__dfn

; --- sapphire_init ---
;
; On entry:	R0 == pointer to application name
;		R1 == application's workspace size
;		R2 == size of stack required
;
; On exit:	R10 == pointer to heap base
;		R11 == pointer to ScratchPad
;		R12 == pointer to application workspace
;		R13 == pointer to full descending stack
;		Other registers are corrupted
;
; Use:		Initialises the Sapphire kernel, sets up the memory map,
;		and allocates workspace for library and client units.  The
;		initialisation performed is fairly minimal; in particular,
;		the library units are not initialised -- you must call
;		sapphire_libInit for this to take place.  This allows you
;		to check command line arguments etc. before initialising
;		the Wimp.

		IMPORT	sapphire_init

; --- sapphire_disable ---
;
; On entry:	R0 == pointer to 0-terminated list of initialise routines
;
; On exit:	--
;
; Use:		Prevents the given initialisation routines from being called.
;		This is mainly useful in the dynamic-linking environment,
;		where all Sapphire units are normally active.  This routine
;		allows you to inactivate units which for example do not
;		have the resources they require, or use up unnecesary
;		memory.

		IMPORT	sapphire_disable

; --- sapphire_libInit ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Initialises the Sapphire library and client units.

		IMPORT	sapphire_libInit

; --- sapphire_doInit ---
;
; On entry:	R0 == pointer to application name
;		R1 == client workspace size
;		R2 == requested stack size
;		R3 == pointer to initialisation table
;
; On exit:	R10 == base address of Sapphire heap
;		R11 == pointer to scratchpad and global data
;		R12 == pointer to client global workspace
;		R13 == pointer to a full descendion stack
;
; Use:		Performs initialisation of the Sapphire library and the
;		client's sections.  This is intended for use by the Sapphire
;		stub, while initialising the dynamically linked version of
;		Sapphire.

		IMPORT	sapphire_doInit

; --- sapphire_doLibInit ---
;
; On entry:	R0 == address of library initialisation table
;
; On exit:	--
;
; Use:		Initialises all currently uninitialised library units.

		IMPORT	sapphire_doLibInit

; --- sapphire_doDisable ---
;
; On entry:	R0 == pointer to list of initialise routines to disable
;		R1 == pointer to initialisation table
;
; On exit:	--
;
; Use:		Prevents the given initialisation routines from being
;		called.  This is mainly useful in a dynamically linked
;		environment.

		IMPORT	sapphire_doDisable

; --- sapphire_heapAddr ---
;
; On entry:	--
;
; On exit:	R1 == pointer to the heap base (for passing to OS_Heap)
;
; Use:		Returns the address of the Sapphire heap.

		IMPORT	sapphire_heapAddr

; --- sapphire_appName ---
;
; On entry:	--
;
; On exit:	R0 == pointer to application name (NULL terminated)
;
; Use:		Returns a pointer to the application's name.

		IMPORT	sapphire_appName

; --- sapphire_resetStack ---
;
; On entry:	--
;
; On exit:	R13 == stack pointer
;
; Use:		Resets R13 to point to the top of the stack.

		IMPORT	sapphire_resetStack

; --- sapphire_global ---
;
; On entry:	R0 == magic identifier for global variable
;		R1 == size of area required
;
; On exit:	R0 == pointer to area
;		CS if the area already exists, CC otherwise
;
; Use:		Locates (and creates if necessary) a `named' global area
;		which can be used for inter-section communication without
;		the necessity for dependencies.
;
;		There is a limit on the number of global areas allowed, but
;		this can be raised fairly easily if necessary.
;
;		If an area can't be created, an error is generated.

		IMPORT	sapphire_global

; --- Data relative to R11 ---

		^	0,R11
sapph__R11	#	0			;Make a symbol for R11

sapph_scratchpad EQU	sapph__R11-0		;Scratchpad data area
		[	:LNOT::DEF: sapph__specialWorkspace
sapph_workspace	EQU	sapph__R11-4		;Workspace base address
		]
sapph_stackBase	EQU	sapph__R11-8		;The top of the system stack
sapph_heapBase	EQU	sapph__R11-12		;Base address of the heap
sapph_appName	EQU	sapph__R11-16		;Pointer to application name
sapph_clientWS	EQU	sapph__R11-20		;Address of client's space

; --- Macro: WSPACE ---
;
; Arguments:	addr == address of a word containing the workspace offset
;		reg == (optional) destination register -- default is R12
;		off == (optional) offset from R11 -- default is -4
;
; Use:		Locates a unit's workspace.  The code generated will corrupt
;		R14.  Therefore you must save this register.

		MACRO
$label		WSPACE	$addr,$reg

		IMPORT	|__sph_workoff|,WEAK

		LCLS	r

		[	"$reg"=""
r		SETS	"R12"
		|
r		SETS	"$reg"
		]

		ALIGN
$label
		LDR	$r,$addr

;		LDR	R14,sapph_workspace
		DCD	|__sph_workoff| + &E51BE004

		ADD	$r,R14,$r

		MEND

		]

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

		END
