*************************************************
*             Muzak  Replay-Routine             *
*               Version 1.2 (.23)               *
*						*
*     © copyright 8/1987 by Karsten Obarski   	*
*      3000 Hannover 61  Anderter Strase 1	*
*	       Tel.:  0511/584293		*
*************************************************
;effect (1) appregiato  form = 1.halfup , 2.halfup
;effect (2) pitchbend   form = 0-f down , 0-f up

*************************************************
* main program-loop
*************************************************
;org	$xxxxxx
;load	$xxxxxx
;start:	bra	muzakstart		;startaddress +0
;	bra	preparemuzak		;startaddress +4
;	bra	enablereplay		;startaddress +8
;	bra	disablereplay		;startaddress +12
*************************************************

start:	jsr	preparemuzak
	move.l	$6c,framirqsave		;set frame-flop irq
	move.l	#frameirq,$6c
	jsr	enablereplay

main:	btst	#6,$bfe001
	bne	main

	jsr	disablereplay
	move.l	framirqsave,$6c
	clr.l	d0
end:	rts

*************************************************
* first settings before muzakstart
*************************************************
preparemuzak:
	move.l	#snd1,sounds+0
	move.l	#snd2,sounds+4
	move.l	#snd3,sounds+8
	move.l	#snd4,sounds+12
	move.l	#snd5,sounds+16
	move.l	#snd6,sounds+20
	move.l	#snd7,sounds+24
	move.l	#snd8,sounds+28
	move.l	#snd9,sounds+32
	move.l	#snda,sounds+36
	move.l	#sndb,sounds+40
	move.l	#sndc,sounds+44
	move.l	#sndd,sounds+48
	move.l	#snde,sounds+52
	move.l	#sndf,sounds+56
	lea.l	samples,a0
	move.l	#geslaenge,d0		;code or endcode samples
docode:	eor.b	#$55,(a0)+
	subq.l	#1,d0
	cmp.l	#0,d0
	bne.s	docode
	move.l	#sounds,a0		;clear first longw
	clr.l	d0			;in all samples
clrsam:	move.l	(a0,d0.l),a1
	clr.l	(a1)
	addq.l	#4,d0
	cmp.l	#60,d0
	bne	clrsam	
	lea.l	muzakdata,a0
	move.b	470(a0),numofpatt+1	;save #of patts
	rts

*************************************************
* enable replay routine 
*************************************************
enablereplay:
	move.w	#$ffff,playmode
	move.w	#00,$dff0a8
	move.w	#00,$dff0b8
	move.w	#00,$dff0c8
	move.w	#00,$dff0d8
	clr.l	timerpos
	clr.l	trackpos
	clr.l	patternpos	
	rts

*************************************************
* disable replay routine 
*************************************************
disablereplay:
	clr.w	playmode
	move.w	#00,$dff0a8
	move.w	#00,$dff0b8
	move.w	#00,$dff0c8
	move.w	#00,$dff0d8
	move.w	#$f,$dff096
	rts

*************************************************
* complete muzak replayer (muzakstart > muzakend)
*************************************************
	;datach x format
	;w +0	current note
	;b +2	sound#
	;b +3	effect
	;l +4	sndstart
	;w +8	sndlen
	;l +10	repeatstart
	;w +14	repeatlen
	;w +16	last saved note
	;w +18	volume of sample
	;w +20	dma-bit
	datach0:blk.l	5,0
	dc.w	1
	datach1:blk.l	5,0
	dc.w	2
	datach2:blk.l	5,0
	dc.w	4
	datach3:blk.l	5,0
	dc.w	8
	patternpos:	dc.l	0
	trackpos:	dc.l	0
	timerpos:	dc.l	0
	muzakdata:	blk.b	2,0	;patterndata
	sounds:		blk.l	15,0
	numofpatt:	dc.w	0
	playmode:	dc.w	0
	enablebits:	dc.w	0
	notetable:
	dc.w	856,808,762,720,678,640
	dc.w	604,570,538,508,480,453
	dc.w	428,404,381,360,339,320
	dc.w	302,285,269,254,240,226  
	dc.w	214,202,190,180,170,160
	dc.w	151,143,135,127,120,113
	dc.w	000
*************************************************
muzakstart:
	movem.l	d0-d7/a0-a6,-(a7)
	addq.l	#1,timerpos		;control timing
	cmp.l	#6,timerpos
	bne.s	effecthandler
	clr.l	timerpos
	bra 	replayhandler

*************************************************
* handle possible effects
*************************************************
effecthandler:
eff0:	lea.l	datach0,a6
	cmp.b	#0,3(a6)
	beq.s	eff1
	move.l	#$dff0a0,a5
	bsr.s	effcmp
eff1:	lea.l	datach1,a6
	cmp.b	#0,3(a6)
	beq.s	eff2
	move.l	#$dff0b0,a5
	bsr.s	effcmp
eff2:	lea.l	datach2,a6
	cmp.b	#0,3(a6)
	beq.s	eff3
	move.l	#$dff0c0,a5
	bsr.s	effcmp
eff3:	lea.l	datach3,a6
	cmp.b	#0,3(a6)
	beq.s	eff4
	move.l	#$dff0d0,a5
	bsr.s	effcmp
eff4:	bra	muzakend
effcmp:	move.b	2(a6),d0		;compare effect #
	and.b	#$0f,d0
	cmp.b	#1,d0
	beq	appreggiato		;appre-effect (#1)
	cmp.b	#2,d0
	beq	pitchbend		;slide up/down(#4)
	rts

*************************************************
* effect-module (1) appregiato / timbre
*************************************************
appreggiato:
	cmp.l	#1,timerpos
	beq.s	trans2			;1. transposed note
	cmp.l	#2,timerpos
	beq.s	trans3			;2. transposed note
	cmp.l	#3,timerpos
	beq.s	notrans			;original note
	cmp.l	#4,timerpos
	beq.s	trans2			;1. transposed note
	cmp.l	#5,timerpos
	beq.s	trans3			;2. transposed note
	rts
trans2:	clr.l	d0			;2nd note
	move.b	3(a6),d0		;effectbyte
	lsr.b	#4,d0			;upper nibble
	bra.s	starttranspose
trans3:	clr.l	d0			;3rd note
	move.b	3(a6),d0		;effectbyte
	and.b	#$0f,d0			;lower nibble
	bra.s	starttranspose
notrans:move.w	16(a6),d2		;last saved note
	bra.s	startt2
starttranspose:
	lsl.l	#1,d0			;transpose-wert *2 ...
	clr.l	d1			;b'cause wordlen in table
	move.w	16(a6),d1		;last saved note
	lea.l	notetable,a0
startt1:move.w	(a0,d0.l),d2		;get transposed note
	cmp.w	(a0),d1			;search last note in table
	beq.s	startt2
	addq.l	#2,a0
	bra.s	startt1
startt2:move.w	d2,6(a5)		;set note  $dff0x6
	rts

*************************************************
* effect-module (2) pitchwheel
*************************************************
pitchbend:
	clr.l	d0			;2nd note
	move.b	3(a6),d0		;effectbyte
	lsr.b	#4,d0			;upper nibble
	cmp.b	#0,d0
	beq.s	pitch2
	add.w	d0,(a6)
	move.w	(a6),6(a5)		;set note
	rts
pitch2:	clr.l	d0			;3rd note
	move.b	3(a6),d0		;effectbyte
	and.b	#$0f,d0			;lower nibble
	cmp.b	#0,d0
	beq.s	pitch3
	sub.w	d0,(a6)
	move.w	(a6),6(a5)		;set note
pitch3:	rts

*************************************************
* replay-module
*************************************************
replayhandler:
	lea.l	muzakdata,a0		;top offset
	move.l	a0,a3
	add.l	#12,a3			;start of sndpreferences
	move.l	a0,a2
	add.l	#472,a2			;start of tracksdata
	add.l	#600,a0			;start of patterndata
	move.l	trackpos,d0
	clr.l	d1			;here was a bugg
	move.b	(a2,d0.l),d1		;get patt ptr
	mulu	#1024,d1		;with patternlen
	add.l	patternpos,d1		;add 16tel position
	clr.w	enablebits		;no start if no note

	move.l	#$dff0a0,a5		;handle chanel0
	lea.l	datach0,a6
	bsr.s	soundhandler
	move.l	#$dff0b0,a5		;handle chanel1
	lea.l	datach1,a6
	bsr.s	soundhandler
	move.l	#$dff0c0,a5		;handle chanel2
	lea.l	datach2,a6
	bsr.s	soundhandler
	move.l	#$dff0d0,a5		;handle chanel3
	lea.l	datach3,a6
	bsr.s	soundhandler
	bra	assume

soundhandler:
	move.l	(a0,d1.l),(a6)		;note, snd# & effect
	addq.l	#4,d1			;aha
	clr.l	d2
	move.b	2(a6),d2		;get sound#
	and.b	#$f0,d2			;kill effect number
	lsr.b	#4,d2			;shift to lo-nibble
	cmp.b	#00,d2			;no soundchange?
	beq.s	notehandler		;than forget it
	clr.l	d3
	lea.l	sounds-4,a1		;sample ptr table
	move.l	d2,d4			;exch soundnumber
	mulu	#4,d2			;calc pointer
	mulu	#30,d4			;soundpreferernce
	move.l	(a1,d2.l),4(a6)		;store sndstart
	move.w	(a3,d4.l),8(a6)		;store sndlen
	move.w	2(a3,d4.l),18(a6)	;store volume
	move.w	4(a3,d4.l),d3		;repeatstart value
	cmp.w	#0,d3			;sustain-sound ?
	beq.s	sndhan2			;then..
	move.l	4(a6),d2		;add repstart to ..
	add.l	d3,d2			;sndstart to ..
	move.l	d2,4(a6)		;store soundstart
	move.l	d2,10(a6)		;store repeatstart
	move.w	6(a3,d4),8(a6)		;store soundlen
	move.w	6(a3,d4),14(a6)		;store repeatlen
	move.w	18(a6),8(a5)		;set new volume 
	bra.s	notehandler
sndhan2:move.l	4(a6),d2		;add repstart to ..
	add.l	d3,d2			;sndstart to ..
	move.l	d2,10(a6)		;store repeatstart
	move.w	6(a3,d4.l),14(a6)	;store repeatlen
	move.w	18(a6),8(a5)		;set new volume 
notehandler:
	cmp.w	#00,(a6)		;is a new note set?
	beq.s	handlerend		;then forget it
	move.w	(a6),16(a6)		;save note for effect
	move.w	20(a6),$dff096		;clear dma-bit
	move.l	4(a6),0(a5)		;set sndstart
	move.w	8(a6),4(a5)		;set sndlen
	move.w	0(a6),6(a5)		;set period
	move.w	20(a6),d0
	or.w	d0,enablebits		;set enable if needed
handlerend:
	rts

assume:	move.l	#300,d0
ass2:	dbra	d0,ass2			;wait a while
	move.l	#$8000,d0
	add.w	enablebits,d0		;enable used dmas
	move.w	d0,$dff096
ass3:	move.l	#datach3,a6
	cmp.w	#1,14(a6)		;repeatsound ?
	bne.s	ass4			;eq = no!
	move.l	10(a6),$dff0d0		;set to repeatpoints
	move.w	14(a6),$dff0d4		;set to repeatlenghts
ass4:	move.l	#datach2,a6
	cmp.w	#1,14(a6)
	bne.s	ass5
	move.l	10(a6),$dff0c0
	move.w	14(a6),$dff0c4
ass5:	move.l	#datach1,a6
	cmp.w	#1,14(a6)
	bne.s	ass6
	move.l	10(a6),$dff0b0
	move.w	14(a6),$dff0b4
ass6:	move.l	#datach0,a6
	cmp.w	#1,14(a6)
	bne.s	ass7
	move.l	10(a6),$dff0a0	
	move.w	14(a6),$dff0a4
ass7:	add.l	#16,patternpos		;4*longw further
	cmp.l	#64*16,patternpos	;pattern end?
	bne.s	muzakend
	clr.l	patternpos
	addq.l	#1,trackpos		;increase pointer
	clr.l	d0
	move.w	numofpatt,d0		;number of all patts
	move.l	trackpos,d1		;current pos
	cmp.l	d0,d1			;last pattern done?
	bne.s	muzakend		;no!
	clr.l	trackpos		;set on top of seq
muzakend:
	movem.l	(a7)+,d0-d7/a0-a6
	rts

*************************************************
* sounddata behind the replayer 
*************************************************
samples:
	snd1:	blk.b	2,0
	snd2:	blk.b	2,0
	snd3:	blk.b	2,0
	snd4:	blk.b	2,0
	snd5:	blk.b	2,0
	snd6:	blk.b	2,0
	snd7:	blk.b	2,0
	snd8:	blk.b	2,0
	snd9:	blk.b	2,0
	snda:	blk.b	2,0
	sndb:	blk.b	2,0
	sndc:	blk.b	2,0
	sndd:	blk.b	2,0
	snde:	blk.b	2,0
	sndf:	blk.b	2,0
	samplesend:

*************************************************
* interrupt level 3 (frame flop)
*************************************************
	framirqsave:	dc.l	0
*************************************************
frameirq:
	movem.l	d0/d1/a0/a1/a5/a6,-(a7)	;save stack
	lea	$dff000,a0
	move.l	4,a6
	move.w	$1c(a0),d1
	btst	#$e,d1			;irq dissable?
	beq.s	irqend
	and.w	$1e(a0),d1
	btst	#6,d1
	beq.s	lev3vb
	movem.l	$9c(a6),a1/a5
	pea	-$24(a6)
	jmp	(a5)
lev3vb:	btst	#5,d1			;vertical blank
	beq.s	lev3cop
	bsr	muzakstart 		;own rout
	movem.l	$90(a6),a1/a5
	pea	-$24(a6)
	jmp	(a5)
lev3cop:btst	#4,d1			;copper
	beq.s	irqend
	movem.l	$84(a6),a1/a5
	pea	-$24(a6)
	jmp	(a5)
irqend:	movem.l	(a7)+,d0/d1/a0/a1/a5/a6
	rte
;end:
