                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/
; ******************************************************************************

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  240

MUSICDATA  
                    fdb  0   ; Loop start point * 2
                    fdb  46  ; Song Length * 2
PATTERNDATA         fdb      PAT0
                    fdb      PAT0
                    fdb      PAT0
                    fdb      PAT0
                    fdb      PAT1
                    fdb      PAT2
                    fdb      PAT3
                    fdb      PAT4
                    fdb      PAT5
                    fdb      PAT6
                    fdb      PAT1
                    fdb      PAT2
                    fdb      PAT4
                    fdb      PAT2
                    fdb      PAT1
                    fdb      PAT2
                    fdb      PAT15
                    fdb      PAT16
                    fdb      PAT5
                    fdb      PAT7
                    fdb      PAT8
                    fdb      PAT9
                    fdb      PAT17

; *** 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  10  ; Pattern tempo
             fcb  180,91
             fcb  180,91
             fcb  91,45
             fcb  180,91
             fcb  180,91
             fcb  91,45
             fcb  180,91
             fcb  180,91
             fcb  91,45
             fcb  180,91
             fcb  180,91
             fcb  91,45
             fcb  180,91
             fcb  180,91
             fcb  91,45
             fcb  180,91
         fcb  $FE
PAT1  
         fcb  10  ; Pattern tempo
             fcb  215,36
             fcb  215,108
             fcb  108,34
             fcb  215,108
             fcb  215,36
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,1
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,45
             fcb  215,108
         fcb  $FE
PAT2  
         fcb  10  ; Pattern tempo
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
             fcb  215,108
             fcb  108,54
             fcb  215,108
         fcb  $FE
PAT3  
         fcb  10  ; Pattern tempo
             fcb  215,36
             fcb  215,108
             fcb  215,34
             fcb  108,108
             fcb  215,36
             fcb  215,54
             fcb  108,108
             fcb  215,108
             fcb  215,34
             fcb  108,108
             fcb  215,108
             fcb  215,54
             fcb  108,108
             fcb  215,108
             fcb  215,36
             fcb  108,108
         fcb  $FE
PAT4  
         fcb  10  ; Pattern tempo
             fcb  215,40
             fcb  215,36
             fcb  108,34
             fcb  215,36
             fcb  215,108
             fcb  215,54
             fcb  108,108
             fcb  215,108
             fcb  215,54
             fcb  108,108
             fcb  215,108
             fcb  215,54
             fcb  108,108
             fcb  215,108
             fcb  215,54
             fcb  108,108
         fcb  $FE
PAT5  
         fcb  10  ; Pattern tempo
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,91
             fcb  180,1
             fcb  91,91
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,91
             fcb  180,1
             fcb  91,91
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,1
         fcb  $FE
PAT6  
         fcb  10  ; Pattern tempo
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,91
             fcb  180,1
             fcb  91,91
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,91
             fcb  180,1
             fcb  91,91
             fcb  180,1
             fcb  180,91
             fcb  91,1
             fcb  180,91
         fcb  $FE
PAT7  
         fcb  10  ; Pattern tempo
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
         fcb  $FE
PAT8  
         fcb  10  ; Pattern tempo
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  1,45
             fcb  1,91
             fcb  1,91
             fcb  34,45
             fcb  38,91
         fcb  $FE
PAT9  
         fcb  10  ; Pattern tempo
             fcb  1,36
             fcb  1,108
             fcb  1,34
             fcb  1,108
             fcb  1,36
             fcb  1,54
             fcb  1,108
             fcb  1,108
             fcb  1,34
             fcb  1,108
             fcb  1,108
             fcb  1,54
             fcb  1,108
             fcb  1,108
             fcb  1,36
             fcb  1,108
         fcb  $FE
PAT15  
         fcb  10  ; Pattern tempo
             fcb  240,45
             fcb  240,40
             fcb  121,38
             fcb  240,40
             fcb  240,121
             fcb  240,61
             fcb  121,121
             fcb  240,121
             fcb  240,61
             fcb  121,121
             fcb  240,121
             fcb  240,61
             fcb  121,121
             fcb  240,121
             fcb  240,61
             fcb  121,121
         fcb  $FE
PAT16  
         fcb  10  ; Pattern tempo
             fcb  192,96
             fcb  192,96
             fcb  96,48
             fcb  192,96
             fcb  192,96
             fcb  96,48
             fcb  192,96
             fcb  192,96
             fcb  96,48
             fcb  192,96
             fcb  192,96
             fcb  96,48
             fcb  192,96
             fcb  192,96
             fcb  96,48
             fcb  192,96
         fcb  $FE
PAT17  
         fcb  10  ; Pattern tempo
             fcb  1,36
             fcb  1,108
             fcb  1,34
             fcb  1,108
             fcb  1,36
             fcb  1,54
             fcb  1,108
             fcb  1,108
             fcb  1,34
             fcb  1,108
             fcb  1,108
             fcb  1,54
             fcb  1,108
             fcb  1,108
             fcb  1,36
             fcb  1,108
         fcb  $FE
