


bitMaskArray
    byte #%10000000
    byte #%01000000
    byte #%00100000
    byte #%00010000
    byte #%00001000
    byte #%00000100
    byte #%00000010
    byte #%00000001


;--------------------------------------------------------------------------
; playPattern
;--------------------------------------------------------------------------
; Plays a pattern
;
; - ACC should contain the offset in the patternArray of the pattern to play
; - X should contain the oscillator to be used (0 or 1)
;
;--------------------------------------------------------------------------
playPattern

    ; save unaltered patternArray offset
    sta temp16L

    ; save patternArray offset
    asl
    asl
    asl
    sta temp

    ; custom code to allow 1 quarter note per measure (Thrust):
    ; use beat to determine extra offset within patternArray
    lda beat
    and #%00011000
    lsr
    lsr

    ; add in original offset
    adc temp

    ; save osc number
    stx temp

    tax

    ; This mod allows for high and low volume patterns.
    ; Patterns of offset greater than 128 read from a different
    ; array and play lower.
    lda temp16L
    bmi lowPattern

    ; Loud version
    ; Get address of selected pattern
    lda patternArrayH,x
    ldy patternArrayH+1,x

    ; Set 0 attenuation
    ldx #0
    beq endGetPattern

lowPattern
    ; Soft version
    ; Get address of selected pattern
    lda patternArrayL,x
    ldy patternArrayL+1,x

    ; Set -6 attenuation
    ldx #4

endGetPattern
    sta temp16L
    sty temp16H
    stx atten

    ; The variable, beat, contains the 32nd note
    ; that the beat is currently on.
    lda beat

    ; modification for 1 quarter per measure (Thrust)
    and #%00000111
    tay

    ; Get sound/note data
    lda (temp16L),y
    eor #255
    beq muteNote
    eor #255

;--------------------------------------------------------------------------
; Extract Pattern Data
;--------------------------------------------------------------------------
; Each byte of pattern data contains the frequency and
; sound type data.  This function separates and decodes them.
;
; The encoding is: the 3 high bits contain the encoded sound
; type and the lower 5 bits contain the freq data.
;
; - ACC must contain pattern byte
;
; = ACC will return the freq
; = X will return the sound type
;
; changes ACC,X
;--------------------------------------------------------------------------
    tax

    ; Extract freq data and push it
    and #%00011111
    pha

    txa
    lsr
    lsr
    lsr
    lsr
    lsr
    tax

;-----------------------
    lda atten
    clc
    adc soundTurnArray,x
    sta atten
;-----------------------

    lda soundTypeArray,x
;--------------------------------------------------------------------------

    ; Get the osc number again
    ldx temp
;	bne noPhase

;	sta AUDF0
;	nop
;	nop
;	nop
;	nop


noPhase


    sta AUDC0,x
    pla
    sta AUDF0,x


    ; restore beat & #%111
    tya
    tax

;--------------------------------------------------------------------------
; Accent Reader
;--------------------------------------------------------------------------
; Each set of pattern data is followed by 4 accept bytes.
; Each bit in order represents the accent (on or off)
; of its corresponding 32nd note.  This function
; returns the attenuation of a note in a pattern.
;
; - temp16 must contain an indirect pointer to the pattern data
; - X must contain the beat && %00000111
;
; = will return the volume in ACC
;
; changes X,Y,ACC
;--------------------------------------------------------------------------
    ; Accent offset is always 8 for Thrust mod
    ldy #8

    lda (temp16L),y
    and bitMaskArray,x
    beq noAccent

    ; It's an Accent, so don't attenuate
    lda #15

noAccent
    ; No accent, so use a lower volume
    ora #13
;--------------------------------------------------------------------------

    sbc atten                   ; carry flag???
muteNote
    ldy temp                    ; Get the osc number again
    sta AUDV0,y

	;--------------------------------------------------------------------------
	; Super High Hat (TM)
	;--------------------------------------------------------------------------
	; This plays the high hat sound on the first frame of each beat indicated
	; in hatPattern
	;--------------------------------------------------------------------------
	ldy temp
	beq noHat

	; Reat high hat pattern
	lda measure
	cmp #HATSTART
	bmi noHat

	lda beat
	and #%00000111
	tax
	lda beat
	lsr
	lsr
	lsr
	tay
	lda hatPattern,y
	and bitMaskArray,x
	beq noHat

	; Only play had on first frame
	lda tempoCount
    and #1              ;bit 0 == first frame
	beq noHat

	; Play hat
	lda #HATPITCH
	sta AUDF1
	lda #HATSOUND
	sta AUDC1
	lda #HATVOLUME
	sta AUDV1
noHat
	;--------------------------------------------------------------------------

	;--------------------------------------------------------------------------
	; Percussion cutter
	;--------------------------------------------------------------------------
	; This code cuts off the sound for better percussive sounds.  You
	; can set it to start working at a certain measure.
	;--------------------------------------------------------------------------
;	lda measure
;	cmp #111	; start measure
;	bmi noCut

;	lda tempoCount
;	and #%11111110
;	beq noCut

;	lda #0
;	sta AUDV0

noCut



    rts ; playPattern OTHER RTS IN FUNCTION



;--------------------------------------------------------------------------
; songPlayer
;--------------------------------------------------------------------------
; Plays up to two pre-programmed patterns simlutaneously.
;
; Call this once per screen-draw.
;--------------------------------------------------------------------------
songPlayer

;--------------------------------------------------------------------------
; Generates tempo based on TEMPODELAY
;--------------------------------------------------------------------------

    ;bit 0 in tempoCount == this is the first frame of this beat
    lda tempoCount      ;save a byte of ROM - ignore carry. at worst we're 0.4% off
    adc #TEMPODELTA     ;overflow == next beat
    and #$FE
    sta tempoCount
    bcc quitTempo

    inc tempoCount      ;set bit 0

    inc beat
    lda beat
    eor #32
    bne quitTempo
    sta beat

    inc measure

quitTempo
;--------------------------------------------------------------------------

    ldx #0
    ldy measure
    lda song1,y

    ; Check to see if the end of the song was reached
    cmp #255
    bne notEndOfSong

    ;END
    rts

notEndOfSong
    jsr playPattern

    ldy measure
    lda song2,y

    ldx #1
    jmp playPattern

    ; songPlayer
;--------------------------------------------------------------------------
