; based on sample.library

	STRUCTURE ThxPlayBase,LIB_SIZE
	UBYTE	thx_Flags
	UBYTE	thx_pad
	ULONG	thx_SegList
	APTR	thx_OwnerTask		; task that owns THX
	STRUCT	thx_Sem,SS_SIZE		; semaphore to protect the above
	LABEL	ThxPlayBase_SIZEOF

	moveq	#-1,d0
	rts

RomTag	dc.w	RTC_MATCHWORD
	dc.l	RomTag,EndCode
	dc.b	RTF_AUTOINIT,VERSION,NT_LIBRARY,0
	dc.l	LibName,IDStr,InitTbl

LibName	dc.b	'thxplay.library',0,'$VER: '
IDStr	VSTRING
	ifd	USE020
	dc.b	'68020 version',0
	endc
	cnop	0,4

InitTbl	dc.l	ThxPlayBase_SIZEOF,funcTbl,dataTbl,Init

func	macro
	dc.w	\1 - funcTbl
	endm
funcTbl	dc.w	-1
	func	Open
	func	Close
	func	Expunge
	func	Null

; our functions start here
	func	thxInit_library
	func	thxFree_library

	func	thxPlay
	func	thxStop
	func	thxPause
	func	thxWind

	func	thxGetVolume
	func	thxSetVolume

	func	thxGetNumSongs
	func	thxSetSong

	func	thxPlayNote
	func	thxStopNote
	func	thxNoteFX
	func	Null				; reserved slot

	func	thxSignalEnd
	func	thxSongEnded
	func	thxSyncByte
	func	thxPlaytime

	dc.w	-1


dataTbl	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,	IDStr
	dc.l	0

*--------------------------------------

Init	movem.l	a0/a1/d1/a5,-(sp)
	move.l	d0,a5
	move.l	a0,thx_SegList(a5)
	lea	thx_Sem(a5),a0
	jsr	_LVOInitSemaphore(a6)

	ifd	USE020
	move.w	AttnFlags(a6),d1
	moveq	#0,d0
	btst.b	#AFB_68020,d1
	beq.s	.exit
	endc

	move.l	a5,d0
.exit	movem.l	(sp)+,a0/a1/d1/a5
	rts

*--------------------------------------

Open	addq.w	#1,LIB_OPENCNT(a6)
	bclr	#LIBB_DELEXP,thx_Flags(a6)
	move.l	a6,d0
	rts

Close	moveq	#0,d0
	subq.w	#1,LIB_OPENCNT(a6)
	bne.s	.noexp
	btst	#LIBB_DELEXP,thx_Flags(a6)
	beq.s	.noexp
	bsr.s	Expunge
.noexp	rts

Expunge	movem.l	d2/a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	tst.w	LIB_OPENCNT(a5)
	beq	.close
	bset	#LIBB_DELEXP,thx_Flags(a5)
	moveq	#0,d0
	bra.s	.noexp
.close	move.l	thx_SegList(a5),d2
	move.l	a5,a1
	move.l	4.w,a6
	jsr	_LVORemove(a6)
	moveq	#0,d0
	move.l	a5,a1
	move.w	LIB_NEGSIZE(a5),d0
	sub.l	d0,a1
	add.w	LIB_POSSIZE(a5),d0
	jsr	_LVOFreeMem(a6)
	move.l	d2,d0
.noexp	movem.l	(sp)+,d2/a5/a6
	rts

Null	moveq	#0,d0
	rts

*--------------------------------------

; special semaphore/owner based wrappers for thxInit() and thxFree()

thxInit_library
	movem.l	a0/a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	lea	thx_Sem(a5),a0
	jsr	_LVOObtainSemaphore(a6)
	suba.l	a1,a1
	jsr	_LVOFindTask(a6)	; d0 = ourselves

	lea	thx_OwnerTask(a5),a0
	cmp.l	(a0),d0			; check if owner = ourselves
	beq.s	.got			; continue OK if we own THX
	tst.l	(a0)			; otherwise, see if owner = nobody
	beq.s	.take			; if noone owns THX, we take it

	lea	thx_Sem(a5),a0		; otherwise, we fail to thxInit()
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a0/a5/a6
	moveq	#-1,d0	; FAIL
	rts

.take	move.l	d0,(a0)			; set owner = ourselves
.got	lea	thx_Sem(a5),a0
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a0/a5/a6

	bsr	thxInit			; call the real thxInit()
	tst.l	d0
	beq.s	.exit			; if this fails, also call
	bsr	thxFree_library		; our redefined thxFree()
.exit	rts


thxFree_library
	movem.l	a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	lea	thx_Sem(a5),a0
	jsr	_LVOObtainSemaphore(a6)
	suba.l	a1,a1
	jsr	_LVOFindTask(a6)	; d0 = ourselves

	move.l	thx_OwnerTask(a5),d1	; d1 = owner
	cmp.l	d0,d1			; do we own THX?
	bne.s	.exit			; no! don't allow freeing of THX
	bsr	thxFree			; otherwise, call the real thxFree()
	clr.l	thx_OwnerTask(a5)	; then set owner = nobody

.exit	lea	thx_Sem(a5),a0
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a5/a6
	rts

EndCode
