*************************************************
* Super Hang On Main by The Source (1988).	*
* Adapted by Mr.STYCKX / Nicolas Pomarède	*
*						*
* Original replay was in $1b1c.			*
* Replay Speed : 200 Hz ( Timer=$dfc )		*
*						*
* EaglePlayer / Delitracker port : 29/03/97	*
*	Volume					*
*	Balance					*
*	SubSong					*
*	SongEnd					*
*	EP_Voices				*
*	EP_StructInit (Analyzer)		*
* Songs:	1	Menu			*
*		2	Game Over		*
*		3	Finish			*
*		4	Outride A Crisis	*
*		5	Sprinter		*
*		6	Winning Run		*
*		7	Hard Road		*
* Uses Voices A, B, C				*
*						*	
*************************************************

	opt	o+

	output	ram:CUST.SuperHangOn_Main


SHO_CIA		=	$dfc		; 200 Hz

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

	section	SHO,code



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


	IFEQ	SHO_TEST-0			; COMPLETE VERSION


	PLAYERHEADER PlayerTagArray

	dc.b '$VER: Super Hang On Main Musics (1988) custom player V1.0, '
	dc.b 'ripped and adapted by Mr.STYCKX (03/97)',0

	EVEN

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

	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,SHO_init		; init custom data
	dc.l	DTP_EndSound,SHO_end		; clear DMA

	dc.l	DTP_SubSongRange,SHO_SubSongRange

	dc.l	DTP_Interrupt,SHO_Play

	dc.l	DTP_Volume,SHO_Volume
	dc.l	DTP_Balance,SHO_Volume

	dc.l	EP_Voices,SHO_SetVoices
	dc.l	EP_StructInit,SHO_StructInit

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

	dc.l	TAG_DONE


PName	dc.b	"Super Hang On Main Custom v1.0",0
CName	dc.b	"Music by The Source (1988).",$a
	dc.b	"Adapted by Mr.STYCKX (30/03/97)",0

	EVEN


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



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

InitPlay
	move.l	dtg_SongEnd(a5),SHO_SongEnd

	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

SHO_init
	move.w	#SHO_CIA,dtg_Timer(a5)
	move.l	dtg_SetTimer(a5),a0
	jsr	(a0)
	move.w	dtg_SndNum(a5),d0	; sub song nbr (1..7)
	bra	SHO_InitSong

	move.w	#SHO_CIA,dtg_Timer(a5)
	move.l	dtg_SetTimer(a5),a0
	jmp	(a0)



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

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



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

SHO_Play
	bra.s	SHO_InterVBL



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

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

	rts


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

SHO_Volume
	move.w	dtg_SndLBal(a5),d0	; Vol Left
	mulu	dtg_SndVol(a5),d0	; Vol Max
	lsr.w	#6,d0
	move.w	d0,SHO_MasterVolA	; final Vol Left
	move.w	d0,SHO_MasterVolD

	move.w	dtg_SndRBal(a5),d0
	mulu	dtg_SndVol(a5),d0
	lsr.w	#6,d0
	move.w	d0,SHO_MasterVolB
	move.w	d0,SHO_MasterVolC

	rts


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

SHO_SetVoices
	or.w	#$8000,d0
	move.w	d0,SHO_DMA_EP	; bit=1 <=> voice is ON

	rts


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

SHO_StructInit
	lea	SHO_StructAnalyzer(pc),a0

	rts



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


	ELSEIF				; TESTVERSION


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


	moveq	#1,d0
	bsr	SHO_InitSong

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


End
;;	bsr	StopSong
	move.l	Jmp+2(pc),$6c.w
	move.w	#$f,$dff096
	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	SHO_InterVBL
	movem.l	(a7)+,d0-a6

	move.w	#$345,$dff180

Jmp	jmp	0.l




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


	ENDC



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

SHO_DMA_EP	dc.w	%1111+$8000	; voix actives depuis EaglePlayer

SHO_MasterVolA	dc.w	64		; 0 .. 64
SHO_MasterVolB	dc.w	64
SHO_MasterVolC	dc.w	64
SHO_MasterVolD	dc.w	64

SHO_StructA	dc.l	SHO_StructAnalyzer
SHO_StructB	dc.l	SHO_StructAnalyzer+UPS_Modulo
SHO_StructC	dc.l	SHO_StructAnalyzer+UPS_Modulo*2
SHO_StructD	dc.l	SHO_StructAnalyzer+UPS_Modulo*3

SHO_OldPer1	dc.w	-1
SHO_OldPer2	dc.w	-1
SHO_OldPer3	dc.w	-1
SHO_OldPer4	dc.w	-1



;-----------------------------------------------------------------------
; Super Hang On Loader Music
; Original music by The Source (located in $6000) in 1988.
; Relocated on 29/03/97 by Mr.STYCKX
;
; SHO_InitSong : D0 = 1..7
; SHO_InterVBL : called every VBL
;



;-----------------------------------------------------------------------
; Init la subsong D0

SHO_InitSong
	subq.w	#1,d0			; de 0 à 7
	lsl.w	#3,d0			; adresse 2 mots longs
	lea	SongsAdr(pc),a0
	move.l	4(a0,d0.w),D1		; music speed
	move.l	(a0,d0.w),D0		; music data
	bra	InitSong
	


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

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

	lea	SHO_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),SHO_OldPer1
	move.w	UPS_Voice2Per(a0),SHO_OldPer2
	move.w	UPS_Voice3Per(a0),SHO_OldPer3
	move.w	UPS_Voice4Per(a0),SHO_OldPer4

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

	move.w	SHO_DMA_EP(pc),d0
	move.w	d0,UPS_DMACon(a0)
	not.w	d0
	and.w	#$f,d0
	move.w	d0,$dff096		; stop voices from EP

	bsr	PlaySong

	; La replay de Nebulus 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	SHO_StructAnalyzer(pc),a0
	move.w	UPS_Voice1Per(a0),d0
	cmp.w	SHO_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	SHO_OldPer2(pc),d0
	bne.s	.3
	clr.w	UPS_Voice2Per(a0)

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

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

	clr.w	UPS_Enabled(a0)

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



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


;-----------------------------------------------
;
InitSong

lbC000000	bsr	lbC000152
	move.l	D0,lA118
	move.l	D1,lA11C
	tst.l	D0
	beq.s	lbC00005E
	movem.l	D0/D1/A0,-(SP)
	move.l	D1,lA104
	move.l	D0,D1
	move.l	D0,A0
	add.l	#12,D1
	move.l	D1,lA108
	move.l	D0,D1
	add.l	(A0),D1
	move.l	D1,lA10C
	move.l	D0,D1
	add.l	4(A0),D1
	move.l	D1,lA110
	add.l	8(A0),D0
	move.l	D0,lA114
	clr.l	lA100
	st	lA120
	movem.l	(SP)+,D0/D1/A0
lbC00005E	rts


lbC00008A
	clr.w	lA120
	move.w	#15,$DFF096
;;	move.w	#$780,$DFF09A
	rts


;-----------------------------------------------
;
PlaySong

	tst.w	lA120
	beq.s	lbC0000C2
	movem.l	D0-D7/A0-A6,-(SP)
	bsr	lbC00017A
	bsr.s	lbC00010C
	bsr.s	lbC0000C4
	move.l	lA104,D0
	add.l	D0,lA100

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

;-------

lbC0000C4
	move.l	SHO_StructC(pc),a5
	move.w	SHO_MasterVolC(pc),d7

	move.l	lA110,A0
	move.w	lA100,D0
	cmp.w	(A0),D0
	bcs.s	lbC0000C2
	addq.w	#2,A0
	move.w	(A0)+,D0
	move.l	A0,lA110
	tst.w	D0
	bmi	lbC00016A
	bne.s	lbC0000EC
	moveq	#2,D0
	bra	lbC0001C8

lbC0000EC	lea	lA062(pc),A1
	and.w	#$7F,D0
	sub.w	#$5A,D0
	add.w	D0,D0
	move.w	0(A1,D0.W),D3
	moveq	#2,D0
	moveq	#4,D1
	moveq	#-1,D2
	moveq	#$40,D4
	bra	lbC0001F6

;-------

lbC00010C
	move.l	SHO_StructB(pc),a5
	move.w	SHO_MasterVolB(pc),d7

	move.l	lA10C,A0
	move.w	lA100,D0
	cmp.w	(A0),D0
	bcs	lbC00019A
	addq.w	#2,A0
	move.w	(A0)+,D0
	move.l	A0,lA10C
	tst.w	D0
	bmi.s	lbC00016A
	bne.s	lbC000132
	moveq	#1,D0
	bra	lbC0001C8

lbC000132	lea	lA04A(pc),A1
	and.w	#$7F,D0
	sub.w	#$32,D0
	add.w	D0,D0
	move.w	0(A1,D0.W),D3
	moveq	#1,D0
	moveq	#3,D1
	moveq	#2,D2
	moveq	#$40,D4
	bra	lbC0001F6

lbC000152
	clr.w	lA120
;;	move.w	#$380,$DFF09A
	move.w	#7+8,$DFF096
	rts

lbC00016A
	IFEQ	SHO_TEST-0
	move.l	SHO_SongEnd(pc),a0
	jsr	(a0)
	ENDC
	move.l	lA118,D0
	move.l	lA11C,D1
	bra	lbC000000

;-------

lbC00017A
	move.l	SHO_StructA(pc),a5
	move.w	SHO_MasterVolA(pc),d7

	move.l	lA108,A0
	move.w	lA100,D0
	cmp.w	(A0),D0
	bcs.s	lbC00019A
	addq.w	#2,A0
	move.w	(A0)+,D0
	move.l	A0,lA108
	tst.w	D0
	bmi.s	lbC00016A
	bne.s	lbC00019C
lbC00019A	rts

lbC00019C	cmp.b	#$24,D0
	bne.s	lbC0001B2
	moveq	#0,D0
	moveq	#1,D1
	moveq	#2,D2
	move.w	#$1BF,D3
	moveq	#$40,D4
	bra.s	lbC0001F6

lbC0001B2	cmp.b	#$28,D0
	bne.s	lbC00019A
	moveq	#0,D0
	moveq	#2,D1
	moveq	#2,D2
	move.w	#$1BF,D3
	moveq	#$40,D4
	bra.s	lbC0001F6

lbC0001C8	movem.l	D0/A0/A1,-(SP)
	bsr.s	lbC0001D4
	movem.l	(SP)+,D0/A0/A1
	rts

lbC0001D4	and.w	#3,D0
	lea	lA088,A0
	lsl.w	#2,D0
	lea	0(A0,D0.W),A0
	move.w	$12(A0),$DFF096		; DMA OFF
;;	move.w	$10(A0),$DFF09A		; INTENA OFF
	rts

lbC0001F6	cmp.b	#0,D0
	bne.s	lbC00020E
	tst.b	l6D68
	beq.s	lbC00020E
	tst.b	l6D40
	beq.s	lbC00020E
	rts

lbC00020E	tst.w	D1
	beq.s	lbC0001C8
	cmp.w	#9,D1
	bhi.s	lbC0001C8
	movem.l	D0-D7/A0-A2,-(SP)
	cmp.w	#$7C,D3
	bcc.s	lbC000228
	move.w	#$7C,D3
lbC000228	cmp.w	#$41,D4
	bcs.s	lbC000232
	move.w	#$40,D4
lbC000232	lea	lA0B0,A2
	lsl.w	#3,D1
	lea	0(A2,D1.W),A2
	bsr.s	lbC0001D4
	move.l	(A0),A1
	move.l	(a2),UPS_Voice1Adr(a5)
	move.l	(A2)+,(A1)
	move.w	(a2),UPS_Voice1Len(a5)
	move.w	(A2)+,4(A1)
	move.w	D3,6(A1)
	move.w	d3,UPS_Voice1Per(a5)
	move.w	d4,UPS_Voice1Vol(a5)
	mulu	d7,d4			; mastervol
	lsr.w	#6,d4
	move.w	D4,8(A1)
	clr.w	UPS_Voice1Repeat(a5)	; repeat ON

;	move.w	#$C8,D0
;lbC000254	dbra	D0,lbC000254
	moveq	#5-1,d0
wa1	move.b	$dff006,d1
wa12	cmp.b	$dff006,d1
	beq.s	wa12
	dbf	d0,wa1

	move.w	$22(A0),d0		; DMA ON
	and.w	SHO_DMA_EP(pc),d0
	move.w	d0,$DFF096
	tst.w	D2
	bmi.s	lbC000278

;	move.w	#$C8,D0
;lbC000268	dbra	D0,lbC000268
	moveq	#5-1,d0
wa2	move.b	$dff006,d1
wa22	cmp.b	$dff006,d1
	beq.s	wa22
	dbf	d0,wa2

	move.l	#lA078,(A1)		; empty sample
	move.w	#8,4(A1)
;;	st	UPS_Voice1Repeat(a5)	; repeat OFF

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


;-------


	dc.w	$1BF8,$1A65,$18EA,$1784,$1632,$14F3,$13C6,$12AA
	dc.w	$119E,$10A1,$FB2,$ED0,$DFC,$D33,$C75,$BC2,$B19
	dc.w	$A7A,$9E3,$955,$8CF,$850,$7D9,$768,$6FE,$699,$63B
	dc.w	$5E1,$58D,$53D,$4F2,$4AB,$467,$428,$3EC,$3B4,$37F
	dc.w	$34D,$31D,$2F1,$2C6,$29E,$279,$255,$234,$214,$1F6
	dc.w	$1DA
lA04A	dc.w	$1BF,$1A6,$18F,$178,$163,$14F,$13C,$12B,$11A
	dc.w	$10A,$FB,$ED
lA062	dc.w	$E0,$D3,$C7,$BC,$B2,$A8,$9E,$95,$8D,$85,$7E


lA088	dc.l	$DFF0A0,$DFF0B0,$DFF0C0,$DFF0D0
	dc.l	$800001,$1000002,$2000004,$4000008
	dc.l	$80808001,$81008002,$82008004,$84008008


SAMPLE_START	=	$A122

SampleAdr
	dc.l	$A122-SAMPLE_START+SampleData,$EB0000
	dc.l	$A2F8-SAMPLE_START+SampleData,$3830000
	dc.l	$A9FE-SAMPLE_START+SampleData,$3E70000
	dc.l	$B1CC-SAMPLE_START+SampleData,$9C30000
	dc.l	$C55E-SAMPLE_START+SampleData,$40000
	dc.l	$C566-SAMPLE_START+SampleData,$1F40000
	dc.l	$C94E-SAMPLE_START+SampleData,$5670000	; unused
	dc.l	$D41C-SAMPLE_START+SampleData,$55F0000	;   "
	dc.l	$DEDA-SAMPLE_START+SampleData,$57F0000	;   "

lA0B0 	=		SampleAdr-8


lA100		dc.l	0
lA104		dc.l	0
lA108		dc.l	0
lA10C		dc.l	0
lA110		dc.l	0
lA114		dc.l	0
lA118		dc.l	0
lA11C		dc.l	0
lA120		dcb.b	2,0

l6D40		dc.b	0
l6D68		dc.b	0


;-------


SHO_SongEnd	dc.l	0		; SongEnd rout adr


SongsAdr
	dc.l	MusicData,$10000
	dc.l	MusicData+$f400-$e9d8,$13000
	dc.l	MusicData+$fca8-$e9d8,$12000
	dc.l	Music1,$13000
	dc.l	Music2,$13000
	dc.l	Music3,$13000
	dc.l	Music4,$13000

MusicData					; $e9d8 .. $
	incbin	b:SuperHangOn/SHO_Main.mus

Music1	incbin	b:SuperHangOn/SHO_Tune1.mus
Music2	incbin	b:SuperHangOn/SHO_Tune2.mus
Music3	incbin	b:SuperHangOn/SHO_Tune3.mus
Music4	incbin	b:SuperHangOn/SHO_Tune4.mus


;-------

	section	SHO_smp,data_c

lA078	dcb.l	4,0				; EmptySample

SampleData					; $a122 .. $c566
	incbin	b:SuperHangOn/SHO_Main.smp

;-------

	end
