;********************************************* Date 16/02/91 *****
;*       NEWPLAYER V1.0 by ROLAMOTO (Paul Ryan) of PRISM         *
;*                 Other Members are : - HARD RESET              *
;*                                     - NEON                    *
;*                                     - LOUIE THE FLY           *
;* NOTE : When you pass this great software around, please give  *
;* them a copy with this header message in it.	If you don't,	 *
;* then you're an arsehole.					 *
;* This player is probably the fastest sound player available!   *
;* It will work with all soundtrackerV2.3 and above modules.     *
;* This is the uncomented source code (You don't get everything  *
;* for nothing!).  You may have to change the code at the bottom *
;* where it says "incbin", if you are not a MASTER SEKA coder.   *
;* Otherwise all is fine, have fun, because I didn't when I put  *
;* this masterpiece together.                                    *
;* Thanks to : NOISEV1.2 player for some of the sample effects.  *
;*             A big thankyou to a Demo that boasted it had      *
;*             a music player which ran at 2 to 5 rasters.  The  *
;*             majority of this code happens to be it.  The fact *
;*             is that the routine was not in soundtracker module*
;*             format.  I had to go from head to toe converting. *
;*             I also converted so that the player can use 31    *
;*             samples instead of just 15.  I made so many 	 *
;*             changes and enhancements, I believe I can call it *
;* 	       my own.						 *
;*   PS.  I have included four variables labelled as 'notes:'.   *
;*        These can be used to achieve equalisers, with a little *
;*        mathematics.  					 * 
;*                                                               *
;*   To Contact Us For Future Updates Or Just A Chat Write To    *
;*                                                               *
;*                        ROLAMOTO/HARD RESET:                   *
;*                        24 Gordon Rd,                          *
;*                        Ferny Hills, 4055.                     *
;*                        Qld, Australia.                        *
;*                                                               *
;*                        NEON:                                  *
;*                        41 Northview Outlook,                  *
;*                        Moorooka, Qld, 4105.                   *
;*                        Australia.                             *
;*                                                               *
;*****************************************************************

start:
	move.l	$4, a6
	jsr	-$84(a6)		; forbid
	bsr.s	NEWPLAYER_INIT

main:	move.l	$dff004, d0
	lsr.l	#8, d0
	and.w	#$01ff, d0
	cmp.w	#80, d0			; wait at line 80 for start
	bne.s	main			; of raster timer.
	move.w	#$a00, $dff180		; Raster timer is Rusty RED.

	bsr.l	NEWPLAYER_START

	move.w	#$0, $dff180		; end of raster timer.
	btst	#6, $bfe001
	bne.s	main

	bsr.l	NEWPLAYER_END
	move.l	$4, a6
	jsr	-$8a(a6)		; permit
	rts	

NEWPLAYER_INIT:
	bsr.l 	NEWPLAYER_END
	lea     musicdata(pc),a0
	lea     musicstructure(pc),a5
	move.b	#6, $29(a5)	
	move.b	#6, $2e(a5)
	move.l  a0,$24(a5)
	move.l  a0,$20(a5)
	add.l   #951,$24(a5)
	add.l   #1084,$20(a5)
	or.b    #2,$bfe001	
	move.b	#$40, $2a(a5)	
	tst.b	$2f(a5)
	beq.s	NP_1st
	rts
NP_1st:	move.l  $24(a5), a2
	move.w	#$7f, d1
	lea	$1(a2), a2
	moveq   #0,d0
NP_init1:    
	move.b  (a2)+,d2	
	cmp.b   d2,d0		
	bge.s   NP_init2	
	move.b  d2,d0		
NP_init2:   
	dbra    d1, NP_init1	
	addq.l	#1, d0
	lsl.l	#8, d0
	lsl.l	#2, d0		
	add.l	$20(a5), d0
	move.l	d0, a1		
	lea	42(a0), a3	
	moveq   #30,d7		
NP_init3:    
	tst.w   (a3)		
	bne.s   NP_init4	
	clr.l	(a0)+		
	clr.l	(a0)+		
	clr.l	(a0)+		
	clr.l	(a0)+ 		
	lea	30(a3), a3	
	dbra    d7, NP_init3
	move.b	#1, $2f(a5)
	rts
NP_init4:    
	move.l	a1, (a0)+	
	clr.l	(a1)		
	move.l	(a3), (a0)+	
	move.l	a1, d0		
	moveq	#0, d1
	move.w	4(a3), d1	
	lsl.l	#1, d1		
	add.l	d1, d0
	move.l	d0, (a0)+	
	move.w	6(a3), (a0)+	
	clr.w	(a0)+		
NP_init5:
	moveq   #0,d0
	move.w  (a3), d0	
	lsl.l	#1, d0		
	add.l   d0,a1		
	lea     30(a3), a3	
	dbra    d7, NP_init3
	move.b	#1, $2f(a5)
	rts

NEWPLAYER_END:	
	lea	$dff000, a6
	clr.w   $a8(a6)
        clr.w   $b8(a6)
        clr.w   $c8(a6)
        clr.w   $d8(a6)
        move.w  #15,$96(a6)
        rts

NEWPLAYER_START:
	lea     musicstructure(pc),a5
	addq.b  #1,$29(a5)	
	move.b	$29(a5), d0
	cmp.b   $2e(a5), d0
	bge.s   NP_music1
	bsr.l	repeat_and_effects
	rts

NP_music1:   
	lea	$dff000, a6
	clr.b   $29(a5)
	addq.b  #1,$2a(a5)	
	cmp.b   #$41,$2a(a5)	
	bne.s   NP_music4	
NP_music2:   			
	addq.b	#1,$2b(a5)	
	move.b	$2b(a5), d0
	lea	950+musicdata(pc), a0
	cmp.b   (a0),d0
	bhi.s   restart_music
	move.b  #1, $2a(a5)	
	addq.l  #1, $24(a5)	
	move.l  $24(a5),a0
	moveq   #0,d0
	move.b  (a0),d0
	lsl.l	#8, d0
	lsl.l	#2, d0
	lea	1084+musicdata(pc), a0
	add.l   d0,a0
	move.l  a0,$20(a5)	
	bra.s   NP_music4
restart_music:   
	clr.b	$2b(a5)		
	addq.l	#1, a0		
	move.l	a0, $24(a5)	
	bra.s   NP_music2
NP_music4:   
	clr.b	$2d(a5)		
	move.l  $20(a5),a0	
	add.l   #$10,$20(a5)	
	move.l  (a0),d0		
	lea	notes(pc), a2
	clr.w   d3
	moveq   #1,d2
	bsr.s   new_note
	bsr.l 	check_control_word
	move.l  4(a0),d0
	moveq   #2,d2
	bsr.s   new_note
	bsr.l 	check_control_word
	move.l  8(a0),d0
	moveq   #3,d2
	bsr.s   new_note
	bsr.l 	check_control_word
	move.l  12(a0),d0
	moveq   #4,d2
	bsr.s   new_note
	bsr.l  	check_control_word
	move.w  d3,$96(a6)	
	rts

new_note:
	move.w  d0,d5
	rol.w	#4, d0
	and.b	#$0f, d0
	move.l	d0, d1
	rol.l	#8, d0
	and.b	#$f0, d0
	or.b	d0, d1
	bne.s   new_note_init	
	clr.w	(a2)+
	rts
new_note_init:     
	moveq	#0, d0
	move.b	d1, d0		
	swap    d1
	and.w	#$0fff, d1	
	move.w	d1, (a2)+
	subq.w  #1,d0
	lsl.w   #4,d0
	lea	musicdata(pc), a1
	add.l   d0,a1
channel0:
	cmp.w   #1,d2
	bne.s   channel1
	clr.w   $a8(a6)
	move.l  a1,0(a5)
	move.l  (a1),$a0(a6)
	move.w  4(a1),$a4(a6)
	move.w  d1,$a6(a6)
	move.w  d1,$10(a5)
	move.w  6(a1),$18(a5)
	bset    #0,d3
	rts
channel1:    
	cmp.w   #2,d2
	bne.s   channel2
	clr.w   $b8(a6)
	move.l  a1,4(a5)
	move.l  (a1),$b0(a6)
	move.w  4(a1),$b4(a6)
	move.w  d1,$b6(a6)
	move.w  d1,$12(a5)
	move.w  6(a1),$1a(a5)
	bset    #1,d3
	rts
channel2:    
	cmp.w   #3,d2
	bne.s   channel3
	clr.w   $c8(a6)
	move.l  a1,8(a5)
	move.l  (a1),$c0(a6)
	move.w  4(a1),$c4(a6)
	move.w  d1,$c6(a6)
	move.w  d1,$14(a5)
	move.w  6(a1),$1c(a5)
	bset    #2,d3
	rts
channel3:    
	clr.w   $d8(a6)
	move.l  a1,$c(a5)
	move.l  (a1),$d0(a6)
	move.w  4(a1),$d4(a6)
	move.w  d1,$d6(a6)
	move.w  d1,$16(a5)
	move.w  6(a1),$1e(a5)
	bset    #3,d3
	rts

check_control_word:     
	move.w  d5,d6
	and.w   #$00ff,d5
	lsr.w	#8, d6 
	and.b   #$0f, d6
	tst.b   d6
	beq.s   ccwxit
	cmp.b   #$0c, d6
	beq.s	volume_set
	cmp.b   #$0b, d6
	beq.s   position_jump
	cmp.b   #$0e, d6
	beq.s   set_filter
	cmp.b	#$0f, d6
	beq.s	set_speed
	cmp.b	#$0d, d6
	beq.s	pattbreak
ccwxit:	rts

pattbreak:	
	move.b  #$40,$2a(a5)	
	rts

set_speed:
	move.b  d5,$2e(a5)	
	rts

set_filter:     
	btst	#0, d5
	beq.s   filter_off
	or.b    #2,$bfe001
	rts
filter_off:    
	and.b   #$fd,$bfe001
	rts

position_jump:     
	moveq   #0,d4
	move.b  d5,d4
	subq.b  #1,d4
	move.b  d4,$2b(a5)
	lea	952+musicdata(pc),a0
	add.l   d4,a0
	move.l  a0,$24(a5)	
	bra.s   pattbreak

volume_set:     
	cmp.w   #1,d2
	bne.s   volume_set2
	move.w  d5,$18(a5)
	rts
volume_set2:    
	cmp.w   #2,d2
	bne.s   volume_set3
	move.w  d5,$1a(a5)
	rts
volume_set3:    
	cmp.w   #3,d2
	bne.s   volume_set4
	move.w  d5,$1c(a5)
	rts
volume_set4:    
	move.w  d5,$1e(a5)
	rts

repeat_and_effects:
	move.l  $20(a5),a0	
	sub.l	#$10, a0
	move.l  (a0),d5		
	lea	$dff0a0, a6	
	lea     $10(a5),a5	
	bsr.l 	check_effect
	move.l  4(a0),d5
	lea	$10(a6), a6	
	lea     $2(a5),a5	
	bsr.l 	check_effect
	move.l  8(a0),d5
	lea	$10(a6), a6	
	lea     $2(a5),a5	
	bsr.l 	check_effect
	move.l  12(a0),d5
	lea	$10(a6), a6	
	lea     $2(a5),a5	
	bsr.l 	check_effect
	lea     musicstructure(pc),a5
	lea	$dff000, a6
	move.b	$28(a5), d7	
	btst    #0,d7
	beq.s   repeat_channel1
repeat_channel0:
	bclr    #0,d7
	move.l  0(a5),a0
	move.l  8(a0),$a0(a6)	
	move.w  12(a0),$a4(a6)	
	clr.l   0(a5)
repeat_channel1:
	btst    #1,d7
	beq.s   repeat_channel2
	bclr    #1,d7
	move.l  4(a5),a0
	move.l  8(a0),$b0(a6)	
	move.w  12(a0),$b4(a6)	
	clr.l   4(a5)
repeat_channel2:
	btst    #2,d7
	beq.s   repeat_channel3
	bclr    #2,d7
	move.l  8(a5),a0
	move.l  8(a0),$c0(a6)	
	move.w  12(a0),$c4(a6)	
	clr.l   8(a5)
repeat_channel3:
	btst    #3,d7
	beq.s   channel0_dma
	bclr    #3,d7
	move.l  $c(a5),a0
	move.l  8(a0),$d0(a6)	
	move.w  12(a0),$d4(a6)	
	clr.l   $c(a5)
channel0_dma:
	move.w  #$8000,d3
	tst.l   0(a5)
	beq.s   channel1_dma
	bset    #0,d7
	bset    #0,d3
channel1_dma:
	tst.l   4(a5)
	beq.s   channel2_dma
	bset    #1,d7
	bset    #1,d3
channel2_dma:
	tst.l   8(a5)
	beq.s   channel3_dma
	bset    #2,d7
	bset    #2,d3
channel3_dma:
	tst.l   $c(a5)
	beq.s   set_dma_and_volume
	bset    #3,d7
	bset    #3,d3
set_dma_and_volume:
	move.b	d7, $28(a5)
	move.w  d3,$96(a6)
	move.w  $18(a5),$a8(a6)
	move.w  $1a(a5),$b8(a6)
	move.w  $1c(a5),$c8(a6)
	move.w  $1e(a5),$d8(a6)
	rts

check_effect:
	move.w  d5,d6
	and.w	#$0fff, d6
	beq.s	setup_period
	move.w  d5,d6
	and.w   #$00ff,d5
	lsr.w	#8, d6 
	and.b   #$0f, d6	
	beq.s	NP_arpeggio
	cmp.b	#$1,d6
	beq.l	NP_portup
	cmp.b	#$2,d6
	beq.l	NP_portdown
;	cmp.b	#$3,d6			; Couldn't be bothered with it.
;	beq.l	myport			; Not many use this effect anyway.
	cmp.b	#$4,d6
	beq.l	NP_vib
	bsr.s	setup_period
	cmp.b	#$a,d6
	beq.l	NP_volslide
	rts
			
setup_period:		
	move.w	(a5),$6(a6)
	rts

NP_arpeggio:
	lea	musicdata(pc), a1
	moveq	#0,d0
	move.b	$31(a1),d0	
	divs	#$3,d0
	swap	d0
	or.w	d0, d0
	beq.s	NP_arp2
	cmp.w	#$2,d0
	beq.s	NP_arp1
	moveq	#0,d0
	move.b	d5,d0
	lsr.b	#4,d0
	bra.s	NP_arp3
NP_arp1:moveq	#0,d0
	move.b	d5,d0
	and.b	#$f,d0
	bra.s	NP_arp3
NP_arp2:move.w	(a5),d2		
	bra.s	NP_arp4
NP_arp3:lsl.w	#1,d0
	moveq	#0,d1
	move.w	(a5),d1
	lea	NP_periods(pc),a2
	moveq	#$24,d7
NP_arploop:
	move.w	(a2,d0.w),d2
	cmp.w	(a2),d1
	bge.s	NP_arp4
	lea	$2(a2), a2
	dbf	d7, NP_arploop
	rts
NP_arp4:move.w	d2,$6(a6)
	rts

NP_portup:
	moveq	#0,d0
	move.b	d5,d0
	sub.w	d0,(a5)
	move.w	(a5),d0
	and.w	#$fff,d0
	cmp.w	#$71,d0
	bpl.s	NP_por2
	and.w	#$f000,(a5)
	or.w	#$71,(a5)
NP_por2:move.w	(a5),d0
	and.w	#$fff,d0
	move.w	d0,$6(a6)
	rts

NP_portdown:
	add.w	d5,(a5)	
	move.w	(a5),d5	
	and.w	#$0fff,d5
	cmp.w	#$0358,d5
	bmi.s	pd_1
	and.w	#$f000,(a5)
	or.w	#$0358,(a5)
pd_1:	move.w	(a5),d5
	and.w	#$0fff,d5
	move.w	d5,$6(a6)	
	rts

NP_vib:	lea	musicstructure(pc), a1
	move.b	d5,d0
	beq.s	NP_vi
	move.b	d0,$2c(a1)
NP_vi:	move.b	$2d(a1),d0
	lea	NP_sin(pc),a2
	lsr.w	#$2,d0
	and.w	#$1f,d0
	moveq	#0,d2
	move.b	(a2,d0.w),d2
	move.b	$2c(a1),d0
	and.w	#$f,d0
	mulu	d0,d2
	lsr.w	#$6,d2
	move.w	(a5),d0
	tst.b	$2d(a1)
	bmi.s	NP_vibmin
	add.w	d2,d0
	bra.s	NP_vib2
NP_vibmin:
	sub.w	d2,d0
NP_vib2:move.w	d0,$6(a6)	
	move.b	$2c(a1),d0
	lsr.w	#$2,d0
	and.w	#$3c,d0
	add.b	d0,$2d(a1)
	rts

NP_volslide:
	move.w	d5, d0
	lsr.b	#4,d0
	tst.b	d0
	beq.s	NP_voldown
	add.w	d0,$8(a5)	
	cmp.w	#$40,$8(a5)
	bmi.s	vol_a1
	move.w	#$40,$8(a5)
vol_a1: move.w	$8(a5),$8(a6)
	rts
NP_voldown:
	and.b	#$f,d5
	sub.w	d5,$8(a5)
	bpl.s	vol_b1
	clr.w	$8(a5)
vol_b1:	move.w	$8(a5),$8(a6)
	rts

NP_sin:
	dc.b $00,$18,$31,$4a,$61,$78,$8d,$a1,$b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
	dc.b $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5,$b4,$a1,$8d,$78,$61,$4a,$31,$18
NP_periods:
	dc.w $0358,$0328,$02fa,$02d0,$02a6,$0280,$025c,$023a,$021a,$01fc,$01e0
	dc.w $01c5,$01ac,$0194,$017d,$0168,$0153,$0140,$012e,$011d,$010d,$00fe
	dc.w $00f0,$00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097,$008f,$0087
	dc.w $007f,$0078,$0071,$0000,$0000
notes:	dc.w	0		; channel 0
	dc.w	0		; channel 1
	dc.w	0		; channel 2
	dc.w	0		; channel 3
musicstructure:	blk.b	48, 0 
musicdata:	incbin	"df0:modules/mod.tennis" 

end:
