;
;	Beyond The Dark: Generic DPMS Library Startup Code
;
;	(c) Copyright 1995 Matthias Scheler
;	    All Rights Reserved
;

		CSECT text,0

		NOLIST
		INCLUDE	"exec/types.i"
		INCLUDE	"exec/libraries.i"
		INCLUDE	"exec/resident.i"
		INCLUDE	"exec/initializers.i"
		INCLUDE	"exec/semaphores.i"
		INCLUDE	"dos/dos.i"
		LIST

;	Macros

XLIB:		MACRO
		XREF _LVO\1
		ENDM

CALL:		MACRO
		jsr _LVO\1(a6)
		ENDM

;	External References

		XREF	_LinkerDB

		XREF	_MyDPMSName
		XREF	_MyDPMSID
		XREF	_MyDPMSLibInit
		XREF	_MyDPMSLibFree

		XREF	_QueryMyDPMS
		XREF	_SetMyDPMSLevel

		XLIB	Remove
		XLIB	FreeMem
		XLIB	CloseLibrary
		XLIB	OpenLibrary
		XLIB	InitSemaphore
		XLIB	ObtainSemaphore
		XLIB	ReleaseSemaphore

;	External Definitions

		XDEF	_SysBase

;	Our Library Structure

		STRUCTURE BTDBase,LIB_SIZE
		BPTR	BB_SegList
		STRUCT	BB_Semaphore,SS_SIZE
		LABEL	BB_SIZE

;	Program Code

		moveq	#-1,d0
		rts

;	Library Resident Module Tag

LibResTag:	dc.w	RTC_MATCHWORD
		dc.l	LibResTag
		dc.l	LibResTag+RT_SIZE
		dc.b	RTF_AUTOINIT
		dc.b	VERSION
		dc.b	NT_LIBRARY
		dc.b	0
		dc.l	_MyDPMSName,_MyDPMSID
		dc.l	LibInit

;	Initialization Table for Library Structure

LibInit:	dc.l	BB_SIZE
		dc.l	FuncTab
		dc.l	DataTab
		dc.l	Init

FuncTab:	dc.l	Open
		dc.l	Close
		dc.l	Expunge
		dc.l	ReturnNull

		dc.l	QueryMyDPMS
		dc.l	SetMyDPMSLevel

		dc.l	-1

DataTab:	INITBYTE LN_TYPE,NT_LIBRARY
                INITLONG LN_NAME,_MyDPMSName
                INITBYTE LIB_FLAGS,LIBF_SUMUSED+LIBF_CHANGED
                INITWORD LIB_VERSION,VERSION
                INITWORD LIB_REVISION,REVISION
                INITLONG LIB_IDSTRING,_MyDPMSID
                dc.l	0

;	Init Function

Init:		movem.l	a4/a5,-(sp)
		lea	_LinkerDB,a4

		move.l	d0,a5
		move.l	a0,BB_SegList(a5)
		move.l	a6,_SysBase(a4)

		lea	BB_Semaphore(a5),a0
		CALL	InitSemaphore

		move.l	a5,d0
		movem.l	(sp)+,a4/a5
		rts

;	Open Function

Open:		movem.l	d2/a4-a6,-(sp)
		lea	_LinkerDB,a4
		move.l	a6,d2
		move.l	a6,a5
		move.l	_SysBase(a4),a6

		lea	BB_Semaphore(a5),a0
		CALL	ObtainSemaphore

		addq.w	#1,LIB_OPENCNT(a5)
		bclr	#LIBB_DELEXP,LIB_FLAGS(a5)

		cmp.w	#1,LIB_OPENCNT(a5)
		bne.s	InitDone

		jsr	_MyDPMSLibInit
		tst.l	d0
		bne.s	InitDone

		subq.w	#1,LIB_OPENCNT(a5)
		moveq	#0,d2

InitDone:	lea	BB_Semaphore(a5),a0
		CALL	ReleaseSemaphore

		move.l	d2,d0
		movem.l	(sp)+,d2/a4-a6
		rts

;	Close Function

Close:		movem.l	a4-a6,-(sp)
		lea	_LinkerDB,a4
		move.l	a6,a5
		move.l	_SysBase(a4),a6

		lea	BB_Semaphore(a5),a0
		CALL	ObtainSemaphore

		subq.w	#1,LIB_OPENCNT(a5)
		bne.s	KeepLibrary

		jsr	_MyDPMSLibFree

		btst	#LIBB_DELEXP,LIB_FLAGS(a6)
		bne.s	KeepLibrary

		lea	BB_Semaphore(a5),a0
		CALL	ReleaseSemaphore
		movem.l	(sp)+,a4-a6
		bra.s	TimeToGo

KeepLibrary:	lea	BB_Semaphore(a5),a0
		CALL	ReleaseSemaphore
		movem.l	(sp)+,a4-a6

ReturnNull:	moveq	#0,d0
		rts

;	Expunge Function

Expunge:        tst.w	LIB_OPENCNT(a6)
                beq.s	TimeToGo

                bset	#LIBB_DELEXP,LIB_FLAGS(a6)
                bra.s	ReturnNull

TimeToGo:	movem.l d2/a4-a6,-(sp)
		lea	_LinkerDB,a4
		move.l	BB_SegList(a6),d2

		move.l	a6,a5
		move.l	a5,a1
		move.l	_SysBase(a4),a6
		CALL	Remove

		move.l	a5,a1
		moveq	#0,d0
		move.w	LIB_NEGSIZE(a5),d0
		sub.w	d0,a1
		add.w	LIB_POSSIZE(a5),d0
		CALL	FreeMem

		move.l	d2,d0
		movem.l	(sp)+,d2/a4-a6
		rts

;	own Library functions

;	return DPMSInfo

QueryMyDPMS:	move.l	a4,-(sp)
		lea	_LinkerDB,a4

		jsr	_QueryMyDPMS

		move.l	(sp)+,a4
		rts

;	set DPMS level

SetMyDPMSLevel:	move.l	a4,-(sp)
		lea	_LinkerDB,a4

		move.l	d0,-(sp)
		move.l	a0,-(sp)
		jsr	_SetMyDPMSLevel
		addq.w	#8,sp

		move.l	(sp)+,a4
		rts

;	Data

		CSECT data,1

_SysBase:	dc.l	0

		END
