* Routinesheader
*
*	Name:		libdata.a
*	Main:		xpkmaster
*	Versionstring:	$VER: libdata.a 4.14 (06.06.1997)
*	Author:		SDI
*	Distribution:	PD
*	Description:	all the library startup data
*
* 3.10  28.10.96 : first real version
* 3.11  25.11.95 : recompiled with SAS 6.57
* 4.0   29.12.96 : added some new functions, OS2.0 only, corrected error in
*	locale handling (Ooops - (A2) instead of A2 :-)
* 4.1   11.01.97 : hopefully fixed buffer overworking bug
* 4.2   30.01.97 : mem bug still was not completely fixed
* 4.3   01.03.97 : changed semaphore structure
* 4.4   09.03.97 : added preferences stuff
* 4.5   23.03.97 : fixed Enforcer Hits
* 4.6   28.03.97 : fixed prefs stuff
* 4.7   31.03.97 : changed XpkQuery and Password stuff
* 4.8   02.04.97 : changed a lot, removed some stuff
* 4.9   03.04.97 : preferences buffers now via hookread and not direct
* 4.10  04.04.97 : minor fixes
* 4.11  10.04.97 : Password request now restores FirstScreen
* 4.12  28.04.97 : fixed mem-corrupt bug and changed progress time calc
* 4.13  11.05.97 : fixed reported errors in Expunge code
* 4.14  06.06.97 : added DEBUG output

	NOLIST
	INCLUDE	"AINCLUDE:IncDirs.i" *sets all includedirs, needed for my ASM
	INCLUDE "exec/types.i"
	INCLUDE "exec/initializers.i"
	INCLUDE "exec/libraries.i"
	INCLUDE "exec/lists.i"
	INCLUDE "exec/alerts.i"
	INCLUDE "exec/resident.i"
	INCLUDE "dos/dos.i"
	INCLUDE "libraries/locale.i"
	INCLUDE	"lvo.i"
	LIST

VERSION		EQU	4
REVISION	EQU	14
MINOSVERSION	EQU	37

STRINGANZ	EQU	10
STRINGSTART	EQU	0
ERRSTRINGANZ	EQU	34
ERRSTRINGSTART	EQU	200

VSTRING	MACRO
		DC.B	'xpkmaster 4.14 (06.06.97)',13,10,0
	ENDM

;	XDEF	InitTable
;	XDEF	Open
;	XDEF	Close
;	XDEF	Expunge
;	XDEF	Null
;	XDEF	LibName
	XDEF	_DOSBase,_DosBase,_IntuitionBase,_UtilityBase,_XpkBase
	XDEF	_MainVersion

	XREF	_LIBXpkExamine,_LIBXpkPack
	XREF	_LIBXpkUnpack,_LIBXpkOpen,_LIBXpkRead,_LIBXpkWrite
	XREF	_LIBXpkSeek,_LIBXpkClose,_LIBXpkQuery
	XREF	_LIBXpkAllocObject,_LIBXpkFreeObject
	XREF	_LIBXpkFault,_LIBXpkPrintFault
	XREF	_LIBXpkPassRequest
	XREF	_strings,_XpkErrs

	SECTION	"XPK_LibStart",Code
Start	MOVEQ	#-1,d0	; return an error in case someone
	RTS		; tried to run as a program

; A romtag structure.  Both "exec" and "ramlib" look for this structure to
; discover magic constants about you (such as where to start running you
; from...).

RomTag		DC.W	RTC_MATCHWORD	; UWORD rt_MatchWord
		DC.L	RomTag		; APTR  rt_MatchTag
		DC.L	ENDCODE		; APTR  rt_EndSkip
		DC.B	RTF_AUTOINIT	; UBYTE rt_Flags
_MainVersion	DC.B	VERSION		; UBYTE rt_Version
		DC.B	NT_LIBRARY	; UBYTE rt_type
		DC.B	0		; BYTE  rt_Pri
		DC.L	LibName		; APTR  rt_Name
		DC.L	IDString	; APTR  rt_IDString
		DC.L	InitTable	; APTR  rt_Init  table for InitResident()

LibName		DC.B	'xpkmaster.library',0
DosName		DC.B	'dos.library',0
INTUITIONNAME	DC.B	'intuition.library',0
UTILITYNAME	DC.B	'utility.library',0
LOCALENAME	DC.B	'locale.library',0
CATALOGNAME	DC.B	'xpkmaster.catalog',0
		CNOP	0,2
IDString	VSTRING
  		CNOP	0,2	; word alignement

; The romtag specified that we were "RTF_AUTOINIT". This means that the
; rt_Init structure member points to one of these tables below. If the
; AUTOINIT bit was not set then RT_INIT would point to a routine to run.

InitTable:
	DC.L	LIB_SIZE		; size of library base data space
	DC.L	funcTable		; pointer to function initializers
	DC.L	dataTable		; pointer to data initializers
	DC.L	initRoutine		; routine to run

funcTable:
;------ standard system routines
	DC.L	Open
	DC.L	Close
	DC.L	Expunge
	DC.L	Null
;------ my libraries definitions
	DC.L	Null
	DC.L	_LIBXpkExamine
	DC.L	_LIBXpkPack
	DC.L	_LIBXpkUnpack
	DC.L	_LIBXpkOpen
	DC.L	_LIBXpkRead
	DC.L	_LIBXpkWrite
	DC.L	_LIBXpkSeek
	DC.L	_LIBXpkClose
	DC.L	_LIBXpkQuery
	DC.L	_LIBXpkAllocObject
	DC.L	_LIBXpkFreeObject
	DC.L	_LIBXpkPrintFault
	DC.L	_LIBXpkFault
	DC.L	_LIBXpkPassRequest
;------ function table end marker
	DC.L	-1

; The data table initializes static data structures. The format is specified
; in exec/InitStruct routine's manual pages. The INITBYTE/INITWORD/INITLONG
; routines are in the file "exec/initializers.i". The first argument is the
; offset from the library base for this byte/word/long. The second argument
; is the value to put in that cell. The table is null terminated.

dataTable:
	INITBYTE	LN_TYPE,NT_LIBRARY
	INITLONG	LN_NAME,LibName
	INITBYTE	LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
	INITWORD	LIB_VERSION,VERSION
	INITWORD	LIB_REVISION,REVISION
	INITLONG	LIB_IDSTRING,IDString
	DC.L		0

; This routine gets called after the library has been allocated. The library
; pointer is in D0. The segment list is in A0. If it returns non-zero then
; the library will be linked into the library list.

initRoutine:
;------ get the library pointer into a convenient A register
	MOVEM.L	A2/D6/D7/A6/A5,-(A7)
	MOVEA.L	D0,A5
	MOVE.L	D0,_XpkBase		; init XpkBase for internal calls
;------ save a pointer to our loaded code
	MOVE.L	A0,SegList
;
; specific openings here
;
	MOVEA.L	4.W,A6
	MOVEQ	#MINOSVERSION,D0
	LEA	DosName(PC),A1
	JSR	_LVOOpenLibrary(A6)
	MOVE.L	D0,_DOSBase
	BEQ.W	.kill
	MOVEQ	#MINOSVERSION,D0
	LEA	INTUITIONNAME(PC),A1
	JSR	_LVOOpenLibrary(A6)
	MOVE.L	D0,_IntuitionBase
	BEQ.B	.kill
	MOVEQ	#MINOSVERSION,D0
	LEA	UTILITYNAME(PC),A1
	JSR	_LVOOpenLibrary(A6)
	MOVE.L	D0,_UtilityBase
	BEQ.B	.kill
	MOVEQ	#38,D0
	LEA	LOCALENAME(PC),A1
	JSR	_LVOOpenLibrary(A6)
	MOVE.L	D0,_LocaleBase
	BEQ.B	.endok
	MOVEA.L	D0,A6
	SUBA.L	A0,A0
	JSR	_LVOOpenLocale(A6)
	MOVE.L	D0,_Locale
	BEQ.B	.endok
	MOVEA.L	D0,A0
	LEA	CATALOGNAME(PC),A1
	LEA	CATALOGTAGS(PC),A2
	JSR	_LVOOpenCatalogA(A6)
	MOVE.L	D0,_Catalog
	BEQ.B	.endok
	MOVEQ	#STRINGANZ-1,D6
	MOVEQ	#STRINGSTART,D7
	LEA	_strings,A2
	BSR.B	DoLocale
	MOVEQ	#ERRSTRINGANZ-1,D6
	MOVE.L	#ERRSTRINGSTART,D7
	LEA	_XpkErrs,A2
	BSR.B	DoLocale

.endok	MOVE.L	A5,D0
.end	MOVEM.L	(A7)+,A2/D6/D7/A6/A5
	RTS
.kill	BSR.W	KillLibs
	MOVEQ	#0,D0
	BRA.B	.end

DoLocale	MOVE.L	_Catalog(PC),A0
		MOVE.L	D7,D0
		MOVEA.L	(A2),A1
		ADDQ.L	#1,D7
		JSR	_LVOGetCatalogStr(A6)
		MOVE.L	D0,(A2)+
		DBRA	D6,DoLocale
		RTS

; here begins the system interface commands. When the user calls
; OpenLibrary/CloseLibrary/RemoveLibrary, this eventually gets translated
; into a call to the following routines (Open/Close/Expunge). Exec has
; already put our library pointer in A6 for us. Exec has turned off task
; switching while in these routines (via Forbid/Permit), so we should not
; take too long in them.

; Open returns the library pointer in D0 if the open was successful. If the
; open failed then null is returned. It might fail if we allocated memory
; on each open, or if only one application could have the library open at
; a time...

Open:		; (libptr:A6, version:D0)
;------ mark us as having another opener
	ADDQ.W	#1,LIB_OPENCNT(A6)
	BCLR	#LIBB_DELEXP,LIB_FLAGS(A6)
	MOVE.L	A6,D0
	RTS

; There are two different things that might be returned from the Close
; routine. If the library is no longer open and there is a delayed expunge
; then Close should return the segment list (as given to Init). Otherwise
; close should return NULL.

Close:		; (libptr:A6)
;------ set the return value
	MOVEQ	#0,D0
;------ mark us as having one fewer openers
	SUBQ.W   #1,LIB_OPENCNT(A6)
;------ see if there is anyone left with us open
	BNE.B	.OneLeft
;------ do the expunge
	BTST	#LIBB_DELEXP,LIB_FLAGS(A6)
	BEQ.B	.OneLeft
	BSR.B	Expunge
.OneLeft
	RTS

; There are two different things that might be returned from the Expunge
; routine. If the library is no longer open then Expunge should return the
; segment list (as given to Init). Otherwise Expunge should set the delayed
; expunge flag and return NULL.
; One other important note: because Expunge is called from the memory
; allocator, it may NEVER Wait() or otherwise take long time to complete.

Expunge:	; (libptr: A6)
	MOVEM.L	D2/A5/A6,-(A7)
	MOVEA.L	A6,A5
	MOVEA.L	4.W,A6
;------ see if anyone has us open
	TST.W	LIB_OPENCNT(A5)
	BEQ.B	.DoIt
	BSET	#LIBB_DELEXP,LIB_FLAGS(A5)
	MOVEQ	#0,D0
	BRA.B	.Expunge_End
.DoIt
;------ go ahead and get rid of us.  Store our seglist in D2
	MOVE.L	SegList(PC),D2
;------ unlink from library list
	MOVEA.L	A5,A1
	JSR	_LVORemove(A6)
;
; device specific closings here...
	BSR.B	KillLibs
;
;------ free our memory
	MOVEQ	#0,D0
	MOVEA.L	A5,A1
	MOVE.W	LIB_NEGSIZE(A5),D0
	SUBA.L	D0,A1
	ADD.W	LIB_POSSIZE(A5),D0
	MOVEA.L	4.W,A6
	JSR	_LVOFreeMem(A6)
;------ set up our return value
	MOVE.L	D2,D0

.Expunge_End
	MOVEM.L	(A7)+,D2/A5/A6
	RTS

KillLibs:	MOVEA.L	4.W,A6
		MOVEA.L	_IntuitionBase(PC),A1
		MOVE.L	A1,D0				; for checking
		BEQ.B	.utility
		JSR	_LVOCloseLibrary(A6)
.utility	MOVEA.L	_UtilityBase(PC),A1
		MOVE.L	A1,D0
		BEQ.B	.dos
		JSR	_LVOCloseLibrary(A6)
.dos		MOVEA.L	_DOSBase(PC),A1
		MOVE.L	A1,D0
		BEQ.B	.locale
		JSR	_LVOCloseLibrary(A6)
.locale		MOVEA.L	_LocaleBase(PC),A6
		MOVE.L	A6,D0
		BEQ.B	.endlibs
		MOVEA.L	_Catalog(PC),A0
		MOVE.L	A0,D0
		BEQ.B	.closelocale
		JSR	_LVOCloseCatalog(A6)
.closelocale	MOVEA.L	_Locale(PC),A0
		MOVE.L	A0,D0
		BEQ.B	.closelibrary
		JSR	_LVOCloseLocale(A6)
.closelibrary	MOVEA.L	A6,A1
		MOVEA.L	4.W,A6
		JSR	_LVOCloseLibrary(A6)
.endlibs	RTS

Null:	MOVEQ	#0,D0
	RTS

CATALOGTAGS:	DC.L	OC_Version,2,TAG_DONE
SegList:	DC.L	0	* set by Init
_Catalog:	DC.L	0	* access only by Init
_Locale:	DC.L	0	* or by Expunge, no need to access
_LocaleBase:	DC.L	0	* locale in program
_DosBase:
_DOSBase:	DC.L	0	* set by Init	these are library globals
_UtilityBase:	DC.L	0	* set by Init	in C Code read only !!!
_XpkBase:	DC.L	0	* set by Init
ENDCODE:
_IntuitionBase:	DC.L	0	* set by Init
		END
