*
*	Name:				omnilib.a
*
*	Description:	Universal Amiga shared library controller
*
*	Copyright:		1991-1993 by David Jones.
*
*	Distribution:
*		This program 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 of the License, or
*		(at your option) any later version.
*
*		This program 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 this program; if not, write to:
*
*				The Free Software Foundation		David Jones
*				675 Mass Ave							6730 Tooney Drive
*				Cambridge, MA							Orleans, Ontario
*				02139										K1C 6R4
*				USA										Canada
*
*	Usenet:	gnu@prep.ai.mit.edu					aa457@freenet.carleton.ca
*	Fidonet:												1:163/109.8
*
*		$Log: $
*
*

		include 'exec/types.i'
		include 'exec/libraries.i'
		include 'exec/resident.i'
		include 'exec/alerts.i'
		include 'exec/semaphores.i'
		include 'utility/hooks.i'
		include 'dejmac.i'
		include 'exec.offsets'
		
		STRUCTURE	myLibBase,0
		  STRUCT	ml_LibNode,LIB_SIZE
		  LONG		ml_SegList
		  BYTE		ml_Flags
		  BYTE		ml_Pad
		  LONG		ml_A4
		  STRUCT		ml_Lock,SS_SIZE
		LABEL		MYLIB_SIZEOF

		XREF	_LibName
		XREF	_LibID
		XREF	_FuncTable
		XREF	_LibInit
		XREF	_LibOpen
		XREF	_LibClose
		XREF	_LibExpunge
		XREF	_Version
		XREF	_Revision

		XREF	_LinkerDB
		XREF	_LibBase
		XREF	_DOSBase
		XREF	_SysBase


		SECTION	Omnilib, CODE
		XDEF	_LIBInit
		XDEF	_LIBOpen
		XDEF	_LIBClose
		XDEF	_LIBExpunge
		XDEF	_LIBExtFunc

_LIBInit:
		move.l	A6,_SysBase
		move.l	D0,_LibBase	; set global variables
		move.l	D0,A1		; initialize base
		move.l	A0,ml_SegList(A1)
		move.l	#_LinkerDB,ml_A4(A1)
		move.b	#NT_LIBRARY,LN_TYPE(A1)
		move.l	#_LibName,LN_NAME(A1)
		move.b	#LIBF_SUMUSED!LIBF_CHANGED,LIB_FLAGS(A1)
		move.w	_Version,LIB_VERSION(A1)
		move.w	_Revision,LIB_REVISION(A1)
		move.l	#_LibID,LIB_IDSTRING(A1)
		moveq		#0,D0
		move.w	D0,ml_Flags(A1)
		lea		ml_Lock(A1),A0
		CALL		InitSemaphore
		lea		DosName(PC),A1	; open DOS
		moveq		#0,D0
		CALL		OpenLibrary
		move.l	D0,_DOSBase
		bne.s		1$
		ALERT		AG_OpenLib!AO_DOSLib
1$		jsr		_LibInit	; call user init
		rts


_LIBOpen:
		lea		ml_Lock(A6),A0
		LINKSYS	ObtainSemaphore,_SysBase
		addq.w	#1,LIB_OPENCNT(A6)
		bclr		#LIBB_DELEXP,ml_Flags(A6)
		jsr		_LibOpen	; call user init
		move.l	D0,-(SP)
		lea		ml_Lock(A6),A0
		LINKSYS	ReleaseSemaphore,_SysBase
		move.l	(SP)+,D0
		rts

_LIBExpunge:
		move.l	A6,-(SP)
		move.l	_LibBase,A1
		lea		ml_Lock(A1),A0
		LINKSYS	AttemptSemaphore,_SysBase
		tst.l		D0
		beq.s		2$		; seglist is zero, just like D0
		move.l	_LibBase,A1
		tst.w		LIB_OPENCNT(A1)
		beq.s		1$
		bset		#LIBB_DELEXP,ml_Flags(A1)
		moveq		#0,D0
		bra.s		2$
1$
		jsr		_LibExpunge
		tst.l		D0
		bne.s		3$
		
		move.l	_LibBase,A1
		lea		ml_Lock(A1),A0
		CALLSYS	ReleaseSemaphore,_SysBase
		moveq		#0,D0
		beq.s		2$
3$
		move.l	_LibBase,A1
		CALLSYS	Remove,_SysBase
		move.l	_DOSBase,A1
		CALL		CloseLibrary
		moveq		#0,D0
		move.l	_LibBase,A1
		move.l	ml_SegList(A1),-(SP)
		bsr.s		DropBase
		move.l	(SP)+,D0
2$
		move.l	(SP)+,A6
		rts

DropBase: ; base in A1
		move.l	A1,A0
		move.w	LIB_NEGSIZE(A0),D0
		sub.l		D0,A1
		add.w		LIB_POSSIZE(A0),D0
		CALL		FreeMem
		rts

_LIBClose:
		move.l	_LibBase,A0 ; semaphore on real base
		add.w		#ml_Lock,A0
		LINKSYS	ObtainSemaphore,_SysBase
		jsr		_LibClose
		cmp.l		_LibBase,A6
		beq.s		2$
		move.l	A6,A1
		bsr.s		DropBase		; if base was cloned, kill it and use real base
		move.l	_LibBase,A6
2$		moveq		#0,D0
		subq.w	#1,LIB_OPENCNT(A6)
		bne.s		1$
		btst		#LIBB_DELEXP,ml_Flags(A6)
		beq.s		1$
		bsr		_LIBExpunge
1$		move.l	D0,-(SP)
		lea		ml_Lock(A6),A0
		LINKSYS	ReleaseSemaphore,_SysBase
		move.l	(SP)+,D0
		rts

_LIBExtFunc:
		moveq		#0,D0
		rts

DosName:
		dc.b	'dos.library',0
		ds.w	0

		SECTION	RexxQuery,CODE
		XDEF	_LIBRexxQuery
		XREF	_LibRexxQuery

_LIBRexxQuery:
		link		A5,#-4
		lea		-4(A5),A1	; pointer for return value
		jsr		_LibRexxQuery
		move.l	-4(A5),A0	;	fetch return value
		unlk		A5
		rts

      ENDC

		SECTION	CallHookRes,CODE
		XDEF	_CallHookRes
		XDEF	_Geta4
		
_CallHookRes:
		move.l	h_Entry(A0),-(SP)
		rts

		SECTION	CloneBase,CODE
		XDEF	_CloneBase

_Geta4:
		move.l	A4,D0
		rts

_CloneBase:

		END
