;; LibHead.asm
;;		Copyright 1986, James M Synge
;;
;; This file contains the data structures and an
;; initialization routine.
;;
	far	code	; Absolute addresses please.
	far	data	; Me too!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; To protect against the library accidentally being invoked
;; as a program, we return an error value.  This code must
;; be the first thing in the library.

	cseg		; Code segment
	moveq.l	#20,d0	; AmigaDOS Fatal Error
	rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Declaration Section:
;;
;; Imported Global Variables and Constants:

	dseg			; Data segment

	public	_LibraryName	; char * LibraryName
	public	_LibraryId	; char * LibraryId

	public	LibVersion	; Current version number.
				; Will be checked by
				; OpenLibrary() against the
				; requested version number.

	public	_LibInitBlock	; Defined in Library.c

	public	_SysBase	; Library Base Pointer for
				; exec.library

;; Exported Global Variables:

	global	_LibraryBase,4	; Address of this library.

	global	_LibSegList,4	; Address of first entry in
				; this library's seg list.
;; Imported Functions:

	cseg

	public	_LibraryInit	; This is the routine which
				; handles most of the
				; details of preparing the
				; library, except for regs.
;; Exported Functions:

	public	__LibInitCode	; Referenced by LibInitBlock
				; in Library.c

	public	_regA6		; Returns register A6.

;; Constants:
;; (These should be set in the Amiga supplied include files
;;  but these aren't available for Manx 3.2a)

RTC_MATCHWORD	EQU	$4afc	; An illegal instruction
RTF_AUTOINIT	EQU	(1 << 7)
NT_LIBRARY	EQU	9	; As defined in exec/nodes.i

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Resident (RomTag) Structure
;; This structure must be in the first hunk (AmigaDOS Hunk)
;; of the library.  Defined in "exec/resident.h"

RomTag:
	DC.W	RTC_MATCHWORD	; This value is an illegal
				; instruction.  It is used
				; to mark the beginning of a
				; rom tag.  The next
				; longword confirms it.

	DC.L	RomTag		; The RomTag points to
				; itself as confirmation
				; that this is a RomTag.

	DC.L	EndMarker	; The address of a location
				; after this structure, but
				; still in the same hunk.
				; The simplest solution is
				; to place the label right
				; after this structure.

	DC.B	RTF_AUTOINIT	; Auto-initialize flag, see
				; Library.c for description

	DC.B	LibVersion	; Library version, will be
				; checked against the value
				; requested in the
				; OpenLibrary() call.

	DC.B	NT_LIBRARY	; This is the Resident
				; struct of a library.

	DC.B	0		; Execution priority.
				; Not used in libraries.

	DC.L	_LibraryName	; Pointer to library name.

	DC.L	_LibraryId	; Pointer to full library id

	DC.L	_LibInitBlock	; Pointer to initialization
				; descriptor block or code.
				; See Library.c
;;	End of the RomTag

EndMarker	; Simplest place for this marker

; See Interface.asm for a complete explanation of:
AztecBugList:	reg	a4/a6

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; LibInitCode, is called from within MakeLibrary(), after
;; all the memory has been allocated, the jump table has
;; been constructed, and the InitStruct() call has been
;; made.  It is identified as the initialization code by
;; LibInitBlock in Library.c.  LibraryInit() returns the
;; value (in D0 as per the calling standard) which is then
;; returned to MakeLibrary().  If it is zero, the library
;; wouldn't be added to the exec's library list and thus
;; cann't be opened.

__LibInitCode:
	move.l	a6,_SysBase	; Store away these three
				; registers which tell us
	move.l	d0,_LibraryBase	; we are and where the rest
	move.l	a0,_LibSegList	; of the world can be found.

	; Forgive me, Oh Lord, for I have sinned...
	movem.l	AztecBugList,-(sp)

	; Now call the C routine LibraryInit() with the
	; address of our Library struct as its only argument.

	move.l	d0,-(sp)	; Push LibraryBase
	jsr	_LibraryInit	; Call
	addq.l	#4,sp		; Pop LibraryBase

	; Restore the registers
	movem.l	(sp)+,AztecBugList

	rts			; Now return to our caller.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This trite little routine is included so that those
;; library specific routines which wish to access the struct
;; Library may do so by calling regA6() in order to get the
;; value of the Library Base Pointer.
;; Example Code Fragment:
;;
;;		struct Library *lib, *regA6();
;;		lib = regA6();
;;		return(lib -> lib_IdString);
;;
;; An alternate (and perhaps safer method) is to use the
;; _LibraryBase global variable which is setup by the
;; __LibInitCode routine.

	public _regA6
_regA6:	move.l	a6,d0
	rts

	ds.w	0	; Align to a word boundary
        END
