#asm
; *****************************************************************************
; * Savage Music Player Engine
; *
; * Based on code written by Jason C Brooke for the Probe Software game,
; * Savage. Reverse engineerd in Ukraine by barmaley_m and translated to
; * English by Shiru.  Minor mods by Chris Cowley.
; *
; * Produced by Beepola v1.06.01
; ******************************************************************************
 
.musicstart
              RET
              /*
              PUSH  AF
              LD    HL,$FE00
              LD    DE,$FE00 + 1
              LD    BC,257             ; Length of vector table = 257 bytes
              LD    (HL),$FF           ; Point vector table at address $FFFF
              LDIR
              LD    HL,$FFFF
              LD    (HL),$18           ; Copy in a JR instruction for JR FFF4
              LD    HL,$FFF4
              LD    (HL),$C3           ; Copy in a JP instruction
              INC   HL
              LD    (HL),ISR_0
              LD    A,$FE00 / 256
              LD    I,A
              IM    2
              EI                       ; Enable IM2 routine at $F0F0
              POP   AF
              CALL  INIT_MUSIC
              CALL  PLAY_MUSIC
              IM    1
              LD    IY,$5C3A           ; Set up IY and
              LD    HL,$2758           ; HL with sensible values for
              EXX                      ; returning to BASIC
              EI
              RET

.intvec_adr   EQU   $FFF5

.init_music
              PUSH  BC
              PUSH  DE
              PUSH  HL
              PUSH  IX
              LD    HL,SONG_INITDATA_0
              LD    IX,CHAN_0_DATA
              LD    C,$11              ; Length of channel data
.le4bb
              LD    A,(HL)
              LD    (IX + CHAN_ENDPOS),A
              INC   HL
              LD    A,(HL)
              LD    (IX + CHAN_SONGLOOPPOS),A
              INC   HL
              LD    E,(HL)
              INC   HL
              LD    D,(HL)
              INC   HL
              LD    (IX + CHAN_NOTE_LEN_REMAIN),1
              LD    (IX + CHAN_TRANSPOSE),B
              LD    (IX + CHAN_SKEW_XORING),B
              LD    (IX + CHAN_ORN_BASE),B
              LD    (IX + CHAN_CURPOS),B
              LD    (IX + CHAN_PATT_TBL_ADR),E
              LD    (IX + CHAN_PATT_TBL_ADR + 1),D
              LD    A,(DE)
              LD    (IX + CHAN_DATA),A
              INC   DE                  ; relocatable
              LD    A,(DE)
              LD    (IX + 1),A
              BIT   7,(IX + CHAN_NOTE_LEN_TOTAL)
              ADD   IX,BC
              JR    Z,LE4BB

              LD    E,(HL)
              INC   HL
              LD    D,(HL)
              INC   HL
              LD    (LD_HL_ORNOFF + 1),DE
              LD    E,(HL)
              INC   HL
              LD    D,(HL)
              INC   HL
              LD    (LD_HL_ORNDAT + 1),DE

              POP   IX
              POP   HL
              POP   DE
              POP   BC
              LD    A,$FF
              LD    (CONT_FLAG + 1),A
              RET

; Reserve 17 bytes for our Channel 0 (tone) status structure
chan_0_data   DEFW  $0000	; Pattern pointer (CHAN_DATA)
              DEFW  $0000       ; Pattern Table Address (CHAN_PATT_TBL_ADR)
              DEFB  $00,$00,$00 ; CHAN_CURPOS, CHAN_ENDPOS, CHAN_SONGLOOPPOS
              DEFB  $00         ; CHAN_TRANSPOSE
              DEFB  $00,$00     ; CHAN_NOTE_LEN_REMAIN, CHAN_NOTE_LEN_TOTAL
              DEFB  $00         ; CHAN_GENFX
              DEFB  $00         ; CHAN_SKEW_PARAM
              DEFB  $10         ; Channel on
              DEFB  $00         ; CHAN_ORN_BASE
              DEFB  $00         ; CHAN_ORN_COUNT
              DEFB  $00         ; Note
              DEFB  $00         ; CHAN_SKEW_XORING

; Reserve 17 bytes for our Channel 1 (tone) status structure
.chan_1_data  DEFW  $0000	; Pattern pointer (CHAN_DATA)
              DEFW  $0000       ; Pattern Table Address (CHAN_PATT_TBL_ADR)
              DEFB  $00,$00,$00 ; CHAN_CURPOS, CHAN_ENDPOS, CHAN_SONGLOOPPOS
              DEFB  $00         ; CHAN_TRANSPOSE
              DEFB  $00,$00     ; CHAN_NOTE_LEN_REMAIN, CHAN_NOTE_LEN_TOTAL
              DEFB  $00         ; CHAN_GENFX
              DEFB  $00         ; CHAN_SKEW_PARAM
              DEFB  $10         ; Channel on
              DEFB  $00         ; CHAN_ORN_BASE
              DEFB  $00         ; CHAN_ORN_COUNT
              DEFB  $00         ; Note
              DEFB  $00         ; CHAN_SKEW_XORING

; Reserve bytes for percussion channel status
.patdrum_ptr      DEFW  $0000       ; Percussion pattern pointer
.listdrum_ad      DEFW  $0000       ; Percussion pattern table address
.curpos_drum      DEFW  $0000
.drum_songlooppos DEFB  $00
                  DEFB  $00
.patdrum_cnt_qts  DEFB  $00
              DEFB  $FF
              DEFB  $00
*/
//.chan_data               .equ  0
/*
.chan_patt_tbl_adr       .EQU  2
.chan_curpos             .EQU  4
.chan_endpos             .EQU  5
.chan_songlooppos        .EQU  6
.chan_transpose          .EQU  7
.chan_note_len_remain    .EQU  8
.chan_note_len_total     .EQU  9
.CHAN_GENFX              .EQU  10
.CHAN_SKEW_PARAM         .EQU  11
.CHAN_CHANNEL_ON         .EQU  12
.CHAN_ORN_BASE           .EQU  13
.CHAN_ORN_COUNT          .EQU  14
.CHAN_NOTE               .EQU  15
.CHAN_SKEW_XORING        .EQU  16
*/
.FREQ_TABLE
              DEFW  $D8D8,$CC00,$00C0,$B6B5,$ACAB,$A2A1,$9998,$9090,$8888,$8180,$7979,$7372
              DEFW  $6C6C,$6666,$6060,$5B5A,$5655,$5151,$4D4C,$4848,$4444,$4040,$3D3C,$3939
              DEFW  $3636,$3333,$3030,$2E2D,$2B2B,$2928,$2626,$2424,$2222,$2020,$1F1E,$1D1C
              DEFW  $1B1B,$1A19,$1818,$1716,$1615,$1414,$1313,$1212,$1111,$1010,$0F0F,$0F0E
              DEFW  $0E0D,$0D0C,$0C0C,$0C0B,$0B0A,$0A0A,$0A09,$0x909,$0x908,$0x808,$0x807,$0x707
/*
.PLAY_MUSIC
              DI
              EX    AF,AF ; beware!
              PUSH  AF
.CONT_FLAG
              LD    A,$FF
              OR    A
              JP    Z,END_PLAY
              PUSH  IX
              EXX
              PUSH  BC
              PUSH  DE
              PUSH  HL
              LD    A,I
              LD    H,A
              LD    A,(HL)
              LD    H,A
              LD    L,A
              INC   A
              JR    NZ,LE25A
              LD    L,$F4
.LE25A
              LD    A,(HL)
              LD    (HL),$C3
              INC   HL
              LD    (LE2AF+1),HL
              LD    (LE400+1),HL
              LD    E,(HL)
              INC   HL
              LD    D,(HL)
              PUSH  HL
              PUSH  AF
              PUSH  DE
              LD    (SAVE_SP+1),SP
              ; Set initial pattern tempo from CH0
              LD    HL,(CHAN_0_DATA)
              LD    A,(HL)                ; Pattern tempo
              INC   HL
              LD    (QNT_VAL + 2),A
              LD    (CHAN_0_DATA),HL

              ; Skip tempo byte in CH2
              LD    HL,(CHAN_1_DATA)
              INC   HL
              LD    (CHAN_1_DATA),HL

              JR    NEXTQUANT

.ISR_2
              DEC   IXL
              JR    Z,NEXTQUANT_CHK
              LD    SP,(SAVE_SP+1)
              PUSH  IX
              CALL  SETUP_GEN
              POP   IX
              JR    ISR2_END

.NEXTQUANT_CHK
              CALL  CHECK_KEY
.NEXTQUANT
              CALL  PATSTEP_DRUMS
              LD    HL,CHAN_0_DATA + CHAN_NOTE_LEN_REMAIN
              DEC   (HL)
.LE28B        LD    IX,CHAN_0_DATA
              CALL  Z,PATTERN_STEP
              LD    HL,CHAN_1_DATA + CHAN_NOTE_LEN_REMAIN
              DEC   (HL)
.SAVE_SP      LD    SP,$0000
              LD    IX,CHAN_1_DATA
              CALL  Z,PATTERN_STEP
              LD    HL,CHAN_0_DATA + CHAN_ORN_BASE
.LE2A3        LD    A,(CHAN_1_DATA + CHAN_ORN_BASE)
              OR    (HL)
              LD    HL,ISR_1
              JR    Z,LE2AF
              LD    HL,ISR_2
.LE2AF        LD    (INTVEC_ADR),HL
              LD    A,(CHAN_0_DATA + CHAN_CHANNEL_ON)
              LD    (CHAN0_XOUT + 1),A
              LD    A,(CHAN_1_DATA + CHAN_CHANNEL_ON)
              LD    (CHAN1_XOUT + 1),A
              CALL  SETUP_GEN
.QNT_VAL      LD    IXL,4
.ISR2_END     EI

.GENLOOP
              EXX
              EX    AF,AF ; beware!
              DJNZ  LE2F4
              EX    DE,HL
              ADD   HL,BC
              LD    B,H
.CHAN0_XOUT   XOR   $10
.LE2CE        JP    LE2FC

.ISR_0        EI
              RET           ;

.ISR_1
              DEC   IXL
              JR    Z,ISR1_PROC_QNT
              EI
              RET
.ISR1_PROC_QNT
              PUSH  HL
              PUSH  AF
              CALL  CHECK_KEY
              CALL  PATSTEP_DRUMS
              LD    HL,CHAN_0_DATA + CHAN_NOTE_LEN_REMAIN
              DEC   (HL)
              JR    Z,LE28B
              LD    HL,CHAN_1_DATA + CHAN_NOTE_LEN_REMAIN
              DEC   (HL)
              JR    Z,SAVE_SP
              LD    A,(QNT_VAL + 2)
              LD    IXL,A
              POP   AF
              POP   HL
              EI
              RET

.LE2F4        RLCA
              RRCA
              JR    NC,LE2CE
              ADD   A,$80
              LD    H,L
              LD    L,B
.LE2FC        OUT   ($FE),A
              EXX
              EX    AF,AF ; beware!
              DJNZ  LE30C
              EX    DE,HL
              ADD   HL,BC
              LD    B,H
.CHAN1_XOUT   XOR   $10
.LE307        OUT   ($FE),A
.JP_GENLOOP   JP    GENLOOP

.LE30C        RLCA
              RRCA
              JR    NC,LE307
              DEC   HL
              JP    JP_GENLOOP

.CHECK_KEY
              SUB   A
              IN    A,($FE)
              CPL
              AND   $1F
              JR    NZ,KEY_PRESSED
              IN    A,($1F)             ; Read kempston
              AND   0
              RET   Z
              JR    KEY_PRESSED

.TBL_FUNC_OFFSETS
              DEFB  $9E                 ; Func $80 - Rest
              DEFB  $5E                 ; Func $81 - Glissando
              DEFB  $20                 ; Func $82 - End of pattern
              DEFB  $05                 ; Func $83 - End of song
              DEFB  $54                 ; Func $84 - Set transpose
              DEFB  $45                 ; Func $85 - Set Skew
              DEFB  $3E                 ; Func $86 - GenFX
              DEFB  $4A                 ; Func $87 - Set Skew XOR

.FUNC_83_SONG_END
              SUB   A
              LD    (CONT_FLAG + 1),A
.KEY_PRESSED
              LD    SP,(SAVE_SP + 1)
              EX    AF,AF ; beware!
              POP   DE
              POP   AF
              POP   HL
              LD    (HL),D
              DEC   HL
              LD    (HL),E
              DEC   HL
              LD    (HL),A
              POP   HL
              POP   DE
              POP   BC
              EXX
              POP   IX
.END_PLAY     POP   AF
              EX    AF,AF ; beware!
              RET

.FUNC_82_PATTERN_END
              LD    A,(IX + CHAN_CURPOS)  ; Get current position within song
              ADD   A,2
              CP    (IX + CHAN_ENDPOS)    ; Are we at the end of the song
              JR    NZ,LE352
              LD    A,(IX + CHAN_SONGLOOPPOS) ; Yes - Jump back to the loop start
.LE352        LD    (IX + CHAN_CURPOS),A
              LD    L,(IX + CHAN_PATT_TBL_ADR)
              LD    H,(IX + CHAN_PATT_TBL_ADR + 1)
              LD    C,A
              ADD   HL,BC
              LD    E,(HL)
              INC   HL                    ; relocatable
              LD    D,(HL)
              ; DE = address of next pattern
              LD    A,(DE)
              LD    (QNT_VAL + 2),A
              INC   DE
              JR    PATSTEP_LOOP

.FUNC_86_GENFX
              LD    (IX + CHAN_CHANNEL_ON),$90
              JR    PATSTEP_LOOP

.FUNC_85_SKEW
              LD    A,(DE)
              INC   DE
              LD    (IX + CHAN_SKEW_PARAM),A
              JR    PATSTEP_LOOP

.FUNC_87_SKEW_XOR
              LD    A,(DE)
              INC   DE
              LD    (IX + CHAN_SKEW_XORING),A
              JR    PATSTEP_LOOP

.FUNC_84_TRANSPOSE
              LD    A,(DE)
              INC   DE
              LD    (IX + CHAN_TRANSPOSE),A
              JR    PATSTEP_LOOP

.FUNC_81_GLIS
              LD    A,(DE)
              INC   DE
              LD    (IX + CHAN_GENFX),A
              JR    PATSTEP_LOOP

; *****************************************************************************
; * PATTERN_STEP
; *
; * Read the next value (a note, an effect, a note_len cmd, or an arpeggio)
; * from the pattern
; *****************************************************************************
.PATTERN_STEP
              LD    B,0
              LD    (IX + CHAN_GENFX),B
              LD    (IX + CHAN_CHANNEL_ON),$10
              LD    E,(IX + CHAN_DATA)
              LD    D,(IX + CHAN_DATA + 1)
.PATSTEP_LOOP
              LD    A,(DE)
              INC   DE
              CP    $C0
              JR    C,PLAY_NOTE    ; Is less than $C0 (note or effect)
              ADD   A,$20
              JR    C,SET_NOTELEN  ; Is E0 to FF (set note length)
              ADD   A,$20          ; Else is an arpeggio (C0 - DF)
              LD    C,A
.LD_HL_ORNOFF LD    HL,ORN_OFFSETS
              ADD   HL,BC
              LD    A,(HL)
              LD    (IX + CHAN_ORN_BASE),A
              JR    PATSTEP_LOOP

; *****************************************************************************
; * SET_NOTELEN
; *
; * Set the length of all following notes in the channel
; *****************************************************************************
.SET_NOTELEN  INC   A
              LD    (IX + CHAN_NOTE_LEN_TOTAL),A
              JR    PATSTEP_LOOP

.PLAY_NOTE
              OR    A
              JP    P,SIMPLE_NOTE                ; Value $00 - $7F are notes
              LD    C,A                          ; $80 - $BF are effects
              LD    HL,TBL_FUNC_OFFSETS - $80
              ADD   HL,BC
              LD    C,(HL)
              ADD   HL,BC
              JP    (HL)                         ; execute effect function

.FUNC_80_REST                                    ; On entry B=0
              LD    (IX + CHAN_CHANNEL_ON),B     ; Silence this channel

.SIMPLE_NOTE  LD    (IX + CHAN_NOTE),A
              LD    (IX + CHAN_ORN_COUNT),B      ; B = 0
              LD    A,(IX + CHAN_NOTE_LEN_TOTAL)
              LD    (IX + CHAN_NOTE_LEN_REMAIN),A
              LD    (IX + CHAN_DATA + 1),D
              LD    (IX + CHAN_DATA),E
              RET

.SETUP_GEN
              LD    IX,CHAN_0_DATA
              CALL  SETUP_GEN_CHAN
              EXX
              EX    AF,AF ; beware!
              LD    IX,CHAN_1_DATA
.SETUP_GEN_CHAN
              LD     A,(IX + CHAN_SKEW_PARAM)
              XOR    (IX + CHAN_SKEW_XORING)
              LD     (IX + CHAN_SKEW_PARAM),A    ; Store the xored value
              SUB    A
              LD     D,A
              LD     E,(IX + CHAN_ORN_BASE)
.LD_HL_ORNDAT LD     HL,ORNAMENTS_DATA
              ADD    HL,DE
              LD     E,(IX + CHAN_ORN_COUNT)
              ADD    HL,DE
              LD     A,(HL)
              OR     A
              JP     P, LE40A                    ; 00-7F = note offset
              INC    A
              JR     NZ,LE405                    ; 80-FE = note offset + reset
              LD     HL,ISR_1                    ; FF - end ornament, no need for ISR2
.LE400        LD     (INTVEC_ADR),HL
              JR     LE40E
.LE405        DEC    A
              AND    $7F
              LD     E,$FF                       ; Restart ornament
.LE40A        INC    E
              LD     (IX + CHAN_ORN_COUNT),E     ; Incremement the ornament counter
.LE40E        LD     H,D                         ; d = 0
              ADD    A,(IX + CHAN_NOTE)
              ADD    A,(IX + CHAN_TRANSPOSE)
              ADD    A,A
              LD     HL,FREQ_TABLE
              LD     E,A
              ADD    HL,DE
              LD     E,(HL)                      ; NoteFrq1 into E
              INC    HL
              LD     C,(HL)                      ; NoteFrq2 into C
              LD     A,(IX + CHAN_SKEW_PARAM)
              OR     A
              LD     L,D                         ; d=0
              JR     Z,NO_SKEW
              ADD    A,A
              LD     H,A
              JR     NC,LE42A
              ADD    HL,DE
.LE42A
              ADD    HL,HL
              JR     NC,LE42E
              ADD    HL,DE
.LE42E
              ADD    HL,HL
              JR     NC,LE432
              ADD    HL,DE
.LE432
              ADD    HL,HL
              JR     NC,LE436
              ADD    HL,DE
.LE436
              ADD    HL,HL
              JR     NC,LE43A
              ADD    HL,DE
.LE43A
              ADD    HL,HL
              JR     NC,LE43E
              ADD    HL,DE
.LE43E
              ADD    HL,HL
              JR     NC,LE442
              ADD    HL,DE
LE442
              ADD    HL,HL
              JR     NC,LE446
              ADD    HL,DE
LE446
              LD     L,H
.NO_SKEW
              LD     A,C         ; C = initial phase1 period
              ADD    A,L         ; L = skew value
              LD     H,A         ; store skewed phase1 in H
              LD     A,E         ; E = initial phase2 period
              SUB    L
              LD     L,D         ; initialise fractional period to 0
              LD     E,D         ; initialise fractional period to 0
              LD     D,A         ; skewed phase2 period
              LD     C,(IX + CHAN_GENFX)
.LE452
              :LD     A,BORDER_CLR
              xor a
              LD     B,H         ; init counter with phase1
              RET

; ************************************************************************
; * PATSTEP_DRUMS
; *
; * Percussion
; ************************************************************************
.PATSTEP_DRUMS
              LD    HL,PATDRUM_CNT_QTS
              DEC   (HL)
              RET   NZ
              LD    HL,(PATDRUM_PTR)
              LD    A,(HL)
              INC   HL
              OR    A
              JR    NZ,LE483     ; Jump if not end of pattern
              PUSH  BC
              PUSH  DE
              LD    B,A          ; A = 0 at this point
              LD    HL,(CURPOS_DRUM)
              LD    A,L
              ADD   A,2
              CP    H
              JR    NZ,LE472      ; jump if not end of song
              LD    A,(DRUM_SONGLOOPPOS)
.LE472
              LD    (CURPOS_DRUM),A
              LD    C,A
              LD    HL,(LISTDRUM_AD)
              ADD   HL,BC        ; here B=0
              LD    E,(HL)
              INC   HL            ; relocatable
              LD    D,(HL)
              EX    DE,HL
              LD    A,(HL)
              INC   HL
              OR    A
              POP   DE
              POP   BC
.LE483
              LD    (PATDRUM_PTR),HL
              JP    M,PLAYNOISE
              LD    (PATDRUM_CNT_QTS),A
              RET
*/
.PLAYNOISE    LD    HL,PATDRUM_CNT_QTS
              LD    B,(HL)       ; here (HL) = 0
              INC   (HL)
              PUSH  BC
              PUSH  DE
              LD    C,A
              LD    HL,NOISE_OFFSETS - $80
              ADD   HL,BC
              LD    C,(HL)
              ADD   HL,BC
              LD    A,(LE452 + 1)
              JP    (HL)

.NOISE_OFFSETS
              DEFB  $0F,$13,$17,$07,$1
.NOISE_01     LD    BC,$E01F
              JR    LEA24
.NOISE_07     LD    BC,$C0A1
              JR    LEA24
.NOISE_OF     LD    BC,$200F
              JR    LEA24
.NOISE_13     LD    BC,$CF3F
              JR    LEA24
.NOISE_17     LD    BC,$283F
.LEA24        LD    HL,$014A
              JR    LEA30
.LEA29        LD    E,8
.LEA2B        DEC   H
              JR    NZ,LEA3E
              XOR   $10
.LEA30        OUT   ($FE),A
              LD    E,A
              LD    A,R
              XOR   L
              RLCA
              LD    L,A
              AND   C
              INC   A
              LD    H,A
              LD    A,E
              JR    LEA41
.LEA3E        DEC   E
              JR    NZ,LEA2B
.LEA41        DJNZ  LEA29
              POP   DE
              POP   BC
              RET

; ************************************************************************
; * Song data...
; ************************************************************************

.song_initdata_0
              ; *** Channel 1 ***
              DEFB  64  ; song end
              DEFB  0  ; loop
              DEFW  C1_PATTERNS
              ; *** Channel 2 ***
              DEFB  64  ; song end
              DEFB  0  ; loop
              DEFW  C2_PATTERNS
              ; *** Percussion ***
              DEFB  64  ; song end
              DEFB  0  ; loop
              DEFW  PERC_PATTERNS
              DEFW  ORN_OFFSETS
              DEFW  ORNAMENTS_DATA

.orn_offsets  DEFB  $00

.ornaments_data
              DEFB  $80       ; Ornament 0 (no arpeggio)

.c1_patterns  DEFW      PAT1_0
              DEFW      PAT1_1
              DEFW      PAT1_2
              DEFW      PAT1_3
              DEFW      PAT1_4
              DEFW      PAT1_5
              DEFW      PAT1_5
              DEFW      PAT1_6
              DEFW      PAT1_0
              DEFW      PAT1_1
              DEFW      PAT1_7
              DEFW      PAT1_3
              DEFW      PAT1_4
              DEFW      PAT1_5
              DEFW      PAT1_5
              DEFW      PAT1_6
              DEFW      PAT1_0
              DEFW      PAT1_1
              DEFW      PAT1_2
              DEFW      PAT1_3
              DEFW      PAT1_4
              DEFW      PAT1_5
              DEFW      PAT1_5
              DEFW      PAT1_6
              DEFW      PAT1_0
              DEFW      PAT1_1
              DEFW      PAT1_7
              DEFW      PAT1_3
              DEFW      PAT1_4
              DEFW      PAT1_5
              DEFW      PAT1_5
              DEFW      PAT1_8

.pat1_0
        DEFB 11    ; Pattern Tempo
        DEFB $E1,$28
        DEFB $E0,$28
        DEFB $E1,$28
        DEFB $E0,$26
        DEFB $E1,$26
        DEFB $E7,$24
        DEFB $E1,$24
        DEFB $E0,$23
        DEFB $E1,$24
        DEFB $E0,$28
        DEFB $E6,$28
        DEFB $E0,$1F
        DEFB $E1,$1F
        DEFB $82   ; End of Pattern
.pat1_1
        DEFB 11    ; Pattern Tempo
        DEFB $E1,$28
        DEFB $E0,$28
        DEFB $E1,$28
        DEFB $E0,$26
        DEFB $E1,$26
        DEFB $E5,$24
        DEFB $E1,$1F
        DEFB $24
        DEFB $E0,$23
        DEFB $E1,$24
        DEFB $E0,$28
        DEFB $E6,$28
        DEFB $E0,$1F
        DEFB $E1,$1F
        DEFB $82   ; End of Pattern
.pat1_2
        DEFB 11    ; Pattern Tempo
        DEFB $E1,$2B
        DEFB $E0,$28
        DEFB $E1,$2B
        DEFB $E0,$28
        DEFB $E1,$2B
        DEFB $E4,$28
        DEFB $E0,$1F
        DEFB $E1,$1F
        DEFB $2B
        DEFB $E0,$2B
        DEFB $E1,$2D
        DEFB $E0,$28
        DEFB $E6,$28
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $82   ; End of Pattern
.pat1_3
        DEFB 11    ; Pattern Tempo
        DEFB $E2,$26
        DEFB $E1,$28
        DEFB $E7,$26
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $E2,$26
        DEFB $E1,$28
        DEFB $E7,$24
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $82   ; End of Pattern
.pat1_4
        DEFB 11    ; Pattern Tempo
        DEFB $E2,$26
        DEFB $E1,$28
        DEFB $E7,$26
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $E2,$26
        DEFB $E1,$28
        DEFB $E5,$2B
        DEFB $E1,$30
        DEFB $E0,$2F
        DEFB $E1,$2B
        DEFB $82   ; End of Pattern
.pat1_5
        DEFB 11    ; Pattern Tempo
        DEFB $E2,$28
        DEFB $E7,$26
        DEFB $E1,$30
        DEFB $E0,$2F
        DEFB $E1,$2B
        DEFB $E2,$28
        DEFB $E1,$2D
        DEFB $2D
        DEFB $E3,$2B
        DEFB $E1,$30
        DEFB $E0,$2F
        DEFB $E1,$2B
        DEFB $82   ; End of Pattern
.pat1_6
        DEFB 11    ; Pattern Tempo
        DEFB $E2,$28
        DEFB $E1,$26
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $E3,$28
        DEFB $26
        DEFB $EF,$24
        DEFB $82   ; End of Pattern
.pat1_7
        DEFB 11    ; Pattern Tempo
        DEFB $E1,$2B
        DEFB $E0,$28
        DEFB $E1,$2B
        DEFB $E0,$28
        DEFB $E1,$2B
        DEFB $E4,$28
        DEFB $E0,$1F
        DEFB $E1,$1F
        DEFB $E0,$2B
        DEFB $80
        DEFB $2B
        DEFB $2D
        DEFB $80
        DEFB $28
        DEFB $28
        DEFB $E5,$80
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $82   ; End of Pattern
.pat1_8
        DEFB 11    ; Pattern Tempo
        DEFB $E2,$28
        DEFB $E1,$26
        DEFB $E0,$26
        DEFB $E1,$24
        DEFB $E0,$28
        DEFB $E2,$80
        DEFB $E0,$26
        DEFB $E2,$80
        DEFB $E0,$24
        DEFB $EE,$80
        DEFB $82   ; End of Pattern


.C2_PATTERNS  DEFW      PAT2_0
              DEFW      PAT2_0
              DEFW      PAT2_2
              DEFW      PAT2_3
              DEFW      PAT2_4
              DEFW      PAT2_5
              DEFW      PAT2_5
              DEFW      PAT2_6
              DEFW      PAT2_0
              DEFW      PAT2_0
              DEFW      PAT2_7
              DEFW      PAT2_3
              DEFW      PAT2_4
              DEFW      PAT2_5
              DEFW      PAT2_5
              DEFW      PAT2_6
              DEFW      PAT2_0
              DEFW      PAT2_0
              DEFW      PAT2_2
              DEFW      PAT2_3
              DEFW      PAT2_4
              DEFW      PAT2_5
              DEFW      PAT2_5
              DEFW      PAT2_6
              DEFW      PAT2_0
              DEFW      PAT2_0
              DEFW      PAT2_7
              DEFW      PAT2_3
              DEFW      PAT2_4
              DEFW      PAT2_5
              DEFW      PAT2_5
              DEFW      PAT2_8

.PAT2_0
        DEFB 11    ; Pattern Tempo
        DEFB $EF,$11
        DEFB $0C
        DEFB $82   ; End of Pattern
.PAT2_2
        DEFB 11    ; Pattern Tempo
        DEFB $EF,$11
        DEFB $ED,$0C
        DEFB $E0,$10
        DEFB $13
        DEFB $82   ; End of Pattern
.PAT2_3
        DEFB 11    ; Pattern Tempo
        DEFB $E0,$17
        DEFB $07
        DEFB $07
        DEFB $18
        DEFB $07
        DEFB $17
        DEFB $E7,$07
        DEFB $E1,$9
        DEFB $E0,$17
        DEFB $05
        DEFB $05
        DEFB $18
        DEFB $05
        DEFB $15
        DEFB $E9,$05
        DEFB $82   ; End of Pattern
.PAT2_4
        DEFB 11    ; Pattern Tempo
        DEFB $E0,$17
        DEFB $07
        DEFB $07
        DEFB $18
        DEFB $07
        DEFB $17
        DEFB $E7,$07
        DEFB $E1,$9
        DEFB $E0,$17
        DEFB $05
        DEFB $05
        DEFB $18
        DEFB $05
        DEFB $1C
        DEFB $E9,$05
        DEFB $82   ; End of Pattern
.PAT2_5
        DEFB 11    ; Pattern Tempo
        DEFB $E7,$05
        DEFB $07
        DEFB $9
        DEFB $0C
        DEFB $82   ; End of Pattern
.PAT2_6
        DEFB 11    ; Pattern Tempo
        DEFB $E7,$05
        DEFB $E3,$9
        DEFB $07
        DEFB $EF,$05
        DEFB $82   ; End of Pattern
.PAT2_7
        DEFB 11    ; Pattern Tempo
        DEFB $EF,$11
        DEFB $E0,$0C
        DEFB $1F
        DEFB $1C
        DEFB $1F
        DEFB $0C
        DEFB $E2,$1C
        DEFB $E5,$80
        DEFB $E0,$10
        DEFB $13
        DEFB $82   ; End of Pattern
.PAT2_8
        DEFB 11    ; Pattern Tempo
        DEFB $E7,$05
        DEFB $E0,$9
        DEFB $E2,$80
        DEFB $E0,$07
        DEFB $E2,$80
        DEFB $E0,$05
        DEFB $EE,$80
        DEFB $82   ; End of Pattern
.PERC_PATTERNS
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM4
              DEFW      DRM5
              DEFW      DRM5
              DEFW      DRM6
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM7
              DEFW      DRM0
              DEFW      DRM4
              DEFW      DRM5
              DEFW      DRM5
              DEFW      DRM6
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM4
              DEFW      DRM5
              DEFW      DRM5
              DEFW      DRM9
              DEFW      DRM0
              DEFW      DRM0
              DEFW      DRM7
              DEFW      DRM0
              DEFW      DRM4
              DEFW      DRM5
              DEFW      DRM5
              DEFW      DRM8

.DRM0
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $00   ; End of pattern
.DRM4
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $01
        DEFB $00   ; End of pattern
.DRM5
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $00   ; End of pattern
.DRM6
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $00   ; End of pattern
.DRM7
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $02
        DEFB $80
        DEFB $83
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $83
        DEFB $02
        DEFB $81
        DEFB $81
        DEFB $03
        DEFB $00   ; End of pattern
.DRM8
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $01
        DEFB $82
        DEFB $81
        DEFB $80
        DEFB $01
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $02
        DEFB $81
        DEFB $81
        DEFB $03
        DEFB $80
        DEFB $02
        DEFB $81
        DEFB $81
        DEFB $03
        DEFB $00   ; End of pattern
.DRM9
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $80
        DEFB $81
        DEFB $80
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $81
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $80
        DEFB $02
        DEFB $80
        DEFB $80
        DEFB $03
        DEFB $00   ; End of pattern
#endasm

