	ifd _USE020_
	machine	68020
	endc

*--------------------------------------------------------------------------*
	xdef	thxWind_i
thxWind_i
	move.l	4(sp),d0
	movem.l	d3-d7/a2-a6,-(sp)
	move.b	mod_OK(pc),d1
	beq.s	.exit
	move.l	d0,d7
	beq.s	.exit
	bmi.s	.neg
	bsr	THX+thxNextPattern
	bra.s	.exit
.neg	bsr	THX+thxPrevPattern
.exit	movem.l	(sp)+,d3-d7/a2-a6
	rts

*--------------------------------------------------------------------------*
	xdef	thxSignalEnd_i
thxSignalEnd_i
	move.b	mod_OK(pc),d0
	beq.s	.nosong
	move.l	4.w,a6
	suba.l	a1,a1
	jsr	-294(a6)	; _LVOFindTask(a6)
	lea	task(pc),a0
	move.l	d0,(a0)+
	move.l	4(sp),(a0)+
	st.w	(a0)		; set 'signal enable' _last_
.nosong	rts

*--------------------------------------------------------------------------*
	xdef	thxSongEnded
thxSongEnded
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	thx_pSongEnd(a0),d0
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxGetSyncByte
thxGetSyncByte
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	(a0),d0	; thx_pExternalTiming(a0),d0
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxGetNumSongs
thxGetNumSongs
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	thx_pSubsongs(a0),d0
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxSetSong_i
thxSetSong_i
	bsr.s	thxStop
	bsr.s	thxGetNumSongs
	move.l	4(sp),d1	; get arg from E
	cmp.l	d0,d1
	bhi.s	.exit
	move.l	d1,d0
	move.b	mod_OK(pc),d1
	beq.s	.exit
	lea	song(pc),a0
	move.w	d0,(a0)
	movem.l	d3-d7/a2-a6,-(sp)
	moveq	#1,d1
	bsr	THX+thxInitSubSong
	movem.l	(sp)+,d3-d7/a2-a6
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxGetVolume
thxGetVolume
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	thx_pMainVolume(a0),d0
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxSetVolume_i
thxSetVolume_i
	move.l	4(sp),d0
	cmp.l	#64,d0
	bhi.s	.exit
	move.l	THX+thxBSS_P(pc),d1
	beq.s	.exit
	move.l	d1,a0
	move.b	d0,thx_pMainVolume(a0)
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxPause
thxPause
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	clr.b	thx_pPlaying(a0)
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxPlay
thxPlay
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	st.b	thx_pPlaying(a0)
.exit	rts

*--------------------------------------------------------------------------*
	xdef	thxStop
thxStop
	movem.l	d3-d7/a2-a6,-(sp)
	move.b	mod_OK(pc),d0
	beq.s	.nosong
	lea	dosig(pc),a0
	clr.w	(a0)
	bsr	THX+thxStopSong
	bsr.s	thxPause
	move.l	mod(pc),d0
	beq.s	.nosong
	move.l	d0,a0
	bsr	THX+thxInitModule
	moveq	#0,d0
	lea	song(pc),a0
	move.w	(a0),d0
	moveq	#1,d1		; don't play immediately
	bsr	THX+thxInitSubSong
.nosong	movem.l	(sp)+,d3-d7/a2-a6
	rts

*--------------------------------------------------------------------------*
	xdef	thxInit_i
thxInit_i
	lea	mod(pc),a0
	move.l	4(sp),(a0)
	lea	mod_OK(pc),a0
	clr.b	(a0)			; mod is NOT ok until we say so
	lea	song(pc),a0
	clr.w	(a0)
	movem.l	d3-d7/a2-a6,-(sp)	; 40 bytes onto stack
	move.b	init_OK(pc),d0
	bne.s	.init_d
	moveq	#0,d0
	moveq	#0,d1
	sub.l	a0,a0	;auto-allocate public (fast)
	sub.l	a1,a1	;auto-allocate chip
	bsr	THX+thxInitPlayer
	tst.l	d0
	bne	.fail
	lea	init_OK(pc),a0
	st.b	(a0)

.init_d	move.l	mod(pc),d0
	beq.s	.nomod
	move.l	d0,a0
	bsr	THX+thxInitModule
	moveq	#0,d0
	moveq	#1,d1		; don't play immediately
	bsr	THX+thxInitSubSong


.nomod	move.b	cia_OK(pc),d0
	bne.s	.inimod
	lea	vbcode(pc),a0
	moveq	#0,d0
	bsr	THX+thxInitCIA
	tst.l	d0
	bne.s	.nocia
	lea	cia_OK(pc),a0
	st.b	(a0)
	bra.s	.inimod

.nocia	move.b	vb_OK(pc),d0
	bne.s	.inimod
	lea	int(pc),a0
	clr.l	(a0)+
	clr.l	(a0)+
	lea	intcode(pc),a0
	lea	vbcode(pc),a1
	move.l	a1,(a0)
	lea	intname(pc),a0
	lea	vbname(pc),a1
	move.l	a1,(a0)
	moveq	#5,d0
	lea	int(pc),a1
	move.l	4.w,a6
	jsr	-168(a6)	; _LVOAddIntServer(a6)
	lea	vb_OK(pc),a0
	st.b	(a0)

.inimod	move.l	mod(pc),d0
	beq.s	.done
	move.l	d0,a0
	bsr	THX+thxInitModule
	tst.l	d0
	bne.s	.fail

	moveq	#0,d0
	moveq	#1,d1
	bsr	THX+thxInitSubSong

	lea	mod_OK(pc),a0
	st.b	(a0)

.done	moveq	#0,d0
	bra.s	.exit

.fail	bsr.s	thxFree
	moveq	#-1,d0
.exit	movem.l	(sp)+,d3-d7/a2-a6
	rts

*--------------------------------------------------------------------------*
	xdef	thxFree
thxFree	movem.l	d3-d7/a2-a6,-(sp)	; 40 bytes onto stack
	bsr	thxStop

	move.b	cia_OK(pc),d0
	beq.s	.nocia
	bsr	THX+thxKillCIA
	
.nocia	move.b	vb_OK(pc),d0
	beq.s	.novb
	moveq	#5,d0
	lea	int(pc),a1
	move.l	4.w,a6
	jsr	-174(a6)	; _LVORemIntServer(a6)

.novb	move.b	init_OK(pc),d0
	beq.s	.noinit
	bsr.s	THX+thxKillPlayer

.noinit	lea	cia_OK(pc),a2
	clr.l	(a2)		; clear cia_OK, vb_OK, init_OK and mod_OK
	movem.l	(sp)+,d3-d7/a2-a6
	rts

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

vbcode	movem.l	d0-d7/a0-a6,-(sp)
	move.l	THX+thxBSS_P(pc),a0
	tst.b	thx_pPlaying(a0)
	beq.s	.exit

	tst.b	thx_pSongEnd(a0)
	beq.s	.play		; don't signal if not songend
	move.w	dosig(pc),d0
	beq.s	.play		; don't signal if dosig=0
	move.l	4.w,a6
	move.l	task(pc),a1
	move.l	signal(pc),d0
	jsr	-324(a6)	; _LVOSignal(a6)
	lea	dosig(pc),a0
	clr.w	(a0)

.play	bsr.s	THX+thxInterrupt
.exit	movem.l	(sp)+,d0-d7/a0-a6
	ori.w	#%100,ccr	; set Z flag
	rts

	include	thx-offsets.i
THX
	ifd	_USE020_
	incbin	thx-replayer020.bin
	else
	incbin	thx-replayer000.bin
	endc

cia_OK	dc.b	0	; int routine is CIA, and is initialised and running
vb_OK	dc.b	0	; int routine is VBI, and is initialised and running
init_OK	dc.b	0	; initialisation (memory, etc) is done
mod_OK	dc.b	0	; module is initialised, play can commence

mod	dc.l	0	; ptr to current module
song	dc.w	0	; playing song

task	dc.l	0	; ptr to task to signal
signal	dc.l	0	; signals to send
dosig	dc.w	0	; true if we should signal sometime, false if not

int	dc.l	0,0	; succ,pred
	dc.b	2,0	; NT_INTERRUPT,pri=0
intname	dc.l	0,0	; name, iv_data
intcode	dc.l	0	; iv_code

vbname	dc.b	"Nora Batty's original THX2 player (tm)",0
	cnop	0,4
