* MultiPlayer
* Copyright (C) 1992 Bryan Ford
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* I (the author of MultiPlayer) can be contacted on the Internet at
* "bryan.ford@m.cc.utah.edu".  See "Player.doc" for other addresses.
*
* Note:  This playroutine was not originally written by me.  In general
* these playroutines are public domain, so I am bringing the versions
* modified for MultiPlayer under the General Public License.  In the
* few cases of already-copyrighted playroutines, the above copyright
* notice applies only to the parts of the file written by me.
*
* $Id: ntpackplay.asm,v 4.1 92/06/21 11:14:05 BAF Exp Locker: BAF $
*

	include "player.i"

	xref	modmem
	xref	getfreqmodspeed,dmawait

	xdef	ntpackstart

	code	text

ntpackstart
	plstartret 9$

        cnop    0,4
	dc.l	gmod_Hook
9$	gmodnop
	gmodbra	_pack_init		; StartMusic
	gmodbra	_pack_end		; StopMusic
	gmodnop
	gmodnop
	moveq	#1,d0			; ContinueMusic
	rts
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodnop
	gmodbra	getfreqmodspeed		; GetFrequency
	gmodbra	_pack_music		; TimerTick
	lea	name(pc),a0		; GetMakerName
	move.l	a0,d0
	rts

;*******************************
;*** NOISETRACKER COMPRESSED ***
;*** REPLAYROUTINE 1.3 D     ***
;*** IMPROVED ON 15/03/91    ***
;*** BY ANTICHRIST OF UFO    ***
;*******************************

; This routine is fully pc-relative.
; Don't change anything in mt_vars
; ('coz the offsets below won't fit anymore!).

; Include your PACKED module at mt_data (still the same!)
; To init, jump to Offset 0
; ťť Load your start position to d0.l ŤŤ
; To play, jump to Offset 4
; To stop, jump to Offset 8

mt_speed	equ 0
mt_songpos	equ 1
mt_pattpos	equ 2
mt_counter	equ 4
mt_break	equ 5
mt_dmacon	equ 6
mt_samplestarts equ 8
mt_voice1	equ 132
mt_voice2	equ 166
mt_voice3	equ 200
mt_voice4	equ 234

_pack_init:
; !!!!
	movem.l	d0-d7/a0-a6,-(a7)
; !!!!
	move.l	d0,-(sp)
	lea	mt_vars(pc),a4
	move.l	modmem,a0
	move.l	a0,a1
	lea	$176(a1),a1
	moveq	#$7f,d0
	moveq	#0,d1
	moveq	#0,d2

.seek	move.b	(a1)+,d1
	cmp.b	d1,d2
	bge.s	.nohi
	move.b	d1,d2
.nohi	dbf	d0,.seek

	move.l	modmem,(a0)
	lea	$1f6(a0),a0
	lea	mt_patterns(pc),a1
	move.w	#$5041,d0
	move.w	#$5454,d1
.getPatt
	cmp.w	(a0)+,d0
	bne.s	.getPatt
	cmp.w	(a0)+,d1
	bne.s	.getPatt
	move.l	a0,(a1)+
	dbf	d2,.getPatt

	lea	mt_samplestarts(a4),a1
	move.l	modmem,a2
	move.l	a2,d2
	moveq	#31-1,d1
mt_lop3:
	move.l	(a2),d0
	add.l	d2,d0
	move.l	d0,(a1)+
	lea	12(a2),a2
	dbf	d1,mt_lop3

	move.l	(sp)+,d0
	moveq	#0,d0			;insert this line, if you don't
	bsr	setChannel		;want to start your song at any
					;other position than 0
	move.b	#6,mt_speed(a4)
	clr.w	$dff0a8
	clr.w	$dff0b8
	clr.w	$dff0c8
	clr.w	$dff0d8
	clr.b	mt_counter(a4)
	clr.w	mt_pattpos(a4)

; !!!!
	movem.l	(a7)+,d0-d7/a0-a6
; !!!!
	rts

_pack_end:
	clr.w	$dff0a8
	clr.w	$dff0b8
	clr.w	$dff0c8
	clr.w	$dff0d8
	move.w	#$f,$dff096
	rts
_pack_music:
; !!!!
	movem.l	d0-d7/a0-a6,-(a7)
; !!!!
	bsr	mt_music
; !!!!
	movem.l	(a7)+,d0-d7/a0-a6
; !!!!
	rts

mt_music:
	lea	mt_vars(pc),a4
	addq.b	#1,mt_counter(a4)
	move.b	mt_counter(a4),D0
	cmp.b	mt_speed(a4),D0
	blt.s	mt_nonew
	clr.b	mt_counter(a4)
	bra	mt_getnew

mt_nonew:
	lea	mt_voice1(a4),a6
	lea	$dff0a0,a5
	bsr	mt_checkcom
	lea	mt_voice2(a4),a6
	lea	$10(a5),a5
	bsr	mt_checkcom
	lea	mt_voice3(a4),a6
	lea	$10(a5),a5
	bsr	mt_checkcom
	lea	mt_voice4(a4),a6
	lea	$10(a5),a5
	bsr	mt_checkcom
	bra	mt_endr

mt_arpeggio:
	moveq	#0,d0
	move.b	mt_counter(a4),d0
	divs	#3,d0
	swap	d0
	cmp.w	#0,d0
	beq.s	mt_arp2
	cmp.w	#2,d0
	beq.s	mt_arp1

	moveq	#0,d0
	move.b	3(a6),d0
	lsr.b	#4,d0
	bra.s	mt_arp3
mt_arp1:
	moveq	#0,d0
	move.b	$3(a6),d0
	and.b	#$f,d0
	bra.s	mt_arp3
mt_arp2:
	move.w	$10(a6),d2
	bra.s	mt_arp4
mt_arp3:
	asl.w	#1,d0
	moveq	#0,d1
	move.w	$10(a6),d1
	lea	mt_periods(pc),a0
	moveq	#$24,d7
mt_arploop:
	move.w	0(a0,d0.w),d2
	cmp.w	(a0),d1
	bge.s	mt_arp4
	addq.l	#2,a0
	dbf	d7,mt_arploop
	rts
mt_arp4: move.w	d2,$6(a5)
	rts

mt_getnew:
	move.l	modmem,a3
	clr.w	mt_dmacon(a4)
	lea	$dff0a0,a5
	lea	mt_voice1(a4),a6
	bsr.s	mt_playvoice
	lea	$10(a5),a5
	lea	mt_voice2(a4),a6
	bsr.s	mt_playvoice
	lea	$10(a5),a5
	lea	mt_voice3(a4),a6
	bsr.s	mt_playvoice
	lea	$10(a5),a5
	lea	mt_voice4(a4),a6
	bsr.s	mt_playvoice
	bra	mt_setdma

mt_playvoice:
	tst.w	32(a6)
	beq.s	.nodelay
	subq.w	#1,32(a6)
	bra.s	.morevoice
.nodelay
	move.l	28(a6),a0
	moveq	#0,d2
	move.b	(a0),d2
	cmpi.b	#$ff,d2
	bne.s	.nocrunch
	move.b	1(a0),33(a6)
	addq.l	#2,28(a6)
	clr.l	(a6)
	bra.s	mt_playvoice
.nocrunch
	move.b	d2,d0
	andi.b	#$3f,d2
	beq.s	.noset
	lsl.w	#1,d2
	lea	mt_periods(pc),a1
	move.w	-2(a1,d2.w),d2
.noset	btst	#7,d0
	beq.s	.nohisamp
	bset	#12,d2
.nohisamp
	move.w	d2,(a6)
	move.b	1(a0),2(a6)
	clr.b	3(a6)
	btst	#6,d0
	bne.s	.nocom
	move.b	2(a0),3(a6)
	addq.l	#1,28(a6)
.nocom	addq.l	#2,28(a6)
.morevoice
	moveq	#0,d2
	move.b	2(a6),d2
	and.b	#$f0,d2
	lsr.b	#4,d2
	move.b	(a6),d0
	and.b	#$f0,d0
	or.b	d0,d2
	tst.b	d2
	beq.s	mt_setregs
	lea	mt_samplestarts(a4),a1
	subq.l	#1,d2
	move.l	d2,d4
	mulu	#12,d4
	asl.l	#2,d2
	move.l	0(a1,d2.l),4(a6)
	move.w	4(a3,d4.l),8(a6)
	move.w	6(a3,d4.l),18(a6)
	moveq	#0,d3
	move.w	8(a3,d4.l),d3
	tst.w	d3
	beq.s	mt_noloop
	move.l	4(a6),d2
	lsl.l	#1,d3
	add.l	d3,d2
	move.l	d2,$a(a6)
	move.w	8(a3,d4.l),d0
	add.w	10(a3,d4.l),d0
	move.w	d0,8(a6)
	move.w	10(a3,d4.l),$e(a6)
	move.w	$12(a6),$8(a5)
	bra.s	mt_setregs
mt_noloop:
	move.l	4(a6),d2
	add.l	d3,d2
	move.l	d2,10(a6)
	move.w	10(a3,d4.l),14(a6)
	move.w	18(a6),8(a5)
mt_setregs:
	move.w	(a6),d0
	andi.w	#$fff,d0
	beq	mt_checkcom2
	move.b	2(a6),d0
	and.b	#$F,d0
	cmp.b	#$3,d0
	bne.s	mt_setperiod
	bsr	mt_setmyport
	bra	mt_checkcom2

mt_setperiod:
	move.w	(a6),$10(a6)
	and.w	#$fff,$10(a6)
	move.w	$14(a6),d0
	move.w	d0,$dff096
	clr.b	$1b(a6)

	move.l	4(a6),(a5)
	move.w	8(a6),4(a5)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	move.w	d0,$6(a5)
	move.w	20(a6),d0
	or.w	d0,mt_dmacon(a4)
	bra	mt_checkcom2

mt_setdma:
        jsr     dmawait
	move.w	mt_dmacon(a4),d0
	or.w	#$8000,d0
	move.w	d0,$dff096
        jsr     dmawait

	lea	$dff000,a5
	lea	mt_voice4(a4),a6
	move.l	$a(a6),$d0(a5)
	move.w	$e(a6),$d4(a5)
	lea	mt_voice3(a4),a6
	move.l	$a(a6),$c0(a5)
	move.w	$e(a6),$c4(a5)
	lea	mt_voice2(a4),a6
	move.l	$a(a6),$b0(a5)
	move.w	$e(a6),$b4(a5)
	lea	mt_voice1(a4),a6
	move.l	$a(a6),$a0(a5)
	move.w	$e(a6),$a4(a5)
	addq.b	#1,mt_pattpos+1(a4)
	cmpi.b	#64,mt_pattpos+1(a4)
	bne.s	mt_endr
mt_nex:	clr.b	mt_pattpos+1(a4)
	clr.b	mt_break(a4)
	addq.b	#1,mt_songpos(a4)
	andi.b	#$7f,mt_songpos(a4)
	move.l	a0,-(a7)
	move.l	modmem,a0
	move.b	mt_songpos(a4),d1
	cmp.b	$174(a0),d1
	bne.s	.not
	move.b	$175(a0),mt_songpos(a4)
.not	moveq	#0,d0
	movem.l	(a7)+,a0
	move.b	mt_songpos(a4),d0
	bsr	setChannel
mt_endr:
	tst.b	mt_break(a4)
	bne.s	mt_nex
	rts

mt_setmyport:
	move.w	(a6),d2
	and.w	#$fff,d2
	move.w	d2,$18(a6)
	move.w	$10(a6),d0
	clr.b	$16(a6)
	cmp.w	d0,d2
	beq.s	mt_clrport
	bge.s	mt_rt
	move.b	#$1,$16(a6)
	rts
mt_clrport:
	clr.w	$18(a6)
mt_rt:	rts

mt_myport:
	move.b	3(a6),d0
	beq.s	mt_myslide
	move.b	d0,$17(a6)
	clr.b	3(a6)
mt_myslide:
	tst.w	$18(a6)
	beq.s	mt_rt
	moveq	#0,d0
	move.b	$17(a6),d0
	tst.b	$16(a6)
	bne.s	mt_mysub
	add.w	d0,$10(a6)
	move.w	$18(a6),d0
	cmp.w	$10(a6),d0
	bgt.s	mt_myok
	move.w	$18(a6),$10(a6)
	clr.w	$18(a6)
mt_myok: move.w	$10(a6),$6(a5)
	rts
mt_mysub:
	sub.w	d0,$10(a6)
	move.w	$18(a6),d0
	cmp.w	$10(a6),d0
	blt.s	mt_myok
	move.w	$18(a6),$10(a6)
	clr.w	$18(a6)
	move.w	$10(a6),$6(a5)
	rts

mt_vib:	move.b	3(a6),d0
	beq.s	mt_vi
	move.b	d0,$1a(a6)

mt_vi:	move.b	$1b(a6),d0
	lea	mt_sin(pc),a4
	lsr.w	#$2,d0
	and.w	#$1f,d0
	moveq	#0,d2
	move.b	0(a4,d0.w),d2
	move.b	$1a(a6),d0
	and.w	#$f,d0
	mulu	d0,d2
	lsr.w	#$6,d2
	move.w	$10(a6),d0
	tst.b	$1b(a6)
	bmi.s	mt_vibmin
	add.w	d2,d0
	bra.s	mt_vib2
mt_vibmin:
	sub.w	d2,d0
mt_vib2: move.w	d0,$6(a5)
	move.b	$1a(a6),d0
	lsr.w	#$2,d0
	and.w	#$3c,d0
	add.b	d0,$1b(a6)
	lea	mt_vars(pc),a4
	rts

mt_nop:	move.w	$10(a6),$6(a5)
	rts

mt_checkcom:
	move.w	2(a6),d0
	and.w	#$fff,d0
	beq.s	mt_nop
	move.b	2(a6),d0
	and.b	#$f,d0
	tst.b	d0
	beq	mt_arpeggio
	cmp.b	#$1,d0
	beq.s	mt_portup
	cmp.b	#$2,d0
	beq	mt_portdown
	cmp.b	#$3,d0
	beq	mt_myport
	cmp.b	#$4,d0
	beq	mt_vib
	move.w	$10(a6),$6(a5)
	cmp.b	#$a,d0
	beq.s	mt_volslide
	rts

mt_volslide:
	moveq	#0,d0
	move.b	$3(a6),d0
	lsr.b	#4,d0
	tst.b	d0
	beq.s	mt_voldown
	add.w	d0,$12(a6)
	cmp.w	#$40,$12(a6)
	bmi.s	mt_vol2
	move.w	#$40,$12(a6)
mt_vol2: move.w	$12(a6),$8(a5)
	rts

mt_voldown:
	moveq	#0,d0
	move.b	$3(a6),d0
	and.b	#$f,d0
	sub.w	d0,$12(a6)
	bpl.s	mt_vol3
	clr.w	$12(a6)
mt_vol3: move.w	$12(a6),$8(a5)
	rts

mt_portup:
	moveq	#0,d0
	move.b	3(a6),d0
	sub.w	d0,$10(a6)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	cmp.w	#$71,d0
	bpl.s	mt_por2
	and.w	#$f000,$10(a6)
	or.w	#$71,$10(a6)
mt_por2: move.w	$10(a6),d0
	and.w	#$fff,d0
	move.w	d0,$6(a5)
	rts

mt_portdown:
	clr.w	d0
	move.b	$3(a6),d0
	add.w	d0,$10(a6)
	move.w	$10(a6),d0
	and.w	#$fff,d0
	cmp.w	#$358,d0
	bmi.s	mt_por3
	and.w	#$f000,$10(a6)
	or.w	#$358,$10(a6)
mt_por3: move.w	$10(a6),d0
	and.w	#$fff,d0
	move.w	d0,$6(a5)
	rts

mt_checkcom2:
	move.b	2(a6),d0
	and.b	#$f,d0
	cmp.b	#$e,d0
	beq.s	mt_setfilt
	cmp.b	#$d,d0
	beq.s	mt_pattbreak
	cmp.b	#$b,d0
	beq.s	mt_posjmp
	cmp.b	#$c,d0
	beq.s	mt_setvol
	cmp.b	#$f,d0
	beq.s	mt_setspeed
	rts

mt_setfilt:
	move.b	$3(a6),d0
	and.b	#$1,d0
	asl.b	#$1,d0
	and.b	#$fd,$bfe001
	or.b	d0,$bfe001
	rts
mt_posjmp:
	move.b	3(a6),d0
	subq.b	#1,d0
	move.b	d0,mt_songpos(a4)
mt_pattbreak:
	not.b	mt_break(a4)
	rts
mt_setvol:
	cmp.b	#$40,$3(a6)
	ble.s	mt_vol4
	move.b	#$40,$3(a6)
mt_vol4:
	move.b	$3(a6),$8(a5)
	rts

mt_setspeed:
	cmp.b	#$1f,$3(a6)
	ble.s	mt_sets
	move.b	#$1f,$3(a6)
mt_sets:
	move.b	$3(a6),d0
	beq.s	mt_rts2
	move.b	d0,mt_speed(a4)
	clr.b	mt_counter(a4)
mt_rts2:
	rts

setChannel:
	move.l	modmem,a0
	lea	mt_vars(pc),a4
	cmp.b	$174(a0),d0
	blt.s	.valid
	moveq	#0,d0
.valid	move.b	d0,mt_songpos(a4)
	lea	$176(a0),a0
	move.b	0(a0,d0.w),d0
	lsl.l	#2,d0
	lea	mt_voice1(a4),a1
	lea	mt_patterns(pc),a0
	move.l	0(a0,d0.w),a0
	move.l	a0,d2
	move.l	d2,d0
	addq.l	#6,d0
	moveq	#3,d1
	bra.s	.dochan
.setchannel
	lea	34(a1),a1
	moveq	#0,d0
	move.w	(a0)+,d0
	add.l	d2,d0
.dochan
	move.l	d0,28(a1)
	clr.w	32(a1)
	dbf	d1,.setchannel
	rts

mt_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

mt_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

mt_patterns:
	ds.l	64
mt_vars:			;*** DON'T CHANGE ANYTHING BELOW ***
	DC.b	6
	DC.b	0
	DC.w	0
	DC.b	0
	DC.b	0
	DC.w	0
;mt_samplestarts
	ds.L	$1f

;mt_voice1
	ds.w	10
	DC.w	1
	ds.w	3
	dc.l	0
	dc.w	0

;mt_voice2
	ds.w	10
	DC.w	2
	ds.w	3
	dc.l	0
	dc.w	0

;mt_voice3
	ds.w	10
	DC.w	4
	ds.w	3
	dc.l	0
	dc.w	0

;mt_voice4
	ds.w	10
	DC.w	8
	ds.w	3
	dc.l	0
	dc.w	0

;atdp Coke's Touchdown !

name	dc.b	"NoiseTracker Packed",0

	end
