*************************************************
* HammerFist Musics by Wally Beben (1991).	*
* Adapted by Mr.STYCKX / Nicolas Pomarede	*
*						*
* Original replay was in $4f130.		*
*						*
* Ripped : 06/91				*
* Relocated : 11/04/96				*
* EaglePlayer / Delitracker port : 18/04/96	*
*	Volume					*
*	Balance					*
*	SubSong					*
*	EP_Voices				*
*	EP_StructInit (Analyzer)		*	
*************************************************

	opt	o+

	output	ram:CUST.HammerFist


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

	section HammerCode,code


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


	IFEQ	HF_TEST-0			; COMPLETE VERSION


	PLAYERHEADER PlayerTagArray

	dc.b '$VER: HammerFist Musics (1991) custom player V1.0, '
	dc.b 'ripped and adapted by Mr.STYCKX (04/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,HF_init		; init custom data
	dc.l	DTP_EndSound,HF_end		; clear DMA

	dc.l	DTP_SubSongRange,HF_SubSongRange

	dc.l	DTP_Interrupt,HF_Play

	dc.l	DTP_Volume,HF_Volume
	dc.l	DTP_Balance,HF_Volume

	dc.l	EP_Voices,HF_SetVoices
	dc.l	EP_StructInit,HF_StructInit

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

	dc.l	TAG_DONE


PName	dc.b	"HammerFist Custom v1.0",0
CName	dc.b	"Music by Wally Beben (1991).",$a
	dc.b	"Adapted by Mr.STYCKX (18/04/96)",0

	EVEN


HF_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

HF_init
	move.w	dtg_SndNum(a5),d0	; sub song nbr (1..7)
	bsr	HF_InitSong

	rts


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

HF_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

HF_Play
	bsr	HF_InterVBL
	rts


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

HF_SubSongRange
	moveq	#1,d0			; min
	moveq	#7,d1			; max

	rts


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

HF_Volume
	move.w	dtg_SndLBal(a5),d0	; Vol Left
	mulu	dtg_SndVol(a5),d0	; Vol Max
	lsr.w	#6,d0
	move.w	d0,HF_MasterVolA	; final Vol Left
	move.w	d0,HF_MasterVolD

	move.w	dtg_SndRBal(a5),d0
	mulu	dtg_SndVol(a5),d0
	lsr.w	#6,d0
	move.w	d0,HF_MasterVolB
	move.w	d0,HF_MasterVolC

	rts


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

HF_SetVoices
	move.w	d0,HF_DMA_EP	; bit=1 <=> voice is ON

	rts


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

HF_StructInit
	lea	HF_StructAnalyzer(pc),a0

	rts



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


	ELSEIF				; TESTVERSION


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


	bsr	Run
	bra	Stop

Run
	moveq	#1,d0
	bsr	HF_InitSong

	lea	Jmp+2(PC),A0
	move.l	$6C.W,(A0)
	lea	Vbl(PC),A0
	move.l	A0,$6C
	move.w	#$C020,$DFF09A
	rts

Stop
	move.l	Jmp+2(PC),$6C
	moveq	#0,D0
	bsr	HF_InitSong
	rts

Vbl
	btst	#5,$dff01f
	beq.s	Jmp

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

	move.w	#$700,$dff180

	jsr	HF_InterVBL(PC)

	move.w	#$567,$dff180

Jmp	jmp	0.l


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


	ENDC



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

HF_DMA_EP	dc.w	%1111		; voix actives depuis EaglePlayer

HF_MasterVolA	dc.w	64		; 0 .. 64
HF_MasterVolB	dc.w	64
HF_MasterVolC	dc.w	64
HF_MasterVolD	dc.w	64

HF_StructA	dc.l	HF_StructAnalyzer
HF_StructB	dc.l	HF_StructAnalyzer+UPS_Modulo
HF_StructC	dc.l	HF_StructAnalyzer+UPS_Modulo*2
HF_StructD	dc.l	HF_StructAnalyzer+UPS_Modulo*3

HF_OldPer1	dc.w	-1
HF_OldPer2	dc.w	-1
HF_OldPer3	dc.w	-1
HF_OldPer4	dc.w	-1


FakeDma		dc.w	0

HF_VertPos	dc.w	0



;-----------------------------------------------------------------------
; HammerFist Musics
; Original musics by Wally Beben (located in $4f130) in 1991.
; Relocated on 11/4/96 by Mr.STYCKX
;
; HF_InitSong : D0 = 1..7, choose a subsong
; HF_InterVBL : called every VBL
;


OriginalPatternsAdr	=	$50070
OriginalSamplesAdr	=	$50f1a




;-----------------------------------------------------------------------
; Reloge les subsongs et init la subsong D0 (1..7)

HF_InitSong
	bsr.s	HF_RelocAdr

	move.b	d0,HF_SongNbr
	bsr	HF_StopSong
	rts


;-----------------------------------------------------------------------
; Reloge les adresses des patterns et des samples

HF_RelocAdr
	movem.l	d0-d1/a0-a1,-(sp)

	moveq	#19-1,d0		; 19 samples
	lea	SamplesAdr(pc),a0
	move.l	#SamplesBuf,d1
	cmp.l	(a0),d1			; déjà relogé
	beq.s	.done

	sub.l	#OriginalSamplesAdr,d1
.RelSamples
	add.l	d1,(a0)+
	dbf	d0,.RelSamples

	move.w	#131-1,d0		; 131 patterns
	lea	PatternsAdr(pc),a0
	move.l	#PatternsBuf,d1
	sub.l	#OriginalPatternsAdr,d1
.RelPatterns
	add.l	d1,(a0)+
	dbf	d0,.RelPatterns

.done	movem.l	(sp)+,d0-d1/a0-a1
	rts


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

HF_InterVBL
	movem.l	D0-D7/A0-A6,-(SP)

	lea	HF_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	HF_DMA_EP(pc),UPS_DMACon(a0)

	move.w	UPS_Voice1Per(a0),HF_OldPer1
	move.w	UPS_Voice2Per(a0),HF_OldPer2
	move.w	UPS_Voice3Per(a0),HF_OldPer3
	move.w	UPS_Voice4Per(a0),HF_OldPer4

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

	bsr.s	HF_VBL2

	; La replay d'HammerFist 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	HF_StructAnalyzer(pc),a0
	move.w	UPS_Voice1Per(a0),d0
	cmp.w	HF_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	HF_OldPer2(pc),d0
	bne.s	.3
	clr.w	UPS_Voice2Per(a0)

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

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

	clr.w	UPS_Enabled(a0)

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


;-----------------------------------------------------------------------
; Routine VBL principale (teste si changement de subsong)

HF_VBL2
	moveq	#0,D0
	moveq	#0,D1
	moveq	#0,D2
	moveq	#0,D3
	moveq	#0,D4
	moveq	#0,D5
	moveq	#0,D6
	moveq	#0,D7
	move.b	HF_SongNbr(pc),D0
	bne.s	lbC000142
	move.b	D0,MusicActive		; OFF
	bsr	HF_StopVol
	bra	EndVBL


;----------------------------------------
; Teste s'il s'agit d'une autre subsong

lbC000142
	moveq	#8,D1			; max subsong
	cmp.b	D0,D1
	bcs	SameSubSong
NewSubSong
	subq.w	#1,D0
	asl.w	#4,D0			; 4 mots longs par subsong
	lea	SongPatterns(pc),A0
	add.w	D0,A0
	lea	lbL000CD2(pc),A1
	move.l	(A0)+,(A1)+
	move.l	(A0)+,(A1)+
	move.l	(A0)+,(A1)+
	move.l	(A0),(A1)
	moveq	#3,D1
	moveq	#0,D0
.initvoice
	lea	VoicesData(pc),A0
	add.w	D1,A0
	move.b	D0,$14(A0)
	move.b	D0,$18(A0)
	move.b	D0,12(A0)
	bsr.s	lbC0001A2
	dbra	D1,.initvoice
	bsr	HF_StopSong
	move.b	#1,MusicActive		; ON
	move.b	#15,lbB000C86
	bra	EndVBL


;----------------------------------------
; Initialise une voix en A0

lbC0001A2	lea	lbL000CD2(pc),A1
	move.w	D1,D2
	asl.w	#2,D2
	add.w	D2,A1
	move.l	(A1),lbL000CE2
lbC0001B4	lea	lbL000CE2(pc),A1
	move.l	(A1),A1
	moveq	#0,D0
	move.b	12(A0),D0
	addq.b	#1,12(A0)
	add.w	D0,A1
	move.b	(A1),D0
	cmp.b	#$C0,D0
	bls.s	lbC0001F4
	cmp.b	#$FF,D0
	bne.s	lbC0001E2
	clr.b	12(A0)
	bra.s	lbC0001B4

lbC0001E2	add.w	#$20,D0
	move.b	D0,$20(A0)
	bra.s	lbC0001B4

lbC0001F4	asl.w	#2,D0
	lea	lbL000E7A(pc),A1
	add.w	D0,A1
	lea	lbL000CC2(pc),A2
	move.l	(A1),0(A2,D2.W)
	move.l	(A1),lbL000CE6
	moveq	#0,D0
	rts

;----------------------------------------
; Continue à jouer la subsong actuelle déjà initialisée

SameSubSong
	tst.b	MusicActive
	beq	EndVBL
	move.b	#3,ActualVoice
lbC000224	lea	VoicesData(pc),A0
	moveq	#0,d1
	move.b	ActualVoice(pc),D1
	move.w	D1,D2
	asl.b	#2,D2
	move.w	D2,ActualVoicex4	; pour adresser des mots longs
	move.w	D1,D2
	asl.b	#1,D2
	move.w	D2,ActualVoicex2	; pour adresser des mots
	add.w	D1,A0
	move.b	(A0),lbB000C82
	tst.b	lbB000C7D
	bne.s	lbC0002A8
	subq.b	#1,$14(A0)
	tst.b	$70(A0)
	bne.s	lbC00027A
	tst.b	$14(A0)
	beq.s	lbC000270
	bra.s	lbC00027A

lbC000270	bset	D1,lbB000C86
	bra.s	lbC000282

lbC00027A	tst.b	$14(A0)
	bmi.s	lbC0002BE
lbC000282	tst.b	$2C(A0)
	bne.s	lbC000296
	tst.b	$30(A0)
	bne.s	lbC0002A2
	bra.s	lbC0002BA

lbC000296	subq.b	#1,8(A0)
lbC00029A	bsr	lbC000B00
	bra	lbC000776

lbC0002A2	addq.b	#1,8(A0)
	bra.s	lbC00029A

lbC0002A8	tst.b	$34(A0)
	beq.s	lbC0002BA
	clr.b	$34(A0)
	subq.b	#2,8(A0)
	bra.s	lbC00029A

lbC0002BA	bra	lbC0004F6

lbC0002BE	cmp.b	#2,$18(A0)
	beq.s	lbC0002D0
	clr.b	$18(A0)
	clr.b	$1C(A0)
lbC0002D0	clr.b	lbB000C81
	clr.b	$24(A0)
	clr.b	$2C(A0)
	clr.b	$30(A0)
	clr.b	$6C(A0)
	lea	lbL000CC2(pc),A1
	add.w	ActualVoicex4(pc),A1
	move.l	(A1),lbL000CE6
lbC0002F8	moveq	#0,D4
	moveq	#0,D0
	move.b	lbB000C81(pc),D4
	addq.b	#1,lbB000C81
	move.l	lbL000CE6(pc),A3
	move.b	(A3)+,D0
	addq.b	#1,D4
	cmp.b	#$FF,D0
	bne.s	lbC000328
	moveq	#0,D0
lbC00031C	bsr	lbC0001A2
	clr.b	lbB000C81
	bra.s	lbC0002F8

lbC000328	cmp.b	#$FE,D0
	bne.s	lbC00033C
	clr.b	HF_SongNbr
lbC000336	moveq	#0,D0
	bra	HF_VBL2

lbC00033C	cmp.b	#$FC,D0
	bne.s	lbC00034C
	move.b	(A3),HF_SongNbr
	bra.s	lbC000336

lbC00034C	cmp.b	#$EF,D0
	bls.s	lbC000362
	and.b	#15,D0
	move.b	D0,lbB000C7C
	move.b	(A3)+,D0
	addq.b	#1,D4
lbC000362	cmp.b	#$E0,D0
	bne.s	lbC000382
	move.b	(A3)+,D0
	asl.b	#3,D0
	move.b	D0,$4C(A0)
	move.b	(A3)+,D0
	addq.b	#2,D4
	cmp.b	#$FF,D0
	bne.s	lbC000382
	moveq	#0,D0
	bra.s	lbC00031C

lbC000382	cmp.b	#$BF,D0
	bls.s	lbC0003A6
	and.b	#$1F,D0
	asl.b	#3,D0
	move.b	D0,$50(A0)
	move.b	(A3)+,D0
	addq.b	#1,D4
	cmp.b	#$FF,D0
	bne.s	lbC0003A6
	moveq	#0,D0
	bra.s	lbC00031C

lbC0003A6	cmp.b	#$7F,D0
	bls.s	lbC0003BA
	and.b	#$3F,D0
	move.b	D0,$10(A0)
	move.b	(A3)+,D0
	addq.b	#1,D4
lbC0003BA	cmp.b	#$5F,D0
	bls.s	lbC0003DE
	cmp.b	#$7F,D0
	bne.s	lbC0003E2
	move.b	#1,$2C(A0)
	clr.b	$30(A0)
lbC0003D4	move.b	#1,$18(A0)
lbC0003DA	move.b	(A3)+,D0
	addq.b	#1,D4
lbC0003DE	bra.s	lbC00045C

lbC0003E2	cmp.b	#$7E,D0
	bne.s	lbC0003F6
	move.b	#1,$30(A0)
	clr.b	$2C(A0)
	bra.s	lbC0003D4

lbC0003F6	cmp.b	#$7D,D0
	bne.s	lbC00041A
	move.b	#1,D0
lbC000402	move.b	D0,$18(A0)
	move.b	(A3)+,D0
	addq.b	#1,D4
	move.b	D0,$1C(A0)
	move.b	D0,lbB000C80
	bsr	lbC0008E8
	bra.s	lbC0003DA

lbC00041A	cmp.b	#$7C,D0
	bne.s	lbC000428
	moveq	#2,D0
	bra.s	lbC000402

lbC000428	cmp.b	#$7B,D0
	bne.s	lbC00044C
	clr.b	$1C(A0)
	move.b	#1,$18(A0)
	move.b	(A3)+,D0
	add.b	$20(A0),D0
	move.b	D0,$24(A0)
	move.b	(A3)+,$28(A0)
	addq.b	#2,D4
	bra.s	lbC0003DA

lbC00044C	cmp.b	#$7A,D0
	bne.s	lbC00045C
	move.b	(A3)+,$44(A0)
	move.b	(A3),D0
	addq.b	#2,D4
lbC00045C	bclr	D1,lbB000C86
	moveq	#0,d5
	move.b	$64(A0),D5
	move.w	D5,$DFF096		; stoppe la voix audio en cours
	move.b	D4,lbB000C81
	movem.l	D0-D7/A0-A6,-(SP)
	bsr	lbC000A52
	bsr	lbC0009EC
	movem.l	(SP)+,D0-D7/A0-A6
	add.b	$20(A0),D0
	move.b	D0,8(A0)
	beq.s	lbC0004BC
	tst.b	$1C(A0)
	bne.s	lbC0004BC
	moveq	#0,d4
	move.b	$50(A0),D4
	lea	lbL001016(pc),A1
	add.w	D4,A1
	tst.b	$34(A0)
	beq.s	lbC0004BC
	addq.b	#2,8(A0)
lbC0004BC	bsr	lbC000B00
	lea	lbL000CC2(pc),A1
	add.w	ActualVoicex4(pc),A1
	moveq	#0,d0
	move.b	lbB000C81,D0
	add.l	D0,(A1)
	moveq	#0,D0
	move.b	$10(A0),$14(A0)
	move.b	$44(A0),$48(A0)
	move.b	4(A0),$38(A0)
	addq.b	#1,$38(A0)
lbC0004F2	bra	lbC000776

lbC0004F6	tst.b	8(A0)
	beq.s	lbC0004F2
	tst.b	$18(A0)
	bne.s	lbC000512
	tst.b	$68(A0)
	bne.s	lbC00053C
	move.b	$4E(A0),$80(A0)
lbC000512	bra	lbC00065E


lbC00053C	movem.l	D0-D7/A0-A6,-(SP)
	move.b	$68(A0),D0
	move.b	D0,lbB000C7F
	and.b	#15,lbB000C7F
	lsr.b	#4,D0
	move.b	D0,lbB000C7E
	moveq	#0,d0
	move.b	8(A0),D0
	asl.b	#1,D0
	lea	PerTable(pc),A1
	add.l	D0,A1
	move.w	(A1)+,D0
	sub.w	(A1),D0
	move.w	D0,lbW000CEA
lbC000578	subq.b	#1,lbB000C7F
	bmi.s	lbC000598
	lsr.w	lbW000CEA
	or.w	#1,lbW000CEA
	bra.s	lbC000578

lbC000598	tst.b	$3C(A0)
	bpl.s	lbC0005B4
	subq.b	#1,$40(A0)
	tst.b	$40(A0)
	bne.s	lbC0005D0
	addq.b	#1,$3C(A0)
	bpl.s	lbC0005D0
lbC0005B4	addq.b	#1,$40(A0)
	moveq	#0,d0
	move.b	$40(A0),D0
	cmp.b	lbB000C7E(pc),D0
	bls.s	lbC0005D0
	subq.b	#1,$3C(A0)
lbC0005D0	tst.b	$48(A0)
	beq.s	lbC0005E0
	subq.b	#1,$48(A0)
	bra.s	lbC000656

lbC0005E0	lea	lbL000C88(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	(A1),lbW000CEE
	moveq	#0,d0
	move.b	lbB000C7E(pc),D0
	lsr.b	#1,D0
	move.b	D0,D4
lbC000602	subq.b	#1,D4
	bmi.s	lbC00061C
	move.w	lbW000CEE(pc),D0
	add.w	lbW000CEA(pc),D0
	move.w	D0,lbW000CEE
	bra.s	lbC000602

lbC00061C	move.b	$40(A0),D4
lbC000626	subq.b	#1,D4
	bmi.s	lbC000642
	move.w	lbW000CEE(pc),D0
	sub.w	lbW000CEA(pc),D0
	move.w	D0,lbW000CEE
	bra.s	lbC000626

lbC000642	move.w	lbW000CEE(pc),D0
	lea	VoicesPer(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	D0,(A1)
lbC000656	movem.l	(SP)+,D0-D7/A0-A6
	bra	lbC000776

lbC00065E	tst.b	$1C(A0)
	beq.s	lbC0006BE
	movem.l	D0-D7/A0-A6,-(SP)
lbC00066A
	moveq	#0,d4
	move.b	$38(A0),D4
	lea	lbL000CFA(pc),A1
	add.w	D4,A1
	moveq	#0,d0
	move.b	(A1),D0
	cmp.b	#$FF,D0
	bne.s	lbC000694
	move.b	4(A0),$38(A0)
	bra.s	lbC00066A

lbC000694	add.b	8(A0),D0
	lea	PerTable(pc),A1
	asl.b	#1,D0
	add.w	D0,A1
	move.w	(A1),D0
	lea	VoicesPer(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	D0,(A1)
	addq.b	#1,$38(A0)
	movem.l	(SP)+,D0-D7/A0-A6
	bra	lbC000776

lbC0006BE	tst.b	$24(A0)
	beq	lbC000776
	move.b	$24(A0),lbB000949
	move.b	$28(A0),D0
	and.b	#15,D0
	move.b	D0,lbB0006F7
	move.b	D0,lbB0009D3
	move.b	$28(A0),D0
	lsr.b	#4,D0
	add.b	$14(A0),D0
	cmp.b	$10(A0),D0
	bgt.s	lbC00076A
	add.b	lbB0006F7(pc),D0
	cmp.b	$10(A0),D0
	bls.s	lbC000750
	move.b	8(A0),D5
	movem.l	D0-D7/A0-A6,-(SP)
	bsr	lbC000946
	movem.l	(SP)+,D0-D7/A0-A6
	lea	lbL000C88(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	(A1),D0
	lea	lbL000C98(pc),A2
	tst.b	lbB000C84
	beq.s	lbC000736
	sub.w	(A2),D0
	move.w	D0,(A1)
	bra.s	lbC00073A




lbC000736	add.w	(A2),D0
	move.w	D0,(A1)
lbC00073A	lea	VoicesPer(pc),A2
	add.w	ActualVoicex2(pc),A2
	move.w	(A1),(A2)
	bra.s	lbC00076A


lbC000750	lea	lbL000C88(pc),A1
	add.w	ActualVoicex2(pc),A1
	lea	lbL000C90(pc),A6
	add.w	ActualVoicex2(pc),A6
	move.w	(A6),(A1)
lbC00076A	tst.b	$80(A0)
	beq.s	lbC000776
	bra	lbC00053C

lbC000776	moveq	#0,D4
	moveq	#0,D5
	moveq	#0,D6
	tst.b	$14(A0)
	beq.s	lbC000804
	tst.b	$6C(A0)
	bne.s	lbC0007D6
	move.b	$14(A0),D6
	tst.b	$70(A0)
	bne.s	lbC0007A2
	move.b	#1,$6C(A0)
	bra.s	lbC000804

lbC0007A2	move.b	$70(A0),D4
	cmp.b	#$FF,D4
	beq.s	lbC000804
	move.b	$10(A0),D5
	divu	D4,D5
	sub.b	D5,D6
	tst.b	D6
	beq.s	lbC0007D6
	move.b	$60(A0),D0
	move.b	$54(A0),D4
	cmp.b	D0,D4
	beq.s	lbC000804
	add.b	$58(A0),D0
	move.b	D0,$60(A0)
	bra.s	lbC000804

lbC0007D6	move.b	#1,$6C(A0)
	moveq	#0,D0
	move.b	$60(A0),D0
	move.b	$5C(A0),D4
	sub.b	D4,D0
	tst.b	D0
	beq.s	lbC0007FA
	bmi.s	lbC0007FA
	move.b	D0,$60(A0)
	bra.s	lbC000804

lbC0007FA	clr.b	$60(A0)
	bset	D1,lbB000C86
lbC000804	subq.b	#1,ActualVoice
	bmi.s	lbC000812
	bra	lbC000224


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

lbC000812
	bsr	SetDMAPerVol
	moveq	#0,D0
	moveq	#3,D1
	moveq	#12,D2
	moveq	#6,D3
	moveq	#$30,D4
	moveq	#0,D5
	moveq	#0,D7

	move.b	HF_VertPos(pc),d0
.wa	cmp.b	$dff006,d0		; on doit attendre un nombre de lignes
	bgt.s	.wa			; minimal avant d'installer le Repeat

	lea	HF_StructAnalyzer+UPS_Modulo*3(pc),a3

.dovoice
	moveq	#0,D6
	lea	RepeatLens(pc),A6
	move.w	0(A6,D3.W),D0
	lsr.w	#1,D0
	lea	$DFF0A4,A5
	move.w	D0,0(A5,D4.W)
	moveq	#0,D0
	lea	VoicesRepeat(pc),A6
	move.b	0(A6,D1.W),D0
	bne.s	.repeat_on

;;	lea	RepeatStarts(pc),A6
;;	move.w	0(A6,D3.W),D6
;;	lea	lbL000D6E(pc),A6			; ***
;;	add.l	0(A6,D2.W),D6

	move.l	#EmptySample,d6
	move.w	#1,UPS_Voice1Repeat(a3)	; repeat OFF

	bra.s	.lbC000882

.repeat_on
	lea	RepeatStarts(pc),A6
	move.w	0(A6,D3.W),D6
	lea	CurrentSamples(pc),A6
	add.l	0(A6,D2.W),D6
	clr.w	UPS_Voice1Repeat(a3)	; repeat ON
.lbC000882
	lea	$DFF0A0,A5
	move.l	D6,0(A5,D4.W)
	subq.w	#4,D2
	subq.w	#2,D3
	sub.w	#$10,D4
	lea	-UPS_Modulo(a3),a3
	dbra	D1,.dovoice

	subq.b	#1,lbB000C7D
	bpl.s	EndVBL
	move.b	lbB000C7C(pc),lbB000C7D

EndVBL	move.b	#$FF,HF_SongNbr		; subsong traitée
	rts


;----------------------------------------
; Met le volume à 0

HF_StopVol
	moveq	#0,D0
	move.l	#$DFF0A8,A5
	move.w	D0,(A5)
	move.w	D0,$10(A5)
	move.w	D0,$20(A5)
	move.w	D0,$30(A5)
	clr.w	HF_StructAnalyzer+UPS_Voice1Vol
	clr.w	HF_StructAnalyzer+UPS_Voice2Vol
	clr.w	HF_StructAnalyzer+UPS_Voice3Vol
	clr.w	HF_StructAnalyzer+UPS_Voice4Vol
	lea	VoicesVol(pc),A5
	move.l	D0,(A5)
	rts


;----------------------------------------
; Coupe le volume et stoppe la replay

HF_StopSong
	bsr.s	HF_StopVol
	move.b	D0,lbB000C7D
	move.b	D0,MusicActive		; replay OFF
	rts


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

lbC0008E8	movem.l	D0-D7/A0-A6,-(SP)
	moveq	#0,D4
	move.b	4(A0),D4
	addq.b	#1,D4
	moveq	#0,D5
lbC0008F6	moveq	#0,D0
	move.b	lbB000C80(pc),D0
	btst	#0,D0
	beq.s	lbC000920
	lea	lbL000E02(pc),A1
	add.w	D5,A1
	move.b	(A1),D0
	lea	lbL000CFA(pc),A1
	add.w	D4,A1
	move.b	D0,(A1)
	addq.w	#1,D4
	move.b	lbB000C80(pc),D0
lbC000920	lsr.b	#1,D0
	move.b	D0,lbB000C80
	addq.w	#1,D5
	cmp.b	#8,D5
	bne.s	lbC0008F6

	lea	lbL000CFA(pc),A1
	add.w	D4,A1
	move.b	#$FF,(A1)
	clr.b	$24(A0)
	movem.l	(SP)+,D0-D7/A0-A6
	rts



lbC000946
	move.b	lbB000949(pc),D4
	cmp.b	D4,D5
	bcc.s	lbC00098E
	move.b	#1,lbB000C84
	lea	PerTable(pc),A1
	asl.b	#1,D4
	add.w	D4,A1
	move.w	(A1),D4
	move.l	A6,-(SP)
	lea	lbL000C90(pc),A6
	add.w	ActualVoicex2(pc),A6
	move.w	D4,(A6)
	move.l	(SP)+,A6
	asl.b	#1,D5
	lea	PerTable(pc),A1
	add.w	D5,A1
	move.w	(A1),D5
	sub.w	D4,D5
	move.w	D5,lbL000C98
	bra.s	lbC0009C6

lbC00098E	clr.b	lbB000C84
	lea	PerTable(pc),A1
	asl.b	#1,D4
	add.w	D4,A1
	move.w	(A1),D4
	move.l	A6,-(SP)
	lea	lbL000C90(pc),A6
	add.w	ActualVoicex2(pc),A6
	move.w	D4,(A6)
	move.l	(SP)+,A6
	asl.b	#1,D5
	lea	PerTable(pc),A1
	add.w	D5,A1
	move.w	(A1),D5
	sub.w	D5,D4
	move.w	D4,lbL000C98
lbC0009C6	moveq	#0,D4
	move.b	lbB000C7C(pc),D4
	moveq	#0,D0
lbC0009D0
	add.b	lbB0009D3(pc),D0
	dbra	D4,lbC0009D0
	moveq	#0,D4
	moveq	#0,D5
	move.w	lbL000C98(pc),D5
	divu	D0,D5
	move.w	D5,lbL000C98
	rts


lbC0009EC	moveq	#0,D0
	move.b	$50(A0),D0
	lea	lbL001016(pc),A2
	add.w	D0,A2
	move.b	(A2),$60(A0)
	move.b	1(A2),$54(A0)
	move.b	2(A2),$58(A0)
	move.b	3(A2),$5C(A0)
	move.b	4(A2),$70(A0)
	move.b	5(A2),$68(A0)
	tst.b	6(A2)
	beq.s	lbC000A3A
	move.b	6(A2),$1C(A0)
	move.b	#$7C,$18(A0)
	move.b	6(A2),lbB000C80
	bsr	lbC0008E8
lbC000A3A	tst.b	7(A2)
	beq.s	lbC000A50
	move.b	7(A2),D0
	btst	#3,D0
	beq.s	lbC000A50
	move.b	#1,$27(A0)
lbC000A50	rts


;----------------------------------------
; Initialise AudioStart et AudioLen

lbC000A52	moveq	#0,D0
	move.b	$4C(A0),D0
	lea	SamplesInfos(pc),A1
	add.w	D0,A1
	move.b	(A1),D4
	move.b	1(A1),$78(A0)		; repeat ON/OFF
	bne.s	lbC000A76
	move.w	2(A1),D0
	bra.s	lbC000A7E

lbC000A76	move.w	4(A1),D0
	add.w	6(A1),D0
lbC000A7E	lea	RepeatLens(pc),A6
	add.w	ActualVoicex2(pc),A6
	move.w	6(A1),(A6)
	lea	RepeatStarts(pc),A6
	add.w	ActualVoicex2(pc),A6
	move.w	4(A1),(A6)
	lea	$DFF0A4,A5
	moveq	#0,d6
	move.b	lbB000C82(pc),D6
	lsr.w	#1,D0
	move.w	D0,0(A5,D6.W)
	lea	HF_StructA(pc),a5
	add.w	ActualVoicex4(pc),A5
	move.l	(a5),a5
	move.w	d0,UPS_Voice1Len(a5)

	btst	#1,$78(A0)		; toujours à 0
	beq.s	lbC000ADA

	;; jamais pris
	moveq	#0,D0
	move.w	4(A1),D0
	lea	SamplesAdr(pc),A1
	asl.l	#2,D4
	add.l	D4,(A1)
	add.l	D0,(A1)
	move.l	(A1),(A5,D6.W)
	bra.s	lbC000AEE

lbC000ADA
	lea	SamplesAdr(pc),A1
	asl.l	#2,D4
	lea	$DFF0A0,A5
	move.l	0(A1,D4.W),0(A5,D6.W)
	lea	HF_StructA(pc),a5
	add.w	ActualVoicex4(pc),A5
	move.l	(a5),a5
	move.l	(a1,d4.w),UPS_Voice1Adr(a5)

lbC000AEE	lea	CurrentSamples(pc),A5
	add.w	ActualVoicex4(pc),A5
	move.l	0(A1,D4.W),(A5)

	move.b	$dff006,d0
	addq.b	#8,d0			; attend un min de 8 lignes rasters
	move.b	d0,HF_VertPos

	rts


lbC000B00	move.b	8(A0),D0
	add.b	D0,D0
	lea	PerTable(pc),A1
	move.w	0(A1,D0.W),D0
	lea	lbL000C88(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	D0,(A1)
	lea	VoicesPer(pc),A1
	add.w	ActualVoicex2(pc),A1
	move.w	D0,(A1)
	rts


;----------------------------------------
; Met à jour DMA, Per et Vol

SetDMAPerVol
	movem.l	d0-d1/a0-a3,-(sp)

	lea	HF_StructAnalyzer(pc),a3
	lea	VoicesPer(pc),A0
	lea	$DFF0A6,A2
	move.w	(A0),(A2)
	move.w	(a0)+,UPS_Voice1Per(a3)
	move.w	(A0),$10(A2)
	move.w	(a0)+,UPS_Voice2Per(a3)
	move.w	(A0),$20(A2)
	move.w	(a0)+,UPS_Voice3Per(a3)
	move.w	(A0),$30(A2)
	move.w	(a0),UPS_Voice4Per(a3)

	move.b	lbB000C86(pc),D1
	not.b	D1
	and.w	#15,D1
	and.w	HF_DMA_EP(pc),d1	; garde les voix ON depuis EP
 	move.w	d1,UPS_DMACon(a3)
	or.w	#$8200,D1
	move.w	D1,$DFF096		; voix ON
	eor.w	#$820F,D1
	move.w	D1,$DFF096		; voix OFF

	lea	VoicesVol(pc),A1
	moveq	#0,D0
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice1Vol(A3)
	mulu	HF_MasterVolA(pc),d0
	lsr.w	#6,d0
	move.w	D0,2(A2)
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice2Vol(A3)
	mulu	HF_MasterVolB(pc),d0
	lsr.w	#6,d0
	move.w	D0,$12(A2)
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice3Vol(A3)
	mulu	HF_MasterVolC(pc),d0
	lsr.w	#6,d0
	move.w	D0,$22(A2)
	move.b	(A1),D0
	move.w	d0,UPS_Voice4Vol(A3)
	mulu	HF_MasterVolD(pc),d0
	lsr.w	#6,d0
	move.w	D0,$32(A2)

	movem.l	(sp)+,d0-d1/a0-a3
	rts



;-----------------------------------------------------------------------
; Données


HF_SongNbr
	dc.b	0			; subsong choisie


lbB0006F7	dc.b	0		; remplace du code auto-modifié
lbB000949	dc.b	0
lbB0009D3	dc.b	0

	EVEN


PerTable
	dc.w	$0000,$0650
	dc.w	$05F4,$05A0
	dc.w	$054C,$0500
	dc.w	$04B8,$0474
	dc.w	$0434,$03F8
	dc.w	$03C0,$0388
	dc.w	$0358,$0328
	dc.w	$02FA,$02D0
	dc.w	$02A6,$0280
	dc.w	$025C,$023A
	dc.w	$021A,$01FC
	dc.w	$01E0,$01C5
	dc.w	$01AC,$0194
	dc.w	$017D,$0168
	dc.w	$0153,$0140
	dc.w	$012E,$011D
	dc.w	$010D,$00FE
	dc.w	$00F0,$00E2
	dc.w	$00D6,$00CA
	dc.w	$00BE,$00B4
	dc.w	$00A9,$00A0
	dc.w	$0097,$008E
	dc.w	$0087,$007F
	dc.w	$0078,$0071

VoicesPer
	dc.w	$02A6,$00FE,$00FE,$00FE

VoicesData
	dc.l	$102030
	dc.l	$A141E
	dc.l	$10212121
	dc.l	$3030303
	dc.l	$13001F03
	dc.l	$13001303
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	$10B151F
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	$50204018
	dc.l	$8080808
	dc.l	$40404040
	dc.l	0
	dc.l	0
VoicesVol	dc.b	0,0,0,0		; lbL000C56
	dc.b	1,2,4,8			; $64(a0) : pour stopper une voix audio
	dc.l	0
	dc.l	0
	dc.l	$4040404
	dc.l	0
VoicesRepeat	dc.b	0,0,1,0
	dc.l	0
	dc.l	$40180808

ActualVoice
	dc.b	0			; 0..3, voix en cours de traitement

MusicActive
	dc.b	0			; 0=OFF, 1=ON

lbB000C7C	dc.b	5
lbB000C7D	dc.b	0
lbB000C7E	dc.b	0
lbB000C7F	dc.b	0
lbB000C80	dc.b	0
lbB000C81	dc.b	2
lbB000C82	dc.b	0
	dc.b	0
lbB000C84	dc.b	0
	dc.b	0
lbB000C86	dc.b	0		; DMA OFF
	dc.b	0
lbL000C88
	dc.w	$02A6,$00FE,$00FE,$00FE
lbL000C90	dc.l	0
	dc.l	0
lbL000C98	dc.l	0
	dc.l	0
	dc.w	0


CurrentSamples				; $4fccc
	dc.l	0,0,0,0

RepeatLens				; $4fcdc
	dc.w	$0002,$0002
	dc.w	$0A62,$0002
RepeatStarts
	dc.w	$0000,$0000
	dc.w	$05BA,$0000

lbL000CC2				; $4fcec
	dc.l	0,0,0,0
lbL000CD2				; $4fcfc
	dc.l	0,0,0,0
lbL000CE2				; $4fd0c
	dc.l	0
lbL000CE6				; $4fd10
	dc.l	0


lbW000CEA	dc.w	0
	dc.w	0
lbW000CEE	dc.w	0
	dc.w	0

ActualVoicex4				; valeur de ActualVoice * 4
	dc.w	0			; 0,4,8,12
ActualVoicex2				; valeur de ActualVoice * 2
	dc.w	0			; 0,2,4,6

lbL000CFA	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0
	dc.l	0


SamplesAdr				; 19 adresses
	dc.l	$50f1a
	dc.l	$50f1c
	dc.l	$522b1
	dc.l	$52a1e
	dc.l	$543fe
	dc.l	$55025
	dc.l	$566a3
	dc.l	$57e75
	dc.l	$597c5
	dc.l	$5b113
	dc.l	$5d6f7
	dc.l	$5e59e
	dc.l	$5fb02
	dc.l	$60728
	dc.l	$613aa
	dc.l	$61b7a
	dc.l	$6273c
	dc.l	$6273c
	dc.l	$6273c


lbL000D6E				; $4fd98
	dc.l	EmptySample
	dc.l	0,0			; $4fd9c


SamplesInfos
	; .B SmplNbr (dans SamplesAdr)
	; .B Repeat ON/OFF (0=OFF)
	; .W Len
	; .W .W RepStart RepLen
	dc.w	$000,$0002,$0000,$0002
	dc.w	$101,$1394,$08EC,$0AA8
	dc.w	$200,$076C,$0000,$0002
	dc.w	$300,$19E0,$0000,$0002
	dc.w	$400,$0C26,$0000,$0002
	dc.w	$501,$167E,$08CC,$072E
	dc.w	$601,$17D2,$06F2,$091E
	dc.w	$701,$1950,$03CC,$0CD0
	dc.w	$801,$194E,$05BA,$0A62
	dc.w	$901,$25E4,$116E,$103C
	dc.w	$A00,$0EA6,$0000,$0002
	dc.w	$B01,$1564,$1446,$011E
	dc.w	$C00,$0C26,$0000,$0002
	dc.w	$D00,$0C82,$0000,$0002
	dc.w	$E00,$07D0,$0000,$0002
	dc.w	$F00,$0BC2,$0000,$0002
	dc.w	$C01,$0C26,$00C8,$0B54


lbL000E02
	dc.b	3,4,5,7,8,9,$A,$C



PatternsAdr				; 131 adresses
SongPatterns				; $4fe34, 7 subsongs
	dc.l	$500B5,$50087,$5009E,$50070
	dc.l	$500CC,$500D6,$500D9,$500E0
	dc.l	$500EE,$500E6,$500E9,$500E3
	dc.l	$5012B,$5012E,$50131,$50134
	dc.l	$5011F,$50107,$50113,$50104
	dc.l	$500F5,$500F8,$500FB,$500FE
	dc.l	$50152,$5013E,$50148,$5013B


lbL000E7A				; $4fea4
	dc.l	$5015C,$501BD,$50202,$5020B,$50219,$50222,$50267,$50276
	dc.l	$50287,$502CC,$502D5,$502F6,$50306,$5031F,$50364,$5036D
	dc.l	$50384,$503C9,$503D0,$503E4,$50429,$50432,$50441,$50486
	dc.l	$5048F,$504B9,$504D6,$504F7,$50504,$50549,$5055C,$50586
	dc.l	$5059B,$505E0,$5061E,$50659,$506A1,$506E6,$506EF,$50710
	dc.l	$50755,$50764,$50786,$507E6,$507ED,$50812,$5081F,$5082E
	dc.l	$50853,$50859,$50865,$5088A,$508A4,$508C7,$508E7,$5090D
	dc.l	$5092C,$50933,$50952,$50961,$50986,$509B3,$509C1,$509E6
	dc.l	$50A13,$50A1B,$50A1F,$50A4F,$50A94,$50AD7,$50ADB,$50AF3
	dc.l	$50B34,$50B38,$50B3C,$50B71,$50B7C,$50B91,$50BD1,$50BF5
	dc.l	$50C0E,$50C1F,$50C4B,$50C77,$50CE1,$50D06,$50D16,$50D3B
	dc.l	$50DA5,$50DB3,$50DD2,$50DE0,$50DFB,$50E04,$50E28,$50E4D
	dc.l	$50E59,$50E7E,$50E8F,$50EB4,$50EC2,$50EE7,$50EF5



lbL001016				; $50040
	dc.l	0
	dc.l	0
	dc.l	$40400000
	dc.l	$4000000
	dc.l	$34340001
	dc.l	$2320000
	dc.l	$36360001
	dc.l	$2320000
	dc.l	$3E3E0001
	dc.l	$2000000
	dc.l	$38380000
	dc.l	$4000000


PatternsBuf				; $50070, 3754 octets
	incbin	b:HammerFist/HammerFist.pat



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


	section Samples,data_c


EmptySample				; $4fd9c
	dc.l	0,0

SamplesBuf				; $50f1a, 71714 octets
	incbin	b:HammerFist/HammerFist.smp

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

