                ORG	$3f00
; *****************************************************************************
; * The Music Studio Player Engine
; *
; * Based on code written by Sasa Pusica for the utility, The Music Studio.
; * Modified by Chris Cowley
; *
; * Produced by Beepola v1.06.01
; *
; * Z80 to 6809 conversion by John Kowalski (Sock Master)
; *
; * Original Z80 to 6809 conversion idea and debugging by Simon Jonassen
; *
; * 6809 code changes and optimization by Steve Evans (Zephyr)
; * http://archive.worldofdragon.org/
; * 
; * Sliding VU by Simon Jonassen
; *
; ******************************************************************************

start		jsr	>check_dos
		pshs	dp
		lda	#$3f			; Set DP = $3F
		tfr	a,dp
		setdp	$3f

		jsr	>initvu
		ldy	#$ff20	
		ldd	#PATTERNDATA 		; Get start address of pattern data
		addd	MUSICDATA		; Add loop start point to the pattern data start address
		tfr	d,x			; Transfer pattern data loop start address to the X register
		ldd	#PATTERNDATA 		; Get start address of pattern data
		addd	MUSICDATA+2		; Add song length to the pattern data loop start address
		std	<patloopend+1		; Set pattern data loop end address
		jsr	>audio_on		; Select DAC as sound source and enable audio
		

; ********************************************************************************************************
; * NEXT_PATTERN
; *
; * Select the next pattern in sequence (and handle looping if we've reached PATTERN_LOOP_END
; * Execution falls through to PLAYNOTE to play the first note from our next pattern
; ********************************************************************************************************
nextpat
		lda	[,x]			; X = Pattern data pointer 
		sta	<qtempo+1
		ldu	#1
playnote 
		ldd	,x
		ldd	d,u			; D,U = Note data pointer
		cmpa	#$fe			; $FE indicates end of pattern
		bne	continue

		leax	2,x
patloopend	cmpx	#0000			; Check for end of pattern loop
		blo	nextpat

		jmp	>audio_off		; Disable audio and return to basic

continue	sta	<ch1freq+1
		stb	<ch2freq+1
noteptr		leau	2,u			; Increment the note pointer by 2 (one note per chan)

qtempo		ldd	#0000			; A = Tempo | B = 0
		std	<tempc
		stb	<bord1+1
		stb	<bord2+1		; So now tempb = 0, tempc = Tempo | bord1 & bord2 = 0

outputnote

		ldb	<ch1freq+1		; Put note frequency for chan 1 into IXH
		stb	<ch1ix+1
		stb	<ch1count
		decb
		stb	<ltemp1
		beq	continue1

		ldb	#$40
continue1	stb	<xore1+1
		stb	<xore1b+1

		ldb	<ch2freq+1		; Put note frequency for chan 2 into IXL
		stb	<ch2ix+1
		stb	<ch2count
		decb
		stb	<ltemp2
		beq	continue2

		ldb	#$40
continue2	stb	<xore2+1
		stb	<xore2b+1

continue3
bord1		lda	#00
		dec	<ch1count		; Dec H, which also holds the frequency value
		bne	l8055
xore1		eora	#00
		sta	<bord1+1
ch1freq		ldb	#00
		stb	<ch1count

ch1ix		ldb	#00
		cmpb	#$20
		bcc	l8055			; if B > $20 then this is not a drum effect, skip the INC D
		inc	<ch1freq+1		; create the "fast falling pitch" percussion effect
l8055		dec	<ltemp1
		bne	bord2
xore1b		eora	#00
		sta	<bord1+1
		ldb	<ch1freq+1
		decb
		stb	<ltemp1

bord2		adda	#00
		sta	,y
		dec	<ch2count
		bne	l806d
		lda	<bord2+1
xore2		eora	#00
		sta	<bord2+1
ch2freq		ldb	#00
		stb	<ch2count
ch2ix		ldb	#00
		cmpb	#$20
		bcc	l806d			; if A > $20 then this is not a drum effect, skip the INC D
		inc	<ch2freq+1		; create the "fast falling pitch" percussion effect

l806d		dec	<ltemp2
		bne	l8073
		lda	<bord2+1
xore2b		eora	#00
		sta	<bord2+1
		ldb	<ch2freq+1
		decb
		stb	<ltemp2
l8073		dec	<tempb
		bne	continue3
		jsr	vu
		jsr	vu2
		dec	<tempc
		bne	continue3
		jmp	<playnote

tempc		fcb	0
tempb		fcb	0
ch1count	fdb	0
ch2count	fdb	0
ltemp1		fcb	0
ltemp2		fcb	0
target		fcb	0
target2		fcb	0
current		fcb	0
current2	fcb	0
DOUBLE_SPEED	fcb	0			; 0 = Normal CPU speed, 1 = Double CPU speed 

check_dos
		ldx	#$444b			; Check if DOS is present
		cmpx	$c000
		beq	nmi_vect
		orcc	#$50			; Disable IRQ/FIRQ interrupts
		rts
nmi_vect	ldx	[$010a]
		cmpx	#$9640			; Check for DragonDOS v1.0 to v4.2/SUPERDOS/DOSPLUS
		beq	dragon_dos	
		cmpx	#$326c			; Check for CumanaDOS v2.0
		beq	dragon_dos
		cmpx	#$b609			; Check for RS-DOS/ADOS/HDB-DOS/RGBDOS
		beq	rs_dos
unknown_dos	ldu	#tempc
		tfr	u,x
		inc	,x
		bra	timeout
dragon_dos	ldu	#$0605
		ldx	#$ff48
		bra	timeout
rs_dos		ldu	#$0985
		ldx	#$ff40

timeout		ldb	#4			; Wait for timeout (about 4.5 seconds max) 
tl1		ldy	#$f400
tl2		lda	,u	
		beq	disable_ints
		leay	-1,y
		bne	tl2
		decb
		bne	tl1
disable_ints	orcc	#$50			; Disable IRQ/FIRQ interrupts
		clr	,x			; Make sure drive motors are off and NMI disabled (DragonDOS)
		rts

initvu		clr	<target			; VU METER
		clr	<target2
		ldd	#$801f
		stb	<current
		stb	<current2
		ldx	#$05e0
		stx	>$0088
		bsr	cls
		rts

vu		pshs	d,x			; CHANNEL 1
		lda	#133
		ldx	#$4a0
		ldb	<current
		abx
		cmpb	<target
		blo	up
		bhi	down

		ldb	<ch1freq+1
		lsrb
		lsrb	
		lsrb
		stb	<target
		puls	d,x,pc

up		cmpb	#16 
		blo	green
		lda	#149

green		cmpb	#24
		blo	yella1
		lda	#181
yella1		sta	,x
		incb
		stb	<current
		puls	d,x,pc

down		lda	#$80
		sta	,x
		decb
		stb	<current
		puls	d,x,pc

vu2		pshs	d,x			; CHANNEL 2
		lda	#133
		ldx	#$540
		ldb	<current2
		abx
		cmpb	<target2
		blo	up2
		bhi	down2

		ldb	<ch2freq+1
		lsrb
		lsrb	
		lsrb
		stb	<target2
		puls	d,x,pc

up2		lda	#133
		cmpb	#16
		blo	green2
		lda	#149	
green2		cmpb	#24
		blo	yella
		lda	#181
yella		sta	,x
		incb
		stb	<current2
		puls	d,x,pc

down2		lda	#$80
		sta	,x
		decb
		stb	<current2
		puls	d,x,pc

cls		ldx	#$0400
nxt		sta	,x+
		cmpx	#$05ff
		bls	nxt
		rts

audio_on
		lda	$ff01			; Select DAC as sound source
		anda	#$f7
		sta	$ff01
		lda	$ff03
		anda	#$f7
		sta	$ff03

		lda	$ff23			; Enable sound
		ora	#$8
		sta	$ff23	

		lda	DOUBLE_SPEED		; Check double speed flag
		beq	music
		sta	$ffd7			; Enable CPU double speed
		sta	$ffd9
music		rts

audio_off
		lda	$ff23 			; Disable sound 
		anda	#$f7
		sta	$ff23	

		lda	DOUBLE_SPEED		; Check double speed flag
		beq	basic
		sta	$ffd8			; Disable CPU double speed
		sta	$ffd6
basic		andcc	#$af			; Enable IRQ/FIRQ interrupts
		puls	dp,pc			; Restore DP, and return to basic

; ** Change the following LOOP START POINT and SONG LENGTH to DOUBLE BYTE VALUES (fdb) for this 16-bit engine **

; *** DATA ***
BORDER_COL                EQU $0
TEMPO                     fcb 250

MUSICDATA 
                    fdb 0    ; Loop start point * 2
                    fdb 88   ; Song Length * 2
PATTERNDATA         fdb      PAT0
                    fdb      PAT1
                    fdb      PAT2
                    fdb      PAT3
                    fdb      PAT0
                    fdb      PAT1
                    fdb      PAT2
                    fdb      PAT8
                    fdb      PAT4
                    fdb      PAT5
                    fdb      PAT6
                    fdb      PAT7
                    fdb      PAT4
                    fdb      PAT5
                    fdb      PAT6
                    fdb      PAT9
                    fdb      PAT10
                    fdb      PAT11
                    fdb      PAT12
                    fdb      PAT13
                    fdb      PAT10
                    fdb      PAT11
                    fdb      PAT12
                    fdb      PAT14
                    fdb      PAT4
                    fdb      PAT5
                    fdb      PAT6
                    fdb      PAT7
                    fdb      PAT4
                    fdb      PAT5
                    fdb      PAT6
                    fdb      PAT9
                    fdb      PAT10
                    fdb      PAT11
                    fdb      PAT12
                    fdb      PAT13
                    fdb      PAT10
                    fdb      PAT11
                    fdb      PAT12
                    fdb      PAT14
                    fdb      PAT15
                    fdb      PAT15
                    fdb      PAT15
                    fdb      PAT16

; *** Pattern data consists of pairs of frequency values CH1,CH2 with a single $FE to
; *** Mark the end of the pattern, and $01 for a rest
PAT0 
         fcb 8  ; Pattern tempo
             fcb 161,0
             fcb 1,161
             fcb 1,81
             fcb 1,81
             fcb 1,0
             fcb 1,161
             fcb 1,81
             fcb 1,81
             fcb 1,0
             fcb 1,161
             fcb 1,0
             fcb 1,81
             fcb 1,0
             fcb 1,161
             fcb 1,81
             fcb 1,81
         fcb $FE
PAT1 
         fcb 8  ; Pattern tempo
             fcb 203,0
             fcb 1,203
             fcb 1,102
             fcb 1,102
             fcb 1,0
             fcb 1,203
             fcb 1,102
             fcb 1,102
             fcb 1,0
             fcb 1,203
             fcb 1,0
             fcb 1,102
             fcb 1,0
             fcb 1,203
             fcb 1,0
             fcb 1,102
         fcb $FE
PAT2 
         fcb 8  ; Pattern tempo
             fcb 180,0
             fcb 1,180
             fcb 1,91
             fcb 1,91
             fcb 1,0
             fcb 1,180
             fcb 1,91
             fcb 1,91
             fcb 1,0
             fcb 1,180
             fcb 1,0
             fcb 1,91
             fcb 1,0
             fcb 1,180
             fcb 1,91
             fcb 1,91
         fcb $FE
PAT3 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 1,240
             fcb 1,121
             fcb 1,121
             fcb 1,0
             fcb 1,240
             fcb 1,121
             fcb 1,121
             fcb 1,0
             fcb 1,240
             fcb 1,0
             fcb 1,121
             fcb 1,0
             fcb 1,240
             fcb 1,0
             fcb 1,121
         fcb $FE
PAT4 
         fcb 8  ; Pattern tempo
             fcb 161,0
             fcb 161,1
             fcb 81,81
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,72
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,0
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,1
             fcb 81,1
         fcb $FE
PAT5 
         fcb 8  ; Pattern tempo
             fcb 203,0
             fcb 203,1
             fcb 102,1
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,81
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,0
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,0
             fcb 102,1
         fcb $FE
PAT6 
         fcb 8  ; Pattern tempo
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,0
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
         fcb $FE
PAT7 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 240,1
             fcb 121,1
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,81
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,0
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,0
             fcb 121,1
         fcb $FE
PAT8 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 1,240
             fcb 1,121
             fcb 1,121
             fcb 1,0
             fcb 1,240
             fcb 1,121
             fcb 1,121
             fcb 121,0
             fcb 1,240
             fcb 1,0
             fcb 1,121
             fcb 1,0
             fcb 1,0
             fcb 1,0
             fcb 1,0
         fcb $FE
PAT9 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 240,1
             fcb 121,1
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,81
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,0
             fcb 121,1
             fcb 240,0
             fcb 240,0
             fcb 121,0
             fcb 121,0
         fcb $FE
PAT10 
         fcb 8  ; Pattern tempo
             fcb 161,0
             fcb 161,1
             fcb 81,1
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,1
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,0
             fcb 81,1
             fcb 161,0
             fcb 161,1
             fcb 81,1
             fcb 81,1
         fcb $FE
PAT11 
         fcb 8  ; Pattern tempo
             fcb 203,0
             fcb 203,1
             fcb 102,1
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,108
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,0
             fcb 102,1
             fcb 203,0
             fcb 203,1
             fcb 102,0
             fcb 102,1
         fcb $FE
PAT12 
         fcb 8  ; Pattern tempo
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,0
             fcb 91,1
             fcb 180,0
             fcb 180,1
             fcb 91,1
             fcb 91,1
         fcb $FE
PAT13 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 240,1
             fcb 121,1
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,108
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,0
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,0
             fcb 121,1
         fcb $FE
PAT14 
         fcb 8  ; Pattern tempo
             fcb 240,0
             fcb 240,1
             fcb 121,1
             fcb 121,1
             fcb 240,0
             fcb 240,1
             fcb 121,108
             fcb 121,1
             fcb 240,0
             fcb 240,0
             fcb 121,0
             fcb 121,0
             fcb 240,0
             fcb 240,0
             fcb 121,0
             fcb 121,0
         fcb $FE
PAT15 
         fcb 8  ; Pattern tempo
             fcb 161,0
             fcb 1,1
             fcb 161,161
             fcb 1,0
             fcb 161,0
             fcb 1,1
             fcb 161,0
             fcb 1,1
             fcb 161,0
             fcb 1,1
             fcb 161,161
             fcb 1,1
             fcb 81,0
             fcb 1,1
             fcb 81,81
             fcb 1,1
         fcb $FE
PAT16 
         fcb 8  ; Pattern tempo
             fcb 81,0
             fcb 1,1
             fcb 1,1
             fcb 1,0
             fcb 1,0
             fcb 1,1
             fcb 1,0
             fcb 1,1
             fcb 1,0
             fcb 1,1
             fcb 1,1
             fcb 1,1
             fcb 1,0
             fcb 1,0
             fcb 1,0
             fcb 1,0
	 fcb $FE
