*************************************************
* Eliminator Musics by JMP (1988).		*
* Adapted by Mr.STYCKX / Nicolas Pomarède	*
*						*
* Original replay was in $6b24.			*
*						*
* Ripped : 4/05/96				*
* Relocated : 8/05/96				*
* EaglePlayer / Delitracker port : 25/05/96	*
*	Volume					*
*	Balance					*
*	SubSong					*
*	EP_Voices				*
*	EP_StructInit (Analyzer)		*
*************************************************

	opt	o+

	output	ram:CUST.Eliminator


ELIM_TEST	=	0		; 0 => BUILD COMPLETE CUSTOM MODULE
					; 1 => BUILD SMALL CODE FOR TESTING

	section	Elim,code



	incdir	"Include:"
	include	"misc/DeliPlayer.i"
	include	"misc/EaglePlayer.i"


	IFEQ	ELIM_TEST-0			; COMPLETE VERSION


	PLAYERHEADER PlayerTagArray

	dc.b '$VER: Eliminator Musics (1988) custom player V1.0, '
	dc.b 'ripped and adapted by Mr.STYCKX (05/96)',0

	EVEN

PlayerTagArray
	dc.l	DTP_CustomPlayer,1		; CustomPlayer - Tag (important !!!)
	dc.l	DTP_Flags,PLYF_CUSTOM

	dc.l	DTP_PlayerVersion,1<<16+0	; v1.0
	dc.l	EP_PlayerVersion,1
	dc.l	DTP_PlayerName,PName
	dc.l	DTP_Creator,CName

	dc.l	DTP_InitPlayer,InitPlay		; alloc audio
	dc.l	DTP_EndPlayer,EndPlay		; free audio
	dc.l	DTP_InitSound,ELIM_init		; init custom data
	dc.l	DTP_EndSound,ELIM_end		; clear DMA

	dc.l	DTP_SubSongRange,ELIM_SubSongRange

	dc.l	DTP_Interrupt,ELIM_Play

	dc.l	DTP_Volume,ELIM_Volume
	dc.l	DTP_Balance,ELIM_Volume

	dc.l	EP_Voices,ELIM_SetVoices
	dc.l	EP_StructInit,ELIM_StructInit

	dc.l	EP_Flags,EPB_Voices!EPB_Analyzer!EPB_Volume!EPB_Balance

	dc.l	TAG_DONE


PName	dc.b	"Eliminator Custom v1.0",0
CName	dc.b	"Music by JMP (1988).",$a
	dc.b	"Adapted by Mr.STYCKX (25/05/96)",0

	EVEN


ELIM_StructAnalyzer			; transmis à EaglePlayer pour gérer
	ds.l	UPS_SizeOF		; les analyzers



*-----------------------------------------------------------------------*
;
; Init Player

InitPlay
	move.l	dtg_AudioAlloc(a5),a0		; Function
	jmp	(a0)


*-----------------------------------------------------------------------*
;
; End Player

EndPlay
	move.l	dtg_AudioFree(a5),a0		; Function
	jmp	(a0)


*-----------------------------------------------------------------------*
;
; Init Custom Replay Routine

ELIM_init
	move.w	dtg_SndNum(a5),d0	; sub song nbr (1..5)
	bsr	ELIM_InitSong

	rts


*-----------------------------------------------------------------------*
;
; Clear Audio Reg.

ELIM_end
	move.w	#$f,$dff096
	clr.w	$dff0a8
	clr.w	$dff0b8
	clr.w	$dff0c8
	clr.w	$dff0d8

	rts


*-----------------------------------------------------------------------*
;
; Interrupt routine called every 1/50 s

ELIM_Play
	bsr.s	ELIM_InterVBL
	rts


*-----------------------------------------------------------------------*
;
; Returns min and max sub song

ELIM_SubSongRange
	moveq	#1,d0			; min
	moveq	#5,d1			; max

	rts


*-----------------------------------------------------------------------*
;
; Set Volume

ELIM_Volume
	move.w	dtg_SndLBal(a5),d0	; Vol Left
	mulu	dtg_SndVol(a5),d0	; Vol Max
	lsr.w	#6,d0
	move.w	d0,ELIM_MasterVolA	; final Vol Left
	move.w	d0,ELIM_MasterVolD

	move.w	dtg_SndRBal(a5),d0
	mulu	dtg_SndVol(a5),d0
	lsr.w	#6,d0
	move.w	d0,ELIM_MasterVolB
	move.w	d0,ELIM_MasterVolC

	rts


*-----------------------------------------------------------------------*
;
; Set DMA Voices

ELIM_SetVoices
	move.w	d0,ELIM_DMA_EP	; bit=1 <=> voice is ON

	rts


*-----------------------------------------------------------------------*
;
; Returns address of the UPS structure to EaglePlayer

ELIM_StructInit
	lea	ELIM_StructAnalyzer(pc),a0

	rts



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


	ELSEIF				; TESTVERSION


;-------
; Small code to test the player under a debugger


	moveq	#1,d0
	bsr	ELIM_InitSong

	move.l	$6c.w,Jmp+2
	move.l	#Vbl,$6c.w
	rts


End
	bsr	StopSong
	move.l	Jmp+2(pc),$6c.w
	rts


Vbl
	btst	#5,$dff01f
	beq.s	Jmp

.wa	cmp.b	#70,$dff006
	blt.s	.wa

	move.w	#$f00,$dff180

	movem.l	d0-a6,-(a7)
	bsr	ELIM_InterVBL
	movem.l	(a7)+,d0-a6

	move.w	#$345,$dff180

Jmp	jmp	0.l




ELIM_StructAnalyzer			; transmis à EaglePlayer pour gérer
	ds.l	UPS_SizeOF		; les analyzers


	ENDC



;------------------------------------------------------------------------
; Données pour EaglePlayer / Delitracker

ELIM_DMA_EP	dc.w	%1111		; voix actives depuis EaglePlayer

ELIM_MasterVolA	dc.w	64		; 0 .. 64
ELIM_MasterVolB	dc.w	64
ELIM_MasterVolC	dc.w	64
ELIM_MasterVolD	dc.w	64

ELIM_OldPer1	dc.w	-1
ELIM_OldPer2	dc.w	-1
ELIM_OldPer3	dc.w	-1
ELIM_OldPer4	dc.w	-1


FakeDma		dc.w	0



;-----------------------------------------------------------------------
; Eliminator Musics
; Original music by JMP (located in $6b24) in 1988.
; Relocated on 8/5/96 by Mr.STYCKX
;
; ELIM_InitSong : D0 = 1..5
; ELIM_InterVBL : called every VBL
;



;-----------------------------------------------------------------------
; Init la subsong D0 (1..5)

ELIM_InitSong
	move.w	d0,-(sp)
	bsr	StopSong
	move.w	(sp)+,d0

	subq.w	#1,d0			; de 0 à 4
	lsl.w	#2,d0			; adresse mots longs
	lea	SongsAdr(pc),a0
	move.l	(a0,d0.w),a0
	bra	InitSong
	


;-----------------------------------------------------------------------
; Routine appelée à chaque VBL

ELIM_InterVBL
	movem.l	D0/A0,-(SP)

	lea	ELIM_StructAnalyzer(pc),a0
	move.w	#-1,UPS_Enabled(a0)
	move.w	#UPSB_Adr!UPSB_Len!UPSB_Per!UPSB_Vol!UPSB_DMACon,UPS_Flags(a0)

	move.w	UPS_Voice1Per(a0),ELIM_OldPer1
	move.w	UPS_Voice2Per(a0),ELIM_OldPer2
	move.w	UPS_Voice3Per(a0),ELIM_OldPer3
	move.w	UPS_Voice4Per(a0),ELIM_OldPer4

	clr.w	UPS_Voice1Per(a0)
	clr.w	UPS_Voice2Per(a0)
	clr.w	UPS_Voice3Per(a0)
	clr.w	UPS_Voice4Per(a0)

	bsr	PlaySong

	; La replay d'Eliminator remet la période à chaque VBL,ce qui perturbe
	; les analyzers. On ne transmet donc une période que si elle est
	; différente de la VBL précédente.

	lea	ELIM_StructAnalyzer(pc),a0
	move.w	UPS_Voice1Per(a0),d0
	cmp.w	ELIM_OldPer1(pc),d0	; nouvelle fréquence
	bne.s	.2			; oui
	clr.w	UPS_Voice1Per(a0)	; non, on remet a 0

.2	move.w	UPS_Voice2Per(a0),d0
	cmp.w	ELIM_OldPer2(pc),d0
	bne.s	.3
	clr.w	UPS_Voice2Per(a0)

.3	move.w	UPS_Voice3Per(a0),d0
	cmp.w	ELIM_OldPer3(pc),d0
	bne.s	.4
	clr.w	UPS_Voice3Per(a0)

.4	move.w	UPS_Voice4Per(a0),d0
	cmp.w	ELIM_OldPer4(pc),d0
	bne.s	.0
	clr.w	UPS_Voice4Per(a0)
.0

	clr.w	UPS_Enabled(a0)

	movem.l	(SP)+,D0/A0
	rts



;-----------------------------------------------------------------------

lbC000000				; 6b24
	lea	l8D1C(pc),A6
	lea	l8CCE(pc),A5
	add.w	D0,D0
	add.w	D0,A5
	tst.w	D2
	beq.s	lbC00005A
	cmp.w	$1E(A5),D2
	bcs.s	lbC00005E
	clr.w	$1E(A5)
	move.l	(A6),A4
	mulu	#$10E,D1
	addq.w	#8,D1
	move.b	0(A4,D1.W),D0
	cmp.w	#$64,D3
	bcc.s	lbC000032
	move.b	D3,D0
lbC000032	ext.w	D0
	add.w	D0,D0
	lea	l8D44(pc),A3
	move.w	0(A3,D0.W),$30(A5)
	move.b	1(A4,D1.W),$36(A5)
	move.b	2(A4,D1.W),$3C(A5)
	move.b	3(A4,D1.W),$42(A5)
	addq.w	#4,D1
	move.w	D1,$2A(A5)
lbC00005A	move.w	D2,$1E(A5)
lbC00005E	rts



;----------------------------------------
; Routine VBL principale

PlaySong
lbC000060				; $6b84
	movem.l	D0-D7/A0-A6,-(SP)
	lea	l8D1C(pc),A6
	tst.l	14(A6)
	beq.s	lbC000074
	subq.w	#1,12(A6)
lbC000074
	lea	l8CCE(pc),A5
	moveq	#0,D7
lbC00007C	tst.w	12(A6)
	bne.s	lbC000086
	bsr	lbC0002E8
lbC000086	addq.w	#2,A5
	addq.w	#1,D7
	cmp.w	#3,D7
	bne.s	lbC00007C
	tst.w	12(A6)
	bne.s	lbC00009C
	move.w	4(A6),12(A6)
lbC00009C

	lea	l8CCE(pc),A5
;;	lea	l8D44(pc),A4		; A4 inutilisé
	lea	ELIM_StructAnalyzer(pc),a4

	lea	$DFF0A0,A3
	moveq	#2,D7
	moveq	#0,D6
lbC0000B2	tst.w	$1E(A5)
	beq	lbC000162
	tst.w	$14(A6)
	bne.s	lbC0000CA
	cmp.w	#1,$1E(A5)
	beq	lbC000162
lbC0000CA	tst.w	$16(A6)
	bne.s	lbC0000DA
	cmp.w	#2,$1E(A5)
	bcc	lbC000162
lbC0000DA	move.l	(A6),A0
	add.w	$2A(A5),A0
	cmp.b	#$FF,(A0)
	beq	lbC000162
	move.b	$3C(A5),D1
	cmp.b	$48(A5),D1
	beq.s	lbC000124
	move.b	D1,$48(A5)
	moveq	#8,D0
	lea	l8E04,A1		; sample copro
	tst.b	D1
	beq.s	lbC00010C
	move.w	l1A98C(pc),D0
	move.l	l1A988(pc),A1
lbC00010C
	move.w	#15,-10(A3)		; stoppe les 4 voix
	bsr	WaitDMA
	move.w	D0,4(A3,D6.W)
	move.l	A1,0(A3,D6.W)
	move.w	d0,UPS_Voice1Len(a4)
	move.l	a1,UPS_Voice1Adr(a4)

	move.w	ELIM_DMA_EP(pc),d0
	and.w	#%0111,d0		; la voix D est toujours OFF
	move.w	d0,UPS_DMACon(a4)
	or.w	#$8000,d0
	move.w	d0,-10(A3)

lbC000124	move.b	(A0)+,D0
	and.w	#$3F,D0
	move.w	d0,UPS_Voice1Vol(a4)

	cmp.w	#2,d7
	bne.s	.1
	move.w	ELIM_MasterVolA(pc),d2
	bra.s	.ok
.1	cmp.w	#1,d7
	bne.s	.2
	move.w	ELIM_MasterVolB(pc),d2
	bra.s	.ok
.2	move.w	ELIM_MasterVolC(pc),d2
.ok	mulu	d2,d0
	lsr.w	#6,d0
	move.w	D0,8(A3,D6.W)

	move.b	(A0)+,D0
	sub.b	#$20,D0
	ext.w	D0
	add.w	$30(A5),D0
	tst.b	$3C(A5)
	bne.s	lbC000146
	move.w	D0,6(A3,D6.W)
	move.w	d0,UPS_Voice1Per(a4)
	bra.s	lbC000152

lbC000146	move.b	$36(A5),D1
	ext.w	D1
	add.w	D1,D0
	move.w	D0,6(A3,D6.W)
	move.w	d0,UPS_Voice1Per(a4)
lbC000152	move.b	$3C(A5),D0
	move.b	$42(A5),$3C(A5)
	move.b	D0,$42(A5)
	bra.s	lbC00016C

lbC000162
	clr.w	8(A3,D6.W)
	clr.w	UPS_Voice1Vol(a4)
	clr.w	$1E(A5)
	bra.s	lbC000170

lbC00016C	addq.w	#2,$2A(A5)
lbC000170	add.w	#$10,D6
	addq.w	#2,A5
	lea	UPS_Modulo(a4),a4
	dbra	D7,lbC0000B2
	movem.l	(SP)+,D0-D7/A0-A6
	rts



;----------------------------------------
; Arrete le son et init qq données générales

StopSong
lbC000180				; 6ca4
	lea	l8D1C(pc),A6
	clr.l	14(A6)
	move.w	#1,$14(A6)
	move.w	#1,$16(A6)
	lea	l7C87C(pc),A0
	move.l	A0,(A6)
	move.w	#3,10(A6)
	lea	$DFF0A0,A0
	move.w	#15,-10(A0)
	moveq	#3,D0
lbC0001B2
	move.l	#l8E04,(A0)
	move.w	#8,4(A0)
	move.w	#$309,6(A0)
	clr.w	8(A0)
	lea	$10(A0),A0
	dbra	D0,lbC0001B2
	move.w	#$800F,$DFF096
	rts

lbB0001DA
	dc.b	0
	dc.b	1
	dc.b	2
	dc.b	4
	dc.b	5
	dc.b	6
	dc.b	7
	dc.b	9
	dc.b	10
	dc.b	11
	dc.b	12
	dc.b	0



;----------------------------------------
; Init les données propres à une subsong

InitSong
l6d0a
	cmp.l	#Song1,A0
	bne.s	lbC000202
	move.l	#l9D04,l1A988
	move.w	#$38E,l1A98C
	bra.s	lbC000214

lbC000202
	move.l	#l8E1C,l1A988
	move.w	#$780,l1A98C
lbC000214
	lea	l8D1C(pc),A6
	lea	l8CCE(pc),A5
	clr.l	14(A6)
	clr.w	$1E(A5)
	clr.w	$20(A5)
	clr.w	$22(A5)
	move.l	A0,D0
	beq.s	lbC0002A4
	move.w	(A0),D0
	move.w	D0,6(A6)
	clr.w	D1
	move.b	lbB0001DA(PC,D0.W),D1
	move.w	D1,8(A6)
	cmp.w	#3,10(A6)
	beq.s	lbC00024E
	move.w	D1,D0
lbC00024E	move.w	D0,4(A6)
	move.w	2(A0),$12(A6)
	move.w	4(A0),D0
	move.w	D0,6(A5)
	move.w	D0,12(A5)
	move.w	#1,(A5)
	move.b	#$22,$48(A5)
	move.w	6(A0),D0
	move.w	D0,8(A5)
	move.w	D0,14(A5)
	move.w	#1,2(A5)
	move.b	#$22,$4A(A5)
	move.w	8(A0),D0
	move.w	D0,10(A5)
	move.w	D0,$10(A5)
	move.w	#1,4(A5)
	move.b	#$22,$4C(A5)
	move.w	#1,12(A6)
lbC0002A4	move.l	A0,14(A6)
	rts



;----------------------------------------
; Change de note ?

lbC0002E8	tst.l	14(A6)
	beq	lbC0003B8
	tst.w	12(A5)
	beq	lbC0003B8
	subq.w	#1,(A5)
	bne	lbC0003B8
	move.l	14(A6),A4
	move.w	12(A5),D6
lbC000306	clr.w	D0
	move.b	0(A4,D6.W),D0
	addq.w	#1,D6
	cmp.b	#$FF,D0
	bne.s	lbC000326
	tst.w	$12(A6)
	beq.s	lbC000320
	move.w	6(A5),D6
	bra.s	lbC000306

lbC000320	clr.w	12(A5)
	rts

lbC000326	cmp.w	#$40,D0
	bcc.s	lbC000346
	move.w	D0,D3
	move.w	D7,D0
	move.w	$24(A5),D1
	move.w	#1,D2
	movem.l	D6/D7/A4-A6,-(SP)
	bsr	lbC000000
	movem.l	(SP)+,D6/D7/A4-A6
	bra.s	lbC000306

lbC000346	cmp.w	#$80,D0
	bcs.s	lbC000306
	cmp.w	#$A0,D0
	bcc.s	lbC00035C
	and.w	#$1F,D0
	move.w	D0,$24(A5)
	bra.s	lbC000306

lbC00035C	bne.s	lbC00036A
	subq.w	#1,$18(A5)
	bmi.s	lbC000306
	move.w	$12(A5),D6
	bra.s	lbC000306

lbC00036A	cmp.w	#$B0,D0
	bcc.s	lbC00037E
	and.w	#15,D0
	move.w	D0,$18(A5)
	move.w	D6,$12(A5)
	bra.s	lbC000306

lbC00037E	cmp.w	#$D0,D0
	bcc.s	lbC0003A4
	sub.w	#$B0,D0
	move.w	D0,D1
	move.w	D7,D0
	move.w	#$FFFF,D3
	move.w	#1,D2
	movem.l	D6/D7/A4-A6,-(SP)
	bsr	lbC000000
	movem.l	(SP)+,D6/D7/A4-A6
	bra	lbC000306

lbC0003A4	cmp.w	#$F0,D0
	bcc	lbC000306
	sub.w	#$D0,D0
	addq.w	#1,D0
	move.w	D0,(A5)
	move.w	D6,12(A5)
lbC0003B8	rts



;----------------------------------------
; Attend 3 lignes raster

WaitDMA					; lbC0003BA
	movem.l	D0/A0,-(SP)
	lea	$DFF006,A0
	move.b	(A0),D0
	addq.b	#3,D0
lbC0003C8	cmp.b	(A0),D0
	bne.s	lbC0003C8
	movem.l	(SP)+,D0/A0
	rts



;----------------------------------------
; Données de la replay

l8CCE
	dcb.b	78,0
l8D1C
	dc.l	0		; 0	Fx Adr
	dc.w	0		; 4
	dc.w	0		; 6
	dc.w	0		; 8
	dc.w	0		; 10
	dc.w	0		; 12
	dc.l	0		; 14	Song Adr
	dc.w	0		; $12
	dc.w	0		; $14
	dc.w	0		; $16

	dcb.b	40,0


l8D44				; freq
	dc.w $1C40,$1AC0,$1940,$17D0,$1680,$1530,$1400,$12E0
	dc.w $11D0,$10D0,$0FE0,$0F00,$0E20,$0D60,$0CA0,$0BE8
	dc.w $0B40,$0A98,$0A00,$0970,$08E8,$0868,$07F0,$0780
	dc.w $0710,$06B0,$0650,$05F4,$05A0,$054C,$0500,$04B8
	dc.w $0474,$0434,$03F8,$03C0,$0388,$0358,$0328,$02FA
	dc.w $02D0,$02A6,$0280,$025C,$023A,$021A,$01FC,$01E0
	dc.w $01C4,$01AC,$0194,$017D,$0168,$0153,$0140,$012E
	dc.w $011D,$010D,$00FE,$00F0,$00E2,$00D6,$00CA,$00BE
	dc.w $00B4,$00AA,$00A0,$0097,$008F,$0087,$007F,$007D
	dc.w $00E2,$00D6,$00CA,$00BE,$00B4,$00AA,$00A0,$0097
	dc.w $008F,$0087,$007F,$007D,$00E2,$00D6,$00CA,$00BE
	dc.w $00B4,$00AA,$00A0,$0097,$008F,$0087,$007F,$007D



l1A988
	dc.l	0	; sampleadr
l1A98C
	dc.w	0	; samplelen




l7C87C					; $7c87c, 8640 octets
	incbin	b:Eliminator/Eliminator.fx

l7EA3C					; $7ea3c, 5126 octets
	incbin	b:Eliminator/Eliminator.sng

Song1	=	l7EA3C			; Intro
Song2	=	l7EA3C-$7EA3C+$7F112	; In Game
Song3	=	l7EA3C-$7EA3C+$7F3F4	; Get Ready
Song4	=	l7EA3C-$7EA3C+$7F466	; Game Over
Song5	=	l7EA3C-$7EA3C+$7F4D2	; Stage Completed


SongsAdr
	dc.l	Song1,Song2,Song3,Song4,Song5



;-----------------------------------------------------------------------
; Données en CHIP


	section Samples,data_c


SamplesBuf				; $8e04, 5676 octets
	incbin	b:Eliminator/Eliminator.smp

l8E04	=	SamplesBuf		; emptysample, len=16 oct
l8E1C	=	SamplesBuf+$8e1c-$8e04	; $780*2 = $f00
l9D04	=	SamplesBuf+$9d04-$8e04	; $38e*2 = $71c

;-----------------------------------------------------------------------
; END
	end

