;ЩЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЛ
;КSadoTracker V1.1 for Musicroutine 8                                          К
;К                                                                             К
;Кby Cadaver                                                                   К
;К                                                                             К
;КChanges:                                                                     К
;КV1.0 - Original release                                                      К
;КV1.1 - Corrected bug in filter-routine (odd timelengths didn't work)         К
;К     - Optimized frequencytable (octave 7 removed)                           К
;К     - Added "Commando" to the example tunes                                 К
;ШЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭМ

        ;Some memory addresses
CHAN1           = $4000
CHAN2           = $4800
CHAN3           = $5000
PATTERNS        = $5800
PLAYERORIG      = $c000
PLAYER          = $c800

        ;"Virtual" memory addresses for the player to be relocated
PLAYERVIRT      = $1000
SONGTBLVIRT     = $2000
PATTTBLLOVIRT   = $3000
PATTTBLHIVIRT   = $4000
SNDVIRT         = $5000
ARPTBLVIRT      = $6000
WAVETBLVIRT     = $7000
ARPCHTBLVIRT    = $8000

        ;"Virtual" sound-table offsets for the player to be relocated
SNDAD           = $0
SNDSR           = $10
SNDPULSE        = $20
SNDPULSESPD     = $30
SNDPULSELIMIT   = $40
SNDVIBDELAY     = $50
SNDVIBDEPTH     = $60
SNDARPPOS       = $70
SNDWAVEPOS      = $80
SNDFILTCTRL     = $90
SNDFILTCUTOFF   = $a0
SNDFILTSPD      = $b0
SNDFILTTIME1    = $c0
SNDFILTTIME2    = $d0

        ;Esc-byte for packed songdata
ESCBYTE         = $fc

        ;Zeropage variables
textlo          = $02
texthi          = $03
destlo          = $04
desthi          = $05
storea          = $06
storex          = $07
storey          = $08
trklo           = $09
trkhi           = $0a
temp1           = $fb
temp2           = $fc
temp3           = $fd
temp4           = $fe
temp5           = $ff
status          = $90
fa              = $ba

        ;Kernal routines
scnkey          = $ff9f
getin           = $ffe4
setnam          = $ffbd
setlfs          = $ffba
load            = $ffd5
save            = $ffd8
chrin           = $ffcf
open            = $ffc0
close           = $ffc3
chkin           = $ffc6
chkout          = $ffc9
ciout           = $ffa8
acptr           = $ffa5
clrchn          = $ffcc
chrout          = $ffd2
plot            = $fff0

        ;Some keycodes
KEY_F1          = $85
KEY_F3          = $86
KEY_F5          = $87
KEY_F7          = $88
KEY_UP          = $91
KEY_DOWN        = $11
KEY_LEFT        = $9d
KEY_RIGHT       = $1d
KEY_INS         = $94
KEY_DEL         = $14
KEY_BREAK       = $03

        ;Constants of the music routine
        ;Pattern data
FIRSTNOTE       = $00
LASTNOTE        = $4f
ARP             = $50
SND             = $60
SLIDE           = $80
TIEOFF          = $8c
TIEON           = $8d
NOPULSEINIT     = $8e
TIENOPULSEINIT  = $8f
DUR             = $90
REST            = $fd
CONT            = $fe
ENDPATT         = $ff

        ;Track data
REPEAT          = $a0
TRSTART         = $c0
TR              = $e0
ENDSONG         = $fe
RESTART         = $ff

        ;Channel bits
TIEBIT          = 1
PULSEBIT        = 2
SLIDEBIT        = 4


                processor 6502
                org $810

start:          cld
                lda fa                  ;Find out drive number
                cmp #$08
                bcs driveok
                lda #$08
driveok:        sta drivenumber
                lda #$36                ;Switch off BASIC-rom
                sta $01
                jsr music+6             ;Make sure music is stopped
                lda firsttime
                bne start_nonuke
                jsr nukeall
                inc firsttime
start_nonuke:   jsr initpatttbl
                jsr initscreen
                jsr initraster
                jmp editmusic

editsounds:     jsr printsoundscreen
editsoundloop:  jsr getkey
                sta storea
                jsr es_hexedit
                ldx #$00
es_findkey:     lda sndeditkeytbl,x
                cmp #$ff
                beq editsoundloop
                cmp storea
                beq es_keyfound
                inx
                inx
                inx
                jmp es_findkey
es_keyfound:    lda sndeditkeytbl+1,x
                sta es_jsr+1
                lda sndeditkeytbl+2,x
                sta es_jsr+2
es_jsr:         jsr $0000
                jmp editsoundloop

help:           pla
                pla
                lda #$00
                sta bgcolor
                lda #$0f
                sta textcolor
                lda #<helptext
                sta textlo
                lda #>helptext
                sta texthi
helppageloop:   jsr clearscreen
                lda #$00
                sta cursorx
                sta cursory
helploop:       ldy #$00
                lda (textlo),y
                beq help_end
                jsr printtextcont
                inc cursory
                lda cursory
                cmp #25
                bne helploop
help_end:       jsr waitkey
                ldy #$00
                lda (textlo),y
                bne helppageloop
                jmp editmusic

es_putsnd:      ldy soundnum
                ldx #$00
                lda #<snd_ad
                sta trklo
                lda #>snd_ad
                sta trkhi
es_putsndloop:  lda (trklo),y
                sta sndcopybuf,x
                clc
                lda trklo
                adc #$20
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                inx
                cpx #14
                bne es_putsndloop
                rts

es_takesnd:     ldy soundnum
                ldx #$00
                lda #<snd_ad
                sta trklo
                lda #>snd_ad
                sta trkhi
es_takesndloop: lda sndcopybuf,x
                sta (trklo),y
                clc
                lda trklo
                adc #$20
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                inx
                cpx #14
                bne es_takesndloop
                jmp printsoundinfo

es_nexttrack:   ldx sndeditmode
                clc
                txa
                adc #$01
                and #$03
                sta sndeditmode
                jsr printsndtrack
                ldx sndeditmode
                jmp printsndtrack

es_hexedit:     jsr gethex
                cmp #$ff
                bne es_hexcont
                rts
es_hexcont:     sta storey
                ldx sndeditmode
                beq es_hexsnd
                lda sndeditadrlo,x
                sta trklo
                lda sndeditadrhi,x
                sta trkhi
                ldy sndeditpos,x
                lda sndeditcpos,x
                beq es_sndhexhigh
                jmp es_sndhexlo
es_hexsnd:      lda #<snd_ad
                sta trklo
                lda #>snd_ad
                sta trkhi
                ldy sndeditpos
es_sndhexloop1: cpy #$00
                beq es_sndhexdone1
                clc
                lda trklo
                adc #$20
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                dey
                jmp es_sndhexloop1
es_sndhexdone1: ldy soundnum
                lda sndeditcpos
                beq es_sndhexhigh
es_sndhexlo:    lda (trklo),y
                and #$f0
                ora storey
                sta (trklo),y
                jmp es_moveright
es_sndhexhigh:  asl storey
                asl storey
                asl storey
                asl storey
                lda (trklo),y
                and #$0f
                ora storey
                sta (trklo),y
                jmp es_moveright

es_prevsnd:     dec soundnum
es_sndcommon:   lda soundnum
                and #$1f
                sta soundnum
                jsr printsoundinfo
                rts
es_nextsnd:     inc soundnum
                jmp es_sndcommon

es_moveup:      ldx sndeditmode
                bne es_munotsnd
                dec sndeditpos
                bpl es_mudone
                lda #13
                sta sndeditpos
es_mudone:      jmp printsndtrack
es_munotsnd:    lda sndeditpos,x
                beq es_mudone
                dec sndeditpos,x
                lda sndeditpos,x
                cmp sndeditview,x
                bcs es_mudone
                dec sndeditview,x
                jmp es_mudone

es_movedown:    ldx sndeditmode
                bne es_mdnotsnd
                inc sndeditpos
                lda sndeditpos
                cmp #14
                bcc es_mddone
                lda #$00
                sta sndeditpos
es_mddone:      jmp printsndtrack
es_mdnotsnd:    lda sndeditpos,x
                cmp sndeditlimit,x
                bcs es_mddone
                inc sndeditpos,x
                sec
                lda sndeditpos,x
                sbc sndeditview,x
                cmp #$10
                bcc es_mddone
                inc sndeditview,x
                jmp es_mddone


es_moveright:   ldx sndeditmode
                inc sndeditcpos,x
                lda sndeditcpos,x
                cmp #$02
                bcc es_mrdone
                lda #$00
                sta sndeditcpos,x
                jmp es_movedown
es_mrdone:      jmp printsndtrack
es_mrnotsnd:    rts

es_moveleft:    ldx sndeditmode
                dec sndeditcpos,x
                bpl es_mldone
                lda #$01
                sta sndeditcpos,x
                jmp es_moveup
es_mldone:      jmp printsndtrack
es_mlnotsnd:    rts

es_ins:         ldx sndeditmode
                beq es_insnot
                cpx #$03
                beq es_insnot
                lda sndeditpos,x
                cmp sndeditlimit,x
                bcc es_inscont
es_insnot:      rts
es_inscont:     lda sndeditadrlo,x
                sta trklo
                lda sndeditadrhi,x
                sta trkhi
                ldy sndeditlimit,x
                dey
es_insloop:     lda (trklo),y
                iny
                sta (trklo),y
                dey
                tya
                cmp sndeditpos,x
                beq es_insdone
                dey
                jmp es_insloop
es_insdone:     cpx #$01
                beq es_insarp
es_inswave:     ldy #$1f
es_inswaveloop: lda snd_wavepos,y
                cmp sndeditpos,x
                beq es_inswaveskip
                bcc es_inswaveskip
                adc #$00        ;Carry=1!
                sta snd_wavepos,y
es_inswaveskip: dey
                bpl es_inswaveloop
es_insdone2:    jsr printsoundinfo
                ldx #$03
                jsr printsndtrack
                ldx sndeditmode
                jmp printsndtrack
es_insarp:      ldy #$1f
es_insarploop:  lda snd_arppos,y
                cmp sndeditpos,x
                beq es_insarpskip
                bcc es_insarpskip
                adc #$00        ;Carry=1!
                sta snd_arppos,y
es_insarpskip:  dey
                bpl es_insarploop
                ldy #$0f
es_insarploop2: lda arpchgtbl,y
                cmp sndeditpos,x
                beq es_insarpskip2
                bcc es_insarpskip2
                adc #$00
                sta arpchgtbl,y
es_insarpskip2: dey
                bpl es_insarploop2
                jmp es_insdone2

es_del:         ldx sndeditmode
                beq es_delnot
                cpx #$03
                bne es_delcont
es_delnot:      rts
es_delcont:     lda sndeditadrlo,x
                sta trklo
                lda sndeditadrhi,x
                sta trkhi
                ldy sndeditpos,x
es_delloop:     iny
                lda (trklo),y
                dey
                sta (trklo),y
                tya
                cmp sndeditlimit,x
                beq es_deldone
                iny
                jmp es_delloop
es_deldone:     ldy sndeditlimit,x
                lda #$00
                sta (trklo),y
                cpx #$01
                beq es_delarp
es_delwave:     ldy #$1f
es_delwaveloop: lda snd_wavepos,y
                cmp sndeditpos,x
                beq es_delwaveskip
                bcc es_delwaveskip
                sbc #$01
                sta snd_wavepos,y
es_delwaveskip: dey
                bpl es_delwaveloop
es_deldone2:    jsr printsoundinfo
                ldx #$03
                jsr printsndtrack
                ldx sndeditmode
                jmp printsndtrack
es_delarp:      ldy #$1f
es_delarploop:  lda snd_arppos,y
                cmp sndeditpos,x
                beq es_delarpskip
                bcc es_delarpskip
                sbc #$01
                sta snd_arppos,y
es_delarpskip:  dey
                bpl es_delarploop
                ldy #$0f
es_delarploop2: lda arpchgtbl,y
                cmp sndeditpos,x
                beq es_delarpskip2
                bcc es_delarpskip2
                sbc #$01
                sta arpchgtbl,y
es_delarpskip2: dey
                bpl es_delarploop2
                jmp es_deldone2

editmusic:      jsr printmainscreen
editmusicloop:  jsr getkey
                sta storea
                lda editmode
                cmp #$03
                beq pt_edit
                jsr tr_hexedit
                ldx #$00
tr_findkey:     lda trkeditkeytbl,x
                cmp #$ff
                beq editmusicloop
                cmp storea
                beq tr_keyfound
                inx
                inx
                inx
                jmp tr_findkey
tr_keyfound:    lda trkeditkeytbl+1,x
                sta tr_jsr+1
                lda trkeditkeytbl+2,x
                sta tr_jsr+2
tr_jsr:         jsr $0000
                jmp editmusicloop

pt_edit:        jsr pt_noteedit
                bcs pt_skiphex
                jsr pt_hexedit
pt_skiphex:     ldx #$00
pt_findkey:     lda patteditkeytbl,x
                cmp #$ff
                beq editmusicloop
                cmp storea
                beq pt_keyfound
                inx
                inx
                inx
                jmp pt_findkey
pt_keyfound:    lda patteditkeytbl+1,x
                sta pt_jsr+1
                lda patteditkeytbl+2,x
                sta pt_jsr+2
pt_jsr:         jsr $0000
                jmp editmusicloop

pt_putpatt:     lda pattnum
                tax
                lda patttbllo,x
                sta trklo
                lda patttblhi,x
                sta trkhi
                ldy #$00
pt_putpattloop: lda (trklo),y
                sta pattcopybuf,y
                iny
                bpl pt_putpattloop
                rts

pt_nukepatt:    jsr confirm
                cmp #"Y"
                beq pt_nukepatt2
                rts
pt_nukepatt2:   lda #$00
                sta trackposlo+3
                sta trackviewlo+3
                lda pattnum
                tax
                lda patttbllo,x
                sta trklo
                lda patttblhi,x
                sta trkhi
                ldy #$00
pt_nukepattloop:lda #ENDPATT
                sta (trklo),y
                iny
                bpl pt_nukepattloop
                ldx editmode
                jmp printtrack

pt_takepatt:    lda pattnum
                tax
                lda patttbllo,x
                sta trklo
                lda patttblhi,x
                sta trkhi
                ldy #$00
                lda (trklo),y
                cmp #ENDPATT
                beq pt_takepattloop
                jsr confirm
                cmp #"Y"
                beq pt_takepattok
                rts
pt_takepattok:  ldy #$00
pt_takepattloop:lda pattcopybuf,y
                sta (trklo),y
                iny
                bpl pt_takepattloop
                ldx editmode
                jmp printtrack

gotosound:      pla
                pla
                jmp editsounds

gotomusic:      pla
                pla
                jmp editmusic

pt_ins:         jsr gettrkpos
                lda trackposlo,x
                cmp #$7f
                bne pt_ins2
                rts
pt_ins2:        clc
                lda trackadrlo,x
                adc #$7e
                sta destlo
                lda trackadrhi,x
                adc #$00
                sta desthi
pt_insloop:     ldy #$00
                lda (destlo),y
                iny
                sta (destlo),y
                lda destlo
                cmp trklo
                bne pt_ins3
                lda desthi
                cmp trkhi
                bne pt_ins3
pt_insdone:     ldx editmode
                jmp printtrack
pt_ins3:        dec destlo
                lda destlo
                cmp #$ff
                bne pt_insloop
                dec desthi
                jmp pt_insloop

pt_del:         jsr gettrkpos
                clc
                lda trackadrlo,x
                adc #$80
                sta destlo
                lda trackadrhi,x
                adc #$00
                sta desthi
pt_delloop:     ldy #$01
                lda (trklo),y
                dey
                sta (trklo),y
                inc trklo
                bne pt_del2
                inc trkhi
pt_del2:        lda trklo
                cmp destlo
                bne pt_delloop
                lda trkhi
                cmp desthi
                bne pt_delloop
                ldy #$00
                clc
                lda trackadrlo,x
                adc #$7f
                sta destlo
                lda trackadrhi,x
                adc #$00
                sta desthi
                lda #ENDPATT
                sta (destlo),y
                jmp pt_insdone

pt_snd:         jsr gettrkpos
                lda #SND
                sta (trklo),y
                lda #3
                sta editcpos
                ldx editmode
                jmp printtrack

pt_arp:         jsr gettrkpos
                lda #ARP
                sta (trklo),y
                lda #3
                sta editcpos
                ldx editmode
                jmp printtrack

pt_dur:         jsr gettrkpos
                lda #DUR+2
                sta (trklo),y
                lda #3
                sta editcpos
                ldx editmode
                jmp printtrack

pt_slide:       jsr gettrkpos
                lda #SLIDE
                sta (trklo),y
                lda #3
                sta editcpos
                ldx editmode
                jmp printtrack

pt_pulsetie:    jsr gettrkpos
                lda (trklo),y
                cmp #$8c
                bcc pt_pulsetie2
                cmp #$90
                bcs pt_pulsetie2
                and #$03
                clc
                adc #$01
                and #$03
                ora #$8c
                sta (trklo),y
                jmp printtrack
pt_pulsetie2:   lda #$8d
                sta (trklo),y
                jmp printtrack

pt_rest:        jsr gettrkpos
                lda #REST
                sta (trklo),y
                jmp pt_movedown

pt_cont:        jsr gettrkpos
                lda #CONT
                sta (trklo),y
                jmp pt_movedown

pt_noteedit:    jsr gettrkpos
                lda #$00
                sta octave
                sta note
                lda (trklo),y
                cmp #ARP
                bcs pt_nenotnote
                tay
                lda octavetable,y
                sta octave
                ldy #$00
                lda (trklo),y
                tay
                lda notetable,y
                sta note
                lda editcpos
                bne pt_nenotnote2
                jsr pt_neisnote
                bcc pt_nenothing
                sta note
pt_nestorenote: ldy octave
                lda octavemultable,y
                clc
                adc note
                ldy #$00
                sta (trklo),y
                jmp pt_nedone
pt_nenotnote2:  lda storea
                cmp #"0"
                bcc pt_nenothing
                cmp #"6"+1
                bcs pt_nenothing
                sec
                sbc #"0"
                sta octave
                jmp pt_nestorenote
pt_nenotnote:   lda editcpos
                bne pt_nenothing
                jsr pt_neisnote
                bcc pt_nenothing
                sta (trklo),y
pt_nedone:      jsr pt_moveright
                sec
                rts
pt_nenothing:   clc
                rts

pt_neisnote:    ldy #$00
                lda storea
pt_neisnoteloop:cmp notekeys,y
                beq pt_nenotefound
                iny
                cpy #12
                bne pt_neisnoteloop
                ldy #$00
                clc
                rts
pt_nenotefound: tya
                ldy #$00
                sec
                rts

notekeys:       dc.b "C"
                dc.b "C"+$80
                dc.b "D"
                dc.b "D"+$80
                dc.b "E"
                dc.b "F"
                dc.b "F"+$80
                dc.b "G"
                dc.b "G"+$80
                dc.b "A"
                dc.b "A"+$80
                dc.b "H"


pt_moveleft:    jsr gettrkpos
                lda (trklo),y
                jsr isspecial
                bcc pt_mlns
                jmp pt_moveup
pt_mlns:        ldy #$00
                dec editcpos
                bpl pt_mlnotneg
                lda #$04
                sta editcpos
                jmp pt_moveup
pt_mlnotneg:    lda (trklo),y
                cmp #ARP
                bcc pt_mlnote
                lda editcpos
                cmp #$03
                bcs pt_mldone
pt_mlzero:      lda #$00
                sta editcpos
pt_mldone:      jsr rightcursorpos
                ldx editmode
                jmp printtrack
pt_mlnote:      lda editcpos
                cmp #$01
                beq pt_mlzero
                jmp pt_mldone

pt_moveright:   jsr gettrkpos
                lda (trklo),y
                jsr isspecial
                bcc pt_mrns
                jmp pt_movedown
pt_mrns:        ldy #$00
                inc editcpos
                lda editcpos
                cmp #$05
                bcc pt_mrnotover
pt_mrnext:      lda #$00
                sta editcpos
                jmp pt_movedown
pt_mrnotover:   lda (trklo),y
                cmp #ARP
                bcc pt_mrnote
pt_mrdone:      jsr rightcursorpos
                ldx editmode
                jmp printtrack
pt_mrnote:      lda editcpos
                cmp #$03
                bcc pt_mrdone
                jmp pt_mrnext



pt_moveup:      ldx editmode
                jsr pt_moveposup
                jsr rightcursorpos
                jmp printtrack
pt_moveupfast:  ldx editmode
                lda #$10
                sta storey
pt_mufloop:     jsr pt_moveposup
                dec storey
                bne pt_mufloop
                jsr rightcursorpos
                jmp printtrack

pt_movedown:    ldx editmode
                jsr pt_moveposdown
                jsr rightcursorpos
                jmp printtrack
pt_movedownfast:ldx editmode
                lda #$10
                sta storey
pt_mdfloop:     jsr pt_moveposdown
                dec storey
                bne pt_mdfloop
                jsr rightcursorpos
                jmp printtrack


pt_moveposup:   lda trackposlo,x
                bne pt_mpu2
                rts
pt_mpu2:        dec trackposlo,x
                lda trackposlo,x
                cmp trackviewlo,x
                bcs pt_mpu3
                dec trackviewlo,x
pt_mpu3:        rts

pt_moveposdown: lda trackposlo,x
                cmp #$7f
                bcc pt_mpd2
                rts
pt_mpd2:        jsr gettrkpos
                lda (trklo),y
                cmp #ENDPATT
                beq pt_mpd3
                inc trackposlo,x
                sec
                lda trackposlo,x
                sbc trackviewlo,x
                cmp #20
                bcc pt_mpd3
                inc trackviewlo,x
pt_mpd3:        rts


tr_prevsong:    dec songnum
tr_songcommon:  lda songnum
                and #$1f
                sta songnum
                jmp printsonginfo

tr_nextsong:    inc songnum
                jmp tr_songcommon

tr_prevpatt:    dec pattnum
tr_pattcommon:  lda pattnum
                cmp #$ff
                bne tr_pc1
                lda #$9f
tr_pc1:         cmp #$a0
                bne tr_pc2
                lda #$00
tr_pc2:         sta pattnum
                jsr selectpattern
                lda #$00
                sta trackposlo+3
                sta trackviewlo+3
                ldx #$03
                jsr printtrack
                rts

tr_nextpatt:    inc pattnum
                jmp tr_pattcommon

tr_gotopatt:    jsr gettrkpos
                lda (trklo),y
                cmp #$a0
                bcc tr_gotopatt2
                rts
tr_gotopatt2:   sta pattnum
                jsr selectpattern
                ldx editmode
                lda #$03
                sta editmode
                jsr printtrack
                lda #$00
                sta trackposlo+3
                sta trackviewlo+3
                sta editcpos
                ldx editmode
                jsr printtrack
                rts

tr_setsongstart:lda songnum
                asl
                sta storey
                asl
                adc storey
                tay
                ldx #$00
tr_sssloop:     clc
                lda trackadrlo,x
                adc trackposlo,x
                sta songtbl,y
                lda trackadrhi,x
                adc trackposhi,x
                sta songtbl+1,y
                iny
                iny
                inx
                cpx #$03
                bne tr_sssloop
                jsr printsonginfo
                rts

tr_gosongstart: lda songnum
                asl
                sta storey
                asl
                adc storey
                tay
                ldx #$00
tr_gssloop:     sec
                lda songtbl,y
                sbc trackadrlo,x
                sta trackposlo,x
                sta trackviewlo,x
                lda songtbl+1,y
                sbc trackadrhi,x
                sta trackposhi,x
                sta trackviewhi,x
                lda trackviewhi,x
                cmp #$07
                bne tr_gssok
                lda trackviewlo,x
                cmp #($100-20)
                bcc tr_gssok
                lda #($100-20)
                sta trackviewlo,x
tr_gssok:       iny
                iny
                inx
                cpx #$03
                bne tr_gssloop
                jsr rightcursorpos
                ldx #$00
                jsr printtrack
                inx
                jsr printtrack
                inx
                jsr printtrack
                rts

pt_hexedit:     jsr gethex
                cmp #$ff
                bne pt_hexcont
pt_nohex:       rts
pt_hexcont:     jsr gettrkpos
                lda (trklo),y
                jsr isspecial
                bcs pt_nohex
                cmp #ARP
                bcc pt_nohex
                sta storey
                lda editcpos
                cmp #$03
                bcc pt_nohex
                sbc #$03
                bne pt_noshift
                asl hexdigit
                asl hexdigit
                asl hexdigit
                asl hexdigit
pt_noshift:     tay
                lda ptmask,y
                sta pt_domask+1
                lda storey
                lsr
                lsr
                lsr
                lsr
                tay
                sec
                lda storey
                sbc ptbase,y
pt_domask:      and #$0f
                ora hexdigit
                cmp ptlimit,y
                bcc pt_nolimit
                lda ptlimit,y
pt_nolimit:     cmp ptlow,y
                bcs pt_notlow
                lda ptlow,y
pt_notlow:      clc
                adc ptbase,y
                ldy #$00
                sta (trklo),y
                jmp pt_moveright

ptbase:         dc.b $00,$00,$00,$00,$00,$50,$60,$60
                dc.b $80,$90,$90,$90,$90,$90,$90,$90
ptlimit:        dc.b $00,$00,$00,$00,$00,$0f,$1f,$1f
                dc.b $0b,$6c,$6c,$6c,$6c,$6c,$6c,$6c
ptlow:          dc.b $00,$00,$00,$00,$00,$00,$00,$00
                dc.b $00,$02,$02,$02,$02,$02,$02,$02
ptmask:         dc.b $0f,$f0

tr_hexedit:     jsr gethex
                cmp #$ff
                bne tr_hexcont
                rts
tr_hexcont:     jsr gettrkpos
                lda (trklo),y
                cmp #REPEAT
                bcc tr_hnormal
                cmp #ENDSONG
                bcc tr_h3
tr_hnew:        lda hexdigit
                and #$07
                asl
                asl
                asl
                asl
                sta (trklo),y
                jmp tr_moveright
tr_h3:          lda editcpos
                beq tr_hnew
                cmp #4
                beq tr_h4
                lda (trklo),y
                cmp #TRSTART
                bcc tr_hrepeat
                lda hexdigit
                and #$03
                asl
                asl
                asl
                asl
                sta hexdigit
                lda (trklo),y
                and #$0f
                ora hexdigit
                ora #TRSTART
                sta (trklo),y
                jmp tr_moveright
tr_hrepeat:     lda hexdigit
                and #$01
                asl
                asl
                asl
                asl
                sta hexdigit
                lda (trklo),y
                and #$0f
                ora hexdigit
                ora #REPEAT
                sta (trklo),y
                jmp tr_moveright
tr_h4:          lda (trklo),y
                jmp tr_hlower
tr_hnormal:     lda editcpos
                bne tr_hlower
                lda hexdigit
                cmp #$0a
                bcc tr_hnormalok
                lda #$09
tr_hnormalok:   asl
                asl
                asl
                asl
                sta hexdigit
                lda (trklo),y
                and #$0f
                ora hexdigit
                sta (trklo),y
                jmp tr_moveright
tr_hlower:      lda (trklo),y
                and #$f0
                ora hexdigit
                sta (trklo),y
                jmp tr_moveright

gethex:         lda storea
                cmp #"0"
                bcc gh_hnotnum
                cmp #"9"+1
                bcs gh_hnotnum
                sbc #"0"-1
                jmp gh_h2
gh_hnotalpha:   lda #$ff
                rts
gh_hnotnum:     cmp #"A"
                bcc gh_hnotalpha
                cmp #"F"+1
                bcs gh_hnotalpha
                sbc #"A"-11
gh_h2:          sta hexdigit
                rts

tr_ins:         jsr gettrkpos
                lda trackposlo,x
                cmp #$ff
                bne tr_ins2
                lda trackposhi,x
                cmp #$07
                bne tr_ins2
                rts
tr_ins2:        clc
                lda trackadrlo,x
                adc #$fe
                sta destlo
                lda trackadrhi,x
                adc #$07
                sta desthi
tr_insloop:     ldy #$00
                lda (destlo),y
                iny
                sta (destlo),y
                lda destlo
                cmp trklo
                bne tr_ins3
                lda desthi
                cmp trkhi
                bne tr_ins3
tr_insdone:     ldx editmode
                jsr printtrack
                jsr gettrkpos
                clc
                lda trackadrlo,x
                sta destlo
                lda trackadrhi,x
                adc #$08
                sta desthi
                ldx #$00
tr_inssongtbl:  lda songtbl+1,x
                cmp trkhi
                beq tr_inssonglow
                bcc tr_inssongnot
                bcs tr_inssongyes
tr_inssonglow:  lda songtbl,x
                cmp trklo
                beq tr_inssongnot
                bcc tr_inssongnot
tr_inssongyes:  lda songtbl+1,x
                cmp desthi
                bcs tr_inssongnot
                inc songtbl,x
                bne tr_inssongnot
                inc songtbl+1,x
tr_inssongnot:  inx
                inx
                cpx #32*2*3
                bcc tr_inssongtbl
                jsr printsonginfo
                rts

tr_ins3:        dec destlo
                lda destlo
                cmp #$ff
                bne tr_insloop
                dec desthi
                jmp tr_insloop

tr_del:         jsr gettrkpos
                clc
                lda trackadrlo,x
                sta destlo
                lda trackadrhi,x
                adc #$08
                sta desthi
tr_delloop:     ldy #$01
                lda (trklo),y
                dey
                sta (trklo),y
                inc trklo
                bne tr_del2
                inc trkhi
tr_del2:        lda trklo
                cmp destlo
                bne tr_delloop
                lda trkhi
                cmp desthi
                bne tr_delloop
                ldy #$00
                clc
                lda trackadrlo,x
                adc #$ff
                sta destlo
                lda trackadrhi,x
                adc #$07
                sta desthi
                lda #RESTART
                sta (destlo),y
tr_deldone:     ldx editmode
                jsr printtrack
                jsr gettrkpos
                clc
                lda trackadrlo,x
                sta destlo
                lda trackadrhi,x
                adc #$08
                sta desthi
                ldx #$00
tr_delsongtbl:  lda songtbl+1,x
                cmp trkhi
                beq tr_delsonglow
                bcc tr_delsongnot
                bcs tr_delsongyes
tr_delsonglow:  lda songtbl,x
                cmp trklo
                beq tr_delsongnot
                bcc tr_delsongnot
tr_delsongyes:  lda songtbl+1,x
                cmp desthi
                bcs tr_delsongnot
                dec songtbl,x
                lda songtbl,x
                cmp #$ff
                bne tr_delsongnot
                dec songtbl+1,x
tr_delsongnot:  inx
                inx
                cpx #32*2*3
                bcc tr_delsongtbl
                jsr printsonginfo
                rts

tr_restart:     jsr gettrkpos
                lda #RESTART
                sta (trklo),y
                jmp tr_movedown
tr_endsong:     jsr gettrkpos
                lda #ENDSONG
                sta (trklo),y
                jmp tr_movedown
tr_repeat:      jsr gettrkpos
                lda #REPEAT+1
                sta (trklo),y
                lda #$03
                sta editcpos
                jmp printtrack
tr_trans:       jsr gettrkpos
                lda #TR
                sta (trklo),y
                lda #$03
                sta editcpos
                jmp printtrack

gettrkpos:      ldx editmode
                clc
                lda trackadrlo,x
                adc trackposlo,x
                sta trklo
                lda trackadrhi,x
                adc trackposhi,x
                sta trkhi
                ldy #$00
                rts

rightcursorpos: jsr gettrkpos
                cpx #$03
                beq rcp_patt
                lda (trklo),y
                cmp #REPEAT
                bcs rcp_negative
                lda editcpos
                cmp #$01
                bcc rcp_ok
                lda #$01
                sta editcpos
rcp_ok:         rts
rcp_negative:   cmp #ENDSONG
                bcs rcp_zero
                lda editcpos
                cmp #$01
                beq rcp_zero
                rts
rcp_zero:       lda #$00
                sta editcpos
                rts
rcp_patt:       lda (trklo),y
                cmp #ARP
                bcc rcp_note
                jsr isspecial
                bcs rcp_zero
                lda editcpos
                cmp #$01
                beq rcp_to3
                cmp #$02
                beq rcp_to3
                rts
rcp_to3:        lda #$03
                sta editcpos
                rts
rcp_note:       lda editcpos
                cmp #$01
                bcc rcp_noshit
                lda #$02
                sta editcpos
rcp_noshit:     rts

isspecial:      ldy #$00
rcp_special:    cmp pptspecial,y
                beq rcp_specfound
                iny
                cpy #$07
                bcc rcp_special
                clc
                rts
rcp_specfound:  sec
                rts

tr_moveleft:    jsr gettrkpos
                lda (trklo),y
                cmp #REPEAT
                bcs tr_mlneg
                dec editcpos
                bpl tr_mlok
tr_ml4:         lda #$04
                sta editcpos
tr_mlmoveup:    jsr tr_moveposup
                jsr rightcursorpos
tr_mlok:        jmp printtrack
tr_mlneg:       cmp #ENDSONG
                bcs tr_ml4
tr_mlnotend:    dec editcpos
                bpl tr_mlnotneg
                jmp tr_ml4
tr_mlnotneg:    lda editcpos
                cmp #$02
                bne tr_mlok
                lda #$00
                sta editcpos
                jmp tr_mlok

tr_moveright:   jsr gettrkpos
                lda (trklo),y
                cmp #REPEAT
                bcs tr_mrneg
                inc editcpos
                lda editcpos
                cmp #$02
                bcc tr_mrok
                lda #$00
                sta editcpos
tr_mrmovedown:  jsr tr_moveposdown
                jsr rightcursorpos
tr_mrok:        jmp printtrack
tr_mrneg:       cmp #ENDSONG
                bcs tr_mrmovedown
                inc editcpos
                lda editcpos
                cmp #$05
                bcs tr_mrover
                cmp #$01
                bne tr_mrok
                lda #$03
                sta editcpos
                jmp tr_mrok
tr_mrover:      lda #$00
                sta editcpos
                jmp tr_mrmovedown

tr_playstop:    lda mus_play+1
                beq tr_play
                jsr music+6
                rts
tr_play:        lda #$00
                sta fastfwd
                sta maxraster
                lda songnum
                jsr music
                rts

tr_fastforward: lda #$10
                sta fastfwd
                rts

tr_nexttrack:   ldx editmode
                inc editmode
                lda editmode
                and #$03
                sta editmode
                jsr printtrack
                jsr rightcursorpos
                ldx editmode
                jsr printtrack
                rts

tr_moveup:      jsr tr_moveposup
                jsr rightcursorpos
                jsr printtrack
                rts
tr_moveupfast:  lda #$10
                sta storey
tr_mufloop:     jsr tr_moveposup
                dec storey
                bne tr_mufloop
                jsr rightcursorpos
                jsr printtrack
                rts

tr_moveposup:   ldx editmode
                lda trackposlo,x
                ora trackposhi,x
                beq tr_moveup2
                dec trackposlo,x
                lda trackposlo,x
                cmp #$ff
                bne tr_moveup3
                dec trackposhi,x
tr_moveup3:     lda trackposhi,x
                cmp trackviewhi,x
                beq tr_moveuplo
                bcs tr_moveup2
                bcc tr_moveup5
tr_moveuplo:    lda trackposlo,x
                cmp trackviewlo,x
                bcs tr_moveup2
tr_moveup5:     dec trackviewlo,x
                lda trackviewlo,x
                cmp #$ff
                bne tr_moveup2
                dec trackviewhi,x
tr_moveup2:     rts

tr_movedown:    jsr tr_moveposdown
                jsr rightcursorpos
                jsr printtrack
                rts
tr_movedownfast:lda #$10
                sta storey
tr_mdfloop:     jsr tr_moveposdown
                dec storey
                bne tr_mdfloop
                jsr rightcursorpos
                jsr printtrack
                rts

tr_moveposdown: ldx editmode
                lda trackposlo,x
                cmp #$ff
                bne tr_movedown2
                lda trackposhi,x
                cmp #$07
                bne tr_movedown2
                rts
tr_movedown2:   inc trackposlo,x
                bne tr_movedown3
                inc trackposhi,x
tr_movedown3:   sec
                lda trackposlo,x
                sbc trackviewlo,x
                sta destlo
                cmp #20
                bcc tr_movedown4
                inc trackviewlo,x
                bne tr_movedown4
                inc trackviewhi,x
tr_movedown4:   rts

diskmenu:       pla
                pla
diskmenu2:      jsr clearscreen
                jsr printsonginfo
                jsr printlogo
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #2
                ldy #4
                jsr setxy
                lda #<disktext
                sta textlo
                lda #>disktext
                sta texthi
dmloop1:        jsr printtextcont
                lda #$00
                sta bgcolor
                lda #$0c
                sta textcolor
                inc cursory
                lda cursory
                cmp #14
                bne dmloop1
                ldx #0
                ldy #22
                jsr setxy
                ldx #<devicetext
                ldy #>devicetext
                jsr printtext
                ldx #14
                ldy #22
                jsr setxy
                lda drivenumber
                jsr printhex8
                jsr getkey
                cmp #"C"
                bne dm_nodrivechg
                lda drivenumber
                clc
                adc #$01
                and #$03
                ora #$08
                sta drivenumber
                jmp diskmenu2
dm_nodrivechg:  cmp #"N"
                beq dm_nuke
                cmp #"X"
                beq dm_exit
                cmp #"L"
                beq dm_load
                cmp #"S"
                bne dm_nosave
                jmp dm_save
dm_nosave:      cmp #"E"
                bne dm_noerase
                jmp dm_erase
dm_noerase:     cmp #"D"
                bne dm_nodir
                jmp dm_dir
dm_nodir:       cmp #"P"
                bne dm_nopack
                jmp dm_pack
dm_nopack:      jmp editmusic

dm_exit:        jsr confirm
                cmp #"Y"
                beq dm_exit2
                jmp diskmenu2
dm_exit2:       jmp 64738

dm_nuke:        jsr confirm
                cmp #"Y"
                beq dm_nuke2
                jmp diskmenu2
dm_nuke2:       jsr music+6
                jsr nukeall
                jmp editmusic

dm_load:        jsr askname
                lda namelength
                bne loadok
                jmp editmusic
loadok:         jsr music+6
                lda #$00
                sta trackposlo+3
                sta trackposhi+3
                sta trackviewlo+3
                sta trackviewhi+3
                lda #$02
                ldy #$00
                ldx drivenumber
                jsr setlfs
                clc
                lda namelength
                adc #$02
                ldx #<(scratch+1)
                ldy #>(scratch+1)
                jsr setnam
                jsr open
                ldx #$02
                jsr chkin
                bcs load_error
                jsr acptr               ;Get startaddress of flie
                sta destlo
                lda status              ;If file ends now, load error!
                bne load_error
                jsr acptr
                sta desthi
                lda destlo              ;Check the startaddress; if it isn't
                cmp #<songtbl           ;correct, this is not a Sadotracker-
                bne load_error          ;song
                lda desthi
                cmp #>songtbl
                bne load_error
load_loop:      jsr load_getbyte
                cmp #ESCBYTE
                beq load_block
                jsr load_storebyte
                jmp load_loop
load_block:     jsr load_getbyte
                sta storea
                jsr load_getbyte
                tax
                lda storea
load_blockloop: jsr load_storebyte
                dex
                bne load_blockloop
                jmp load_loop

load_storebyte: ldy #$00
                sta (destlo),y
                inc destlo
                bne load_storebyte2
                inc desthi
load_storebyte2:rts

load_getbyte:   ldy status
                bne load_fileend
                jsr acptr
                dec $d020
                inc $d020
                rts
load_fileend:   pla
                pla
load_error:     lda #$02
                jsr close
                jsr clrchn
                jmp editmusic

dm_save:        lda #$ff                ;Make sure that the last byte is
                sta $a7ff               ;packed right! :-)
                jsr askname
                lda namelength
                bne saveok
                jmp editmusic
saveok:         jsr music+6
                lda #$02
                ldy #$01
                ldx drivenumber
save_devok:     jsr setlfs
                clc
                lda namelength
                adc #$02
                ldx #<(scratch+1)
                ldy #>(scratch+1)
                jsr setnam
                lda namelength
                jsr open
                ldx #$02
                jsr chkout
                bcs load_error
                lda #<songtbl
                sta destlo
                jsr save_sendbyte
                lda #>songtbl
                sta desthi
                jsr save_sendbyte
save_loop:      ldy #$00
                lda (destlo),y
                ldy #$01
                cmp (destlo),y
                beq save_block
                cmp #ESCBYTE
                beq save_literal
                jsr save_sendbyte
save_next:      inc destlo
                bne save_nothigh
                inc desthi
save_nothigh:   lda desthi
                cmp #$a8
                bcc save_loop
                jmp save_done
save_literal:   lda #ESCBYTE
                jsr save_sendbyte
                jsr save_sendbyte
                lda #$01
                jsr save_sendbyte
                jmp save_next
save_block:     lda #ESCBYTE
                jsr save_sendbyte
                ldy #$00
                lda (destlo),y
                sta storea
                jsr save_sendbyte
                ldy #$00
save_blocklen:  iny
                cpy #$ff
                beq save_blockready
                lda (destlo),y
                cmp storea
                beq save_blocklen
save_blockready:tya
                jsr save_sendbyte
                clc
                adc destlo
                sta destlo
                lda desthi
                adc #$00
                sta desthi
                jmp save_nothigh
save_sendbyte:  jsr ciout
                ldy status
                bne save_senderror
                dec $d020
                inc $d020
                rts
save_senderror: pla
                pla
save_done:      jmp load_error

dm_erase:       jsr askname
                lda namelength
                bne erase_ok
                jmp editmusic
erase_ok:       jsr music+6
                lda #15
                ldx drivenumber
                ldy #15
                jsr setlfs
                clc
                lda namelength
                adc #$03
                ldx #<scratch
                ldy #>scratch
                jsr setnam
                jsr open
                lda #15
                jsr close
                jmp editmusic

dir_end:        lda #$02
                jsr close
                jsr clrchn
                jsr waitkey
                jsr initscreen
                jmp editmusic
dm_dir:         jsr clearscreen
                jsr music+6
                lda #$02
                ldy #$00
                ldx drivenumber
                jsr setlfs
                lda #$01
                ldx #<dirname
                ldy #>dirname
                jsr setnam
                jsr open
                ldx #$02
                jsr chkin
                lda #21
                sta $d018
                lda #27
                sta $d011
                clc
                ldx #$00
                ldy #$00
                jsr plot
                lda #$0c
                sta 646
                jsr acptr
                jsr acptr
dir_loop:       lda status
                bne dir_end
                jsr acptr
                cmp #$01
                bne dir_loop
                jsr acptr
                lda status
                bne dir_end
                jsr acptr
                sta trklo
                jsr acptr
                sta trkhi
                lda #$00
                sta dirprintnum
                tay
dir_100loop:    lda trkhi
                cmp #>100
                beq dir_100cl
                bcs dir_100ok
                bcc dir_100quit
dir_100cl:      lda trklo
                cmp #<100
                bcs dir_100ok
                bcc dir_100quit
dir_100ok:      iny
                sec
                lda trklo
                sbc #<100
                sta trklo
                lda trkhi
                sbc #>100
                sta trkhi
                jmp dir_100loop
dir_100quit:    tya
                clc
                adc #"0"
                cmp #"0"
                beq dir_10
                jsr chrout
                inc dirprintnum
dir_10:         ldy #$00
dir_10loop:     lda trkhi
                cmp #>10
                beq dir_10cl
                bcs dir_10ok
                bcc dir_10quit
dir_10cl:       lda trklo
                cmp #<10
                bcs dir_10ok
                bcc dir_10quit
dir_10ok:       iny
                sec
                lda trklo
                sbc #<10
                sta trklo
                lda trkhi
                sbc #>10
                sta trkhi
                jmp dir_10loop
dir_10quit:     tya
                clc
                adc #"0"
                ldy dirprintnum
                bne dir_10pr
                cmp #"0"
                beq dir_10np
dir_10pr:       jsr chrout
dir_10np:       lda trklo
                clc
                adc #"0"
                jsr chrout
                lda #$20
                jsr chrout
dir_loop3:      lda status
                bne dir_end2
                jsr acptr
                cmp #$00
                bne dir_noline
                lda #13
                jsr chrout
                jmp dir_loop
dir_noline:     jsr chrout
                jmp dir_loop3
dir_end2:       jmp dir_end

dirname:        dc.b "$"
filebuffer:     ds.b 32,0
dirprintnum:    dc.b 0

dm_pack:        jsr clearscreen
                jsr printsonginfo
                lda #$0f
                sta textcolor
                ldx #$00
                stx bgcolor
                ldy #$00
                jsr setxy
                lda #<packtext
                sta textlo
                lda #>packtext
                sta texthi
dm_packloop:    jsr printtextcont
                inc cursory
                lda cursory
                cmp #$07
                bcc dm_packloop
                lda #$00
                sta relocadrlo
                lda #$10
                sta relocadrhi
                lda #$0c
                sta textcolor
dm_packloop2:   ldx #$02
                ldy #$08
                jsr setxy
                lda relocadrlo
                ldx relocadrhi
                jsr printhex16
dm_packwait:    jsr getkey
                cmp #$00
                beq dm_packwait
                cmp #KEY_UP
                bne dm_pl2not1
                dec relocadrhi
dm_pl2not1:     cmp #KEY_DOWN
                bne dm_pl2not2
                inc relocadrhi
dm_pl2not2:     cmp #KEY_LEFT
                bne dm_pl2not3
                dec relocadrlo
                ldx relocadrlo
                cpx #$ff
                bne dm_pl2not3
                dec relocadrhi
dm_pl2not3:     cmp #KEY_RIGHT
                bne dm_pl2not4
                inc relocadrlo
                bne dm_pl2not4
                inc relocadrhi
dm_pl2not4:     cmp #KEY_BREAK
                beq dm_packabort
                cmp #13
                beq dm_packadrok
                jmp dm_packloop2
dm_packabort:   jsr initscreen
                jmp editmusic
dm_packadrok:   jsr music+6             ;Stop song now
                ldx #$1f                ;Find out how many sounds are used
dm_packfindsnd: lda snd_ad,x
                sta $d020
                ora snd_sr,x
                bne dm_packfindsnd2
                dex
                bne dm_packfindsnd
dm_packfindsnd2:inx
                stx numbersnd
                ldx #$1f                ;Find out how many songs are used
                ldy #31*6
dm_packfindsng: lda songtbl,y
                sta $d020
                cmp #<CHAN1
                bne dm_packfindsng2
                lda songtbl+1,y
                cmp #>CHAN1
                bne dm_packfindsng2
                lda songtbl+2,y
                cmp #<CHAN2
                bne dm_packfindsng2
                lda songtbl+3,y
                cmp #>CHAN2
                bne dm_packfindsng2
                lda songtbl+4,y
                cmp #<CHAN3
                bne dm_packfindsng2
                lda songtbl+5,y
                cmp #>CHAN3
                bne dm_packfindsng2
                dey
                dey
                dey
                dey
                dey
                dey
                dex
                bne dm_packfindsng
dm_packfindsng2:inx
                stx numbersong
                ldx #$9f                        ;Find out how many patterns
dm_packfindpt:  lda patttbllo,x                 ;are used
                sta $d020
                sta trklo
                lda patttblhi,x
                sta trkhi
                ldy #$00
                lda (trklo),y
                cmp #$ff
                bne dm_packfindpt2
                dex
                bne dm_packfindpt
dm_packfindpt2: inx
                stx numberpatt
                ldx #253                ;Find out the length of the arpeggio
dm_packfindarp: lda arptbl,x            ;table
                sta $d020
                cmp #$fe
                beq dm_packfindarp3
                cmp #$ff
                bne dm_packfindarp2
                inx
                jmp dm_packfindarp3
dm_packfindarp2:dex
                bne dm_packfindarp
dm_packfindarp3:inx
                stx lengtharp
                ldx #253                ;Find out the length of the wave
dm_packfindwav: lda wavetbl,x            ;table
                sta $d020
                cmp #$fe
                beq dm_packfindwav3
                cmp #$ff
                bne dm_packfindwav2
                inx
                jmp dm_packfindwav3
dm_packfindwav2:dex
                bne dm_packfindwav
dm_packfindwav3:inx
                stx lengthwav
                ldx #$00
dm_packfindtrk: clc                     ;Find out the length of each of
                lda trackadrlo,x        ;the three tracks
                adc #$ff
                sta trklo
                lda trackadrhi,x
                adc #$07
                sta trkhi
dm_packfindtrk2:ldy #$00
                lda (trklo),y
                sta $d020
                cmp #$fe
                bcc dm_packfindtrk3
                sec
                lda trklo
                sbc #$01
                sta trklo
                lda trkhi
                sbc #$00
                sta trkhi
                lda trklo
                cmp trackadrlo,x
                bne dm_packfindtrk2
                lda trkhi
                cmp trackadrhi,x
                bne dm_packfindtrk2
dm_packfindtrk3:clc
                lda trklo
                adc #$02
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                sec
                lda trklo
                sbc trackadrlo,x
                sta lengthtrklo,x
                lda trkhi
                sbc trackadrhi,x
                sta lengthtrkhi,x
                inx
                cpx #$03
                bne dm_packfindtrk
                ldx numberpatt
                dex
dm_packfindpl:  lda patttbllo,x
                sta trklo
                lda patttblhi,x
                sta trkhi
                ldy #$7f
dm_packfindpl2: lda (trklo),y
                sta $d020
                cmp #$ff
                bne dm_packfindpl3
                dey
                bpl dm_packfindpl2
dm_packfindpl3: iny
                iny
                tya
                sta lengthpatt,x
                dex
                cpx #$ff
                bne dm_packfindpl
dm_packmakesnd: lda #<snd_ad            ;Now make the "packed"
                sta trklo               ;sound table
                lda #>snd_sr
                sta trkhi
                lda #<packsndtbl
                sta destlo
                lda #>packsndtbl
                sta desthi
                ldx #14
dm_packmakesnd2:ldy numbersnd
                dey
dm_packmakesnd3:lda (trklo),y
                sta $d020
                sta (destlo),y
                dey
                bpl dm_packmakesnd3
                clc
                lda trklo
                adc #$20
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                clc
                lda destlo
                adc numbersnd
                sta destlo
                lda desthi
                adc #$00
                sta desthi
                dex
                bne dm_packmakesnd2
                clc
                lda relocadrlo                  ;Now calculate address for
                adc #<PLAYERSIZE                ;all elements of the tune
                sta songtbladrlo
                lda relocadrhi
                adc #>PLAYERSIZE
                sta songtbladrhi
                clc
                lda numbersong
                adc numbersong
                adc numbersong
                adc numbersong
                adc numbersong
                adc numbersong
                sta trklo
                clc
                lda songtbladrlo
                adc trklo
                sta patttbladrlo
                lda songtbladrhi
                adc #$00
                sta patttbladrhi
                clc
                lda patttbladrlo
                adc numberpatt
                sta sndtbladrlo
                lda patttbladrhi
                adc #$00
                sta sndtbladrhi
                clc
                lda sndtbladrlo
                adc numberpatt
                sta sndtbladrlo
                lda sndtbladrhi
                adc #$00
                sta sndtbladrhi
                lda sndtbladrlo
                sta arptbladrlo
                lda sndtbladrhi
                sta arptbladrhi
                ldx numbersnd
dm_packshit:    clc
                lda arptbladrlo
                sta $d020
                adc #14
                sta arptbladrlo
                lda arptbladrhi
                adc #0
                sta arptbladrhi
                dex
                bne dm_packshit
                clc
                lda arptbladrlo
                adc lengtharp
                sta wavtbladrlo
                lda arptbladrhi
                adc #0
                sta wavtbladrhi
                clc
                lda wavtbladrlo
                adc lengthwav
                sta arpchtbladrlo
                lda wavtbladrhi
                adc #0
                sta arpchtbladrhi
                clc
                lda arpchtbladrlo
                adc #$10
                sta packtrkadrlo
                lda arpchtbladrhi
                adc #0
                sta packtrkadrhi

                clc
                lda packtrkadrlo
                adc lengthtrklo
                sta packtrkadrlo+1
                lda packtrkadrhi
                adc lengthtrkhi
                sta packtrkadrhi+1

                clc
                lda packtrkadrlo+1
                adc lengthtrklo+1
                sta packtrkadrlo+2
                lda packtrkadrhi+1
                adc lengthtrkhi+1
                sta packtrkadrhi+2

                clc
                lda packtrkadrlo+2
                adc lengthtrklo+2
                sta pattadrlo
                sta trklo
                lda packtrkadrhi+2
                adc lengthtrkhi+2
                sta pattadrhi
                sta trkhi

                ldy numberpatt
                ldx #$00
                clc
                lda dm_packptradr1+1
                adc numberpatt
                sta dm_packptradr2+1
                lda dm_packptradr1+2
                adc #$00
                sta dm_packptradr2+2
dm_packptradr:  lda trklo               ;Build the "virtual" patterntable
                sta $d020
dm_packptradr1: sta packpatttbl,x
                lda trkhi
dm_packptradr2: sta packpatttbl,x
                clc
                lda trklo
                adc lengthpatt,x
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                inx
                dey
                bne dm_packptradr
                lda trklo
                sta songendadrlo
                lda trkhi
                sta songendadrhi
                ldy #$00
                ldx #$00
                lda numbersong
                sta destlo
dm_packsongadr: sec                     ;Build the "virtual" songtable
                lda songtbl,y
                sta $d020
                sbc trackadrlo,x
                sta trklo
                lda songtbl+1,y
                sbc trackadrhi,x
                sta trkhi
                clc
                lda trklo
                adc packtrkadrlo,x
                sta packsongtbl,y
                lda trkhi
                adc packtrkadrhi,x
                sta packsongtbl+1,y
                inx
                cpx #$03
                bcc dm_packsongadr2
                ldx #$00
                dec destlo
dm_packsongadr2:iny
                iny
                lda destlo
                bne dm_packsongadr

                lda #<PLAYERORIG        ;Copy the original player to the
                sta trklo               ;work area for relocating
                lda #>PLAYERORIG
                sta trkhi
                lda #<PLAYER
                sta destlo
                lda #>PLAYER
                sta desthi
                ldy #$00
dm_pcopyplayer: lda (trklo),y
                sta $d020
                sta (destlo),y
                inc trklo
                inc destlo
                bne dm_pcopyplayer2
                inc trkhi
                inc desthi
dm_pcopyplayer2:lda destlo
                cmp #<(PLAYER+PLAYERSIZE)
                bne dm_pcopyplayer
                lda desthi
                cmp #>(PLAYER+PLAYERSIZE)
                bne dm_pcopyplayer

                lda #<PLAYER            ;Now perform the relocation itself
                sta destlo
                lda #>PLAYER
                sta desthi
dm_relocate:    ldy #$00                ;Get the instruction
                lda (destlo),y
                sta $d020
                bne dm_notrelocdone     ;Zero=done
                jmp dm_relocdone
dm_notrelocdone:sta dm_compare+1
                lda #<asmtable
                sta trklo
                lda #>asmtable
                sta trkhi
dm_searchasm:   lda (trklo),y
                cmp #$ff                ;$ff=end of table, something went
                bne dm_compare          ;fucking wrong!
dm_eternity:    inc $d020
                jmp dm_eternity
dm_compare:     cmp #$00
                beq dm_asmfound
                clc
                lda trklo
                adc #$02
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                jmp dm_searchasm
dm_asmfound:    ldy #$01
                lda (trklo),y           ;Get size of instruction
                cmp #$03                ;3-byte instructions must be relocated
                beq dm_absolute
dm_nextasm:     clc
                adc destlo
                sta destlo
                lda desthi              ;Else we go on
                adc #$00
                sta desthi
                jmp dm_relocate
dm_absdone:     lda #$03
                jmp dm_nextasm
dm_absolute:    ldy #$02                ;Get highbyte of the address
                lda (destlo),y          ;which determines the type of the
                cmp #$d4                ;relocation, but if it is a SID-chip
                beq dm_absdone          ;reference then skip it!
                lsr
                lsr
                lsr
                lsr
                asl
                tax
                dex
                dex
                lda dm_reljmptbl,x
                sta dm_reljmp+1
                lda dm_reljmptbl+1,x
                sta dm_reljmp+2
dm_reljmp:      jmp $0000

dm_reljmptbl:   dc.w relplayer
                dc.w relsongtbl
                dc.w relpatttbllo
                dc.w relpatttblhi
                dc.w relsnd
                dc.w relarptbl
                dc.w relwavetbl
                dc.w relarpchtbl


relplayer:      ldy #$01
                sec
                lda (destlo),y
                sbc #<PLAYERVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>PLAYERVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc relocadrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc relocadrhi
                sta (destlo),y
                jmp dm_absdone

relsongtbl:     ldy #$01
                sec
                lda (destlo),y
                sbc #<SONGTBLVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>SONGTBLVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc songtbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc songtbladrhi
                sta (destlo),y
                jmp dm_absdone

relpatttbllo:   ldy #$01
                sec
                lda (destlo),y
                sbc #<PATTTBLLOVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>PATTTBLLOVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc patttbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc patttbladrhi
                sta (destlo),y
                jmp dm_absdone

relpatttblhi:   ldy #$01
                sec
                lda (destlo),y
                sbc #<PATTTBLHIVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>PATTTBLHIVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc patttbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc patttbladrhi
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc numberpatt
                sta (destlo),y
                iny
                lda (destlo),y
                adc #$00
                sta (destlo),y
                jmp dm_absdone

relsnd:         ldy #$01
                lda (destlo),y
                lsr                     ;Get number of soundparameter
                lsr
                lsr
                lsr
                tax
                lda #$00
                sta (destlo),y
                iny
                sta (destlo),y
relsnd2:        cpx #$00
                beq relsnd3
                dex
                ldy #$01
                clc
                lda (destlo),y
                adc numbersnd
                sta (destlo),y
                iny
                lda (destlo),y
                adc #$00
                sta (destlo),y
                jmp relsnd2
relsnd3:        ldy #$01
                clc
                lda (destlo),y
                adc sndtbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc sndtbladrhi
                sta (destlo),y
                jmp dm_absdone

relarptbl:      ldy #$01
                sec
                lda (destlo),y
                sbc #<ARPTBLVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>ARPTBLVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc arptbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc arptbladrhi
                sta (destlo),y
                jmp dm_absdone

relwavetbl:     ldy #$01
                sec
                lda (destlo),y
                sbc #<WAVETBLVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>WAVETBLVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc wavtbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc wavtbladrhi
                sta (destlo),y
                jmp dm_absdone


relarpchtbl:    ldy #$01
                sec
                lda (destlo),y
                sbc #<ARPCHTBLVIRT
                sta (destlo),y
                iny
                lda (destlo),y
                sbc #>ARPCHTBLVIRT
                sta (destlo),y
                dey
                clc
                lda (destlo),y
                adc arpchtbladrlo
                sta (destlo),y
                iny
                lda (destlo),y
                adc arpchtbladrhi
                sta (destlo),y
                jmp dm_absdone


dm_relocdone:   lda #$00
                sta $d020
                lda #$0f
                sta textcolor
                ldx #$00                ;Now print some statistics about
                ldy #$0a                ;memory use of the song
                jsr setxy
                ldx #<packstat1
                ldy #>packstat1
                jsr printtext
                lda #$11
                sta cursorx
                lda numbersong
                jsr printhex8

                ldx #$00
                ldy #$0b
                jsr setxy
                ldx #<packstat2
                ldy #>packstat2
                jsr printtext
                lda #$11
                sta cursorx
                lda numberpatt
                jsr printhex8

                ldx #$00
                ldy #$0c
                jsr setxy
                ldx #<packstat3
                ldy #>packstat3
                jsr printtext
                lda #$11
                sta cursorx
                lda numbersnd
                jsr printhex8

                ldx #$00
                ldy #$0d
                jsr setxy
                ldx #<packstat4
                ldy #>packstat4
                jsr printtext
                lda #$11
                sta cursorx
                sec
                lda songendadrlo
                sbc relocadrlo
                sta trklo
                lda songendadrhi
                sbc relocadrhi
                tax
                lda trklo
                jsr printhex16

                lda #$0c
                sta textcolor
                jsr askname
                lda namelength
                bne dm_packsaveok
                jmp editmusic
dm_packsaveok:  lda #$02
                ldy #$01
                ldx drivenumber
                jsr setlfs
                clc
                lda namelength
                adc #$02
                ldx #<(scratch+1)
                ldy #>(scratch+1)
                jsr setnam
                lda namelength
                jsr open
                ldx #$02
                jsr chkout
                bcc nopackerror
                jmp load_error
nopackerror:    lda relocadrlo
                jsr save_sendbyte
                lda relocadrhi
                jsr save_sendbyte

                lda #<PLAYER            ;First, save the player code
                sta trklo
                lda #>PLAYER
                sta trkhi
                lda #<PLAYERSIZE
                sta destlo
                lda #>PLAYERSIZE
                sta desthi
                jsr saveblock

                lda #<packsongtbl       ;Then songtable
                sta trklo
                lda #>packsongtbl
                sta trkhi
                lda #$00
                sta desthi
                lda numbersong
                asl
                sta destlo
                asl
                adc destlo
                sta destlo
                jsr saveblock

                lda #<packpatttbl       ;Then patterntable
                sta trklo
                lda #>packpatttbl
                sta trkhi
                lda numberpatt
                asl
                sta destlo
                lda #$00
                adc #$00
                sta desthi
                jsr saveblock

                lda #<packsndtbl       ;Then sounds
                sta trklo
                lda #>packsndtbl
                sta trkhi
                ldx #14
                lda #$00
                sta destlo
                sta desthi
packsaveloop1:  clc
                lda numbersnd
                adc destlo
                sta destlo
                lda desthi
                adc #$00
                sta desthi
                dex
                bne packsaveloop1
                jsr saveblock

                lda #<arptbl       ;Then arptable
                sta trklo
                lda #>arptbl
                sta trkhi
                lda #$00
                sta desthi
                lda lengtharp
                sta destlo
                jsr saveblock

                lda #<wavetbl       ;Then wavetable
                sta trklo
                lda #>wavetbl
                sta trkhi
                lda #$00
                sta desthi
                lda lengthwav
                sta destlo
                jsr saveblock

                lda #<arpchgtbl       ;Then arpchgtable
                sta trklo
                lda #>arpchgtbl
                sta trkhi
                lda #$00
                sta desthi
                lda #$10
                sta destlo
                jsr saveblock

                lda #<CHAN1       ;Then track 1
                sta trklo
                lda #>CHAN1
                sta trkhi
                lda lengthtrklo
                sta destlo
                lda lengthtrkhi
                sta desthi
                jsr saveblock
                lda #<CHAN2       ;Then track 2
                sta trklo
                lda #>CHAN2
                sta trkhi
                lda lengthtrklo+1
                sta destlo
                lda lengthtrkhi+1
                sta desthi
                jsr saveblock
                lda #<CHAN3       ;Then track 3
                sta trklo
                lda #>CHAN3
                sta trkhi
                lda lengthtrklo+2
                sta destlo
                lda lengthtrkhi+2
                sta desthi
                jsr saveblock
                ldx #$00
savepattloop:   lda patttbllo,x         ;And at last, patterns
                sta trklo
                lda patttblhi,x
                sta trkhi
                lda #$00
                sta desthi
                lda lengthpatt,x
                sta destlo
                stx storex
                jsr saveblock
                ldx storex
                inx
                cpx numberpatt
                bne savepattloop
                lda #$02
                jsr close               ;We're done!
                jsr clrchn

                lda #$0f                ;Now print JSR address information
                sta textcolor           ;for the elite-coder!
                ldx #$00
                ldy #18
                jsr setxy
                ldx #<packmsg1
                ldy #>packmsg1
                jsr printtext
                inc cursory
                ldx #<packmsg2
                ldy #>packmsg2
                jsr printtext
                inc cursory
                ldx #<packmsg3
                ldy #>packmsg3
                jsr printtext
                ldx #$05
                ldy #18
                jsr setxy
                lda relocadrlo
                ldx relocadrhi
                jsr printhex16
                clc
                lda relocadrlo
                adc #$03
                sta trklo
                lda relocadrhi
                adc #$00
                tax
                lda trklo
                inc cursory
                jsr printhex16
                clc
                lda relocadrlo
                adc #$06
                sta trklo
                lda relocadrhi
                adc #$00
                tax
                lda trklo
                inc cursory
                jsr printhex16
                jsr waitkey
                jmp editmusic

saveblock:      ldy #$00
                lda (trklo),y
                jsr save_sendbyte
                inc trklo
                bne saveblock2
                inc trkhi
saveblock2:     dec destlo
                lda destlo
                cmp #$ff
                bne saveblock3
                dec desthi
saveblock3:     lda destlo
                ora desthi
                bne saveblock
                rts



relocadrlo:     dc.b 0
relocadrhi:     dc.b 0
songtbladrlo:   dc.b 0
songtbladrhi:   dc.b 0
patttbladrlo:   dc.b 0
patttbladrhi:   dc.b 0
sndtbladrlo:    dc.b 0
sndtbladrhi:    dc.b 0
arptbladrlo:    dc.b 0
arptbladrhi:    dc.b 0
wavtbladrlo:    dc.b 0
wavtbladrhi:    dc.b 0
arpchtbladrlo:  dc.b 0
arpchtbladrhi:  dc.b 0
packtrkadrlo:   dc.b 0,0,0
packtrkadrhi:   dc.b 0,0,0
pattadrlo:      dc.b 0
pattadrhi:      dc.b 0
songendadrlo:   dc.b 0
songendadrhi:   dc.b 0



numbersnd:      dc.b 0
numbersong:     dc.b 0
numberpatt:     dc.b 0
lengtharp:      dc.b 0
lengthwav:      dc.b 0
lengthtrklo:    dc.b 0,0,0
lengthtrkhi:    dc.b 0,0,0
lengthpatt:     ds.b 160,0


askname:        lda #$00
                sta namelength
                ldx #$0f
                lda #$20
askname1:       sta name,x
                dex
                bpl askname1
                ldx #2
                ldy #15
                jsr setxy
                ldx #<asknametext
                ldy #>asknametext
                jsr printtext
asknameloop:    ldx #2
                ldy #16
                jsr setxy
                ldx #<name
                ldy #>name
                jsr printtext
                lda #$20
                sta $400+16*40+18
                ldx namelength
                lda $400+16*40+2,x
                ora #$c0
                sta $400+16*40+2,x
                jsr getkey
                cmp #13
                beq askname_end
                cmp #KEY_DEL
                bne askname_nodel
                lda namelength
                beq asknameloop
                dec namelength
                ldx namelength
                lda #$20
                sta name,x
                jmp asknameloop
askname_nodel:  cmp #$20
                bcc asknameloop
                and #$3f
                ldx namelength
                cpx #$10
                bcs asknameloop
                sta name,x
                inc namelength
                jmp asknameloop
askname_end:    ldx #$0f
askname_final:  lda name,x
                cmp #$20
                bcs askname_final2
                ora #$40
                sta name,x
askname_final2: dex
                bpl askname_final
                rts

scratch:        dc.b "S0:"
name:           dc.b "                ",0
namelength:     dc.b 0
drivenumber:    dc.b 8

confirm:        lda #$00
                sta bgcolor
                lda #$07
                sta textcolor
                ldx #0
                ldy #22
                jsr setxy
                ldx #<confirmtext
                ldy #>confirmtext
                jsr printtext
                jsr getkey
                pha
                lda #$20
                ldx #39
confirm2:       sta $400+22*40,x
                dex
                bpl confirm2
                pla
                rts


getkey:         jsr printrasterinfo
                jsr scnkey
                jsr getin
                cmp #$00
                bne getkey_done
                jsr getkey_delay
                jmp getkey
getkey_done:    rts

getkey_delay:   ldy #4
gkd1:           ldx #$ff
gkd2:           dex
                bne gkd2
                dey
                bne gkd1
                rts

waitkey:        jsr getkey_delay
                jsr getkey_delay
                jsr scnkey
                jsr getin
                cmp #$00
                beq waitkey
                rts

printsoundscreen:jsr clearscreen
                jsr printlogo
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #0
                ldy #4
                jsr setxy
                ldx #<soundnumtext
                ldy #>soundnumtext
                jsr printtext
                ldx #21
                ldy #3
                jsr setxy
                ldx #<arptbltext
                ldy #>arptbltext
                jsr printtext
                lda #28
                sta cursorx
                ldx #<wavetbltext
                ldy #>wavetbltext
                jsr printtext
                lda #35
                sta cursorx
                ldx #<arpchgtbltext
                ldy #>arpchgtbltext
                jsr printtext
                lda #$00
                sta bgcolor
                lda #$0f
                sta textcolor
                ldx #0
                ldy #6
                jsr setxy
                lda #<soundattrtext
                sta textlo
                lda #>soundattrtext
                sta texthi
pss_loop:       jsr printtextcont
                inc cursory
                lda cursory
                cmp #14+6
                bcc pss_loop
                ldx #$00
pss_loop2:      jsr printsndtrack
                inx
                cpx #$04
                bcc pss_loop2
                jsr printsonginfo
                jsr preparereginfo
                jsr printrasterinfo
                rts

printsndtrack:  cpx #$00
                bne printsndtrack2
                jmp printsoundinfo
printsndtrack2: stx storex
                lda #$05
                sta cursory
                lda sndeditview,x
                sta storey
                lda sndeditadrlo,x
                sta trklo
                lda sndeditadrhi,x
                sta trkhi
pst_loop:       lda #$00
                sta bgcolor
                lda #$0f
                sta textcolor
                ldx storex
                lda sndeditpos,x
                cmp storey
                bne pst_nowhite
                lda #$01
                sta textcolor
pst_nowhite:    sec
                lda sndeditxpos,x
                sbc #$03
                sta cursorx
                clc
                lda storey
                jsr printhex8
                clc
                lda cursorx
                adc #$03
                sta cursorx
                lda #$0c
                sta textcolor
                ldy storey
                lda (trklo),y
                jsr printhex8

                ldx storex
                cpx sndeditmode
                bne pst_nocursor
                sec
                lda sndeditpos,x
                sbc sndeditview,x
                clc
                adc #$05
                tay
                clc
                lda sndeditxpos,x
                adc sndeditcpos,x
                adc rowtbllo,y
                sta destlo
                lda rowtblhi,y
                adc #$00
                sta desthi
                ldy #$00
                lda (destlo),y
                ora #$c0
                sta (destlo),y
pst_nocursor:   inc storey
                inc cursory
                lda cursory
                cmp #5+16
                bcc pst_loop
                ldx storex
                rts

printsoundinfo: stx storex
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #13
                ldy #4
                jsr setxy
                lda soundnum
                jsr printhex8
                lda #$00
                sta bgcolor
                lda #$0c
                sta textcolor
                clc
                lda #<snd_ad
                adc soundnum
                sta trklo
                lda #>snd_ad
                adc #$00
                sta trkhi
                ldx #16
                ldy #6
                jsr setxy
psi_loop:       ldy #$00
                lda (trklo),y
                jsr printhex8
                clc
                lda trklo
                adc #$20
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                inc cursory
                lda cursory
                cmp #14+6
                bcc psi_loop
                lda sndeditmode
                bne psi_nocursor
                clc
                lda sndeditpos
                adc #$06
                tay
                clc
                lda #16
                adc sndeditcpos
                adc rowtbllo,y
                sta destlo
                lda rowtblhi,y
                adc #$00
                sta desthi
                ldy #$00
                lda (destlo),y
                ora #$c0
                sta (destlo),y
psi_nocursor:   ldx storex
                rts

printlogo:      ldx #0
                ldy #0
                jsr setxy
                lda #$80
                sta bgcolor
                lda #$07
                sta textcolor
                ldx #<titletext
                ldy #>titletext
                jsr printtext
                rts

printmainscreen:jsr clearscreen
                jsr printlogo
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                lda #"1"
                sta chantext+7
                ldx #0
                ldy #1
                jsr setxy
pms_chloop:     ldx #<chantext
                ldy #>chantext
                jsr printtext
                inc chantext+7
                lda cursorx
                clc
                adc #10
                sta cursorx
                cmp #30
                bcc pms_chloop
                ldx #<patttext
                ldy #>patttext
                jsr printtext
                jsr selectpattern
                ldx #0
pms_trkloop:    jsr printtrack
                inx
                cpx #4
                bne pms_trkloop
                jsr printsonginfo
                jsr preparereginfo
                jsr printrasterinfo
                rts

preparereginfo: ldx #39
                ldy #$0d
pri_loop:       lda pricols,y
                sta $d800+24*40,x
                dey
                bpl pri_notover
                ldy #$0d
pri_notover:    dex
                bpl pri_loop
                rts
pricols:        dc.b 0,0,1,1,1,1,7,7,1,1,7,7,7,7

printsonginfo:  ldx #0
                ldy #23
                jsr setxy
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #<songtext
                ldy #>songtext
                jsr printtext
                lda #5
                sta cursorx
                lda songnum
                jsr printhex8
                lda #8
                sta cursorx
                lda #$00
                sta bgcolor
                lda #$0f
                sta textcolor
                ldx #<songtext2
                ldy #>songtext2
                jsr printtext
                lda #14
                sta cursorx
                lda #$0c
                sta textcolor
                lda songnum
                asl
                sta storey
                asl
                adc storey
                sta storey
                tay
                lda songtbl+1,y
                and #$07
                tax
                lda songtbl,y
                jsr converthex16
                ldx #<(hexstring+1)
                ldy #>(hexstring+1)
                jsr printtext
                lda #18
                sta cursorx
                ldy storey
                lda songtbl+3,y
                and #$07
                tax
                lda songtbl+2,y
                jsr converthex16
                ldx #<(hexstring+1)
                ldy #>(hexstring+1)
                jsr printtext
                lda #22
                sta cursorx
                ldy storey
                lda songtbl+5,y
                and #$07
                tax
                lda songtbl+4,y
                jsr converthex16
                ldx #<(hexstring+1)
                ldy #>(hexstring+1)
                jsr printtext
                rts

printrasterinfo:ldx #26
                ldy #23
                jsr setxy
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #<rastertext
                ldy #>rastertext
                jsr printtext
                lda #33
                sta cursorx
                lda #$00
                sta bgcolor
                lda #$0f
                sta textcolor
                ldx #<rastertext1
                ldy #>rastertext1
                jsr printtext
                lda #37
                sta cursorx
                ldx #<rastertext2
                ldy #>rastertext2
                jsr printtext
                lda #34
                sta cursorx
                lda #$0c
                sta textcolor
                lda curraster
                jsr printhex8
                lda #38
                sta cursorx
                lda maxraster
                jsr printhex8
                ldx #$00
                ldy #$00
printregloop:   lda chn_freqhi,x
                jsr printhexfast
                lda chn_freqlo,x
                jsr printhexfast
                ldx storex
                lda chn_pulsehi,x
                asl
                asl
                asl
                asl
                sta storea
                lda chn_pulselo,x
                lsr
                lsr
                lsr
                lsr
                ora storea
                jsr printhexfast
                lda chn_wave,x
                jsr printhexfast
                lda chn_ad,x
                jsr printhexfast
                lda chn_sr,x
                jsr printhexfast
                iny
                iny
                inx
                cpx #$03
                beq prl_done
                jmp printregloop
prl_done:       rts

printhexfast:   sta storea
                stx storex
                lsr
                lsr
                lsr
                lsr
                tax
                lda hexcodes,x
                and #$3f
                ora #$80
                sta $0400+24*40,y
                iny
                lda storea
                and #$0f
                tax
                lda hexcodes,x
                and #$3f
                ora #$80
                sta $0400+24*40,y
                iny
                ldx storex
                rts

selectpattern:  ldy pattnum
                lda patttbllo,y
                sta trackadrlo+3
                lda patttblhi,y
                sta trackadrhi+3
                lda #$40
                sta bgcolor
                lda #$0d
                sta textcolor
                ldx #38
                ldy #1
                jsr setxy
                lda pattnum
                jsr printhex8
                rts

printpattern:   ldx storex
                lda trackxpos,x
                sta cursorx
                lda #$0f
                sta textcolor
                lda trklo
                and #$7f
                cmp trackposlo,x
                bne ppt_notwhite
                lda #$01
                sta textcolor
                lda trklo
ppt_notwhite:   and #$7f
                jsr printhex8
                clc
                lda cursorx
                adc #$03
                sta cursorx
                lda #$0c
                sta textcolor
                ldy #$00
                lda (trklo),y
ppt_special:    cmp pptspecial,y
                bne ppt_spnext
ppt_spfound:    lda pptspechi,y
                ldx pptspeclo,y
                tay
                jsr printtext
                jmp ppt_next
ppt_spnext:     iny
                cpy #$07
                bne ppt_special
                cmp #ARP
                bcs ppt_notnote
                jmp ppt_note
ppt_notnote:    cmp #SND
                bcc ppt_arp
                bcs ppt_notarp
ppt_arp:        ldx #<arptext
                ldy #>arptext
                jsr printtext
ppt_print4:     clc
                lda cursorx
                adc #$03
                sta cursorx
                ldy #$00
                lda (trklo),y
                and #$0f
                jsr printhex8
                jmp ppt_next
ppt_notarp:     cmp #SLIDE
                bcc ppt_snd
                cmp #DUR
                bcs ppt_dur
ppt_slide:      ldx #<slidetext
                ldy #>slidetext
                jsr printtext
                jmp ppt_print4
ppt_snd:        ldx #<sndtext
                ldy #>sndtext
                jsr printtext
                clc
                lda cursorx
                adc #$03
                sta cursorx
                ldy #$00
                lda (trklo),y
                and #$1f
                jsr printhex8
                jmp ppt_next
ppt_dur:        ldx #<durtext
                ldy #>durtext
                jsr printtext
                clc
                lda cursorx
                adc #$03
                sta cursorx
                ldy #$00
                sec
                lda (trklo),y
                sbc #DUR
                jsr printhex8
                jmp ppt_next
ppt_note:       tay
                clc
                lda octavetable,y
                adc #"0"
                sta notestring+2
                ldy #$00
                lda (trklo),y
                tay
                lda notetable,y
                asl
                tay
                lda notename,y
                sta notestring
                lda notename+1,y
                sta notestring+1
                ldx #<notestring
                ldy #>notestring
                jsr printtext
ppt_next:       ldx storex
                cpx editmode
                bne ppt_nocursor
                lda trklo
                and #$7f
                cmp trackposlo,x
                bne ppt_nocursor
                ldy cursory
                clc
                lda #$03
                adc trackxpos,x
                adc editcpos
                adc rowtbllo,y
                sta destlo
                lda rowtblhi,y
                adc #$00
                sta desthi
                ldy #$00
                lda (destlo),y
                ora #$c0
                sta (destlo),y
ppt_nocursor:   ldy #$00
                lda (trklo),y
                cmp #ENDPATT
                beq ppt_restempty
                inc trklo
                bne ppt_nothigh
                inc trkhi
ppt_nothigh:    inc cursory
                lda cursory
                cmp #22
                bcs ppt_ready
                jmp printpattern
ppt_ready:      ldx storex
                rts
ppt_restempty:  inc cursory
                ldx storex
                lda trackxpos,x
                sta cursorx
ppt_emptyloop:  ldx #<emptytext
                ldy #>emptytext
                jsr printtext
                inc cursory
                lda cursory
                cmp #22
                bcc ppt_emptyloop
                ldx storex
                rts

nukeall:        jsr nukepatt
                jsr nuketrack
                lda #$00
                ldx #$03
nukeresetpos:   sta trackposlo,x
                sta trackposhi,x
                sta trackviewlo,x
                sta trackviewhi,x
                dex
                bpl nukeresetpos
                lda #$00
                tax
nukesongs:      lda #<CHAN1
                sta songtbl,x
                lda #>CHAN1
                sta songtbl+1,x
                lda #<CHAN2
                sta songtbl+2,x
                lda #>CHAN2
                sta songtbl+3,x
                lda #<CHAN3
                sta songtbl+4,x
                lda #>CHAN3
                sta songtbl+5,x
                inx
                inx
                inx
                inx
                inx
                inx
                cpx #32*2*3
                bcc nukesongs
                ldx #253
                lda #$00
nukeresetarp:   sta arptbl,x
                sta wavetbl,x
                cpx #$10
                bcs nra_toobig
                sta arpchgtbl,x
nra_toobig:     dex
                cpx #$ff
                bne nukeresetarp
                lda #$fe
                sta arptbl+1
                sta wavetbl+1
                lda #$21
                sta wavetbl
nukesnd:        lda #$00
                tax
nukesnd1:       sta snd_ad,x
                sta snd_sr,x
                sta snd_pulse,x
                sta snd_pulsespd,x
                sta snd_pulselimit,x
                sta snd_vibdelay,x
                sta snd_vibdepth,x
                sta snd_arppos,x
                sta snd_wavepos,x
                sta snd_filtctrl,x
                sta snd_filtcutoff,x
                sta snd_filtspd,x
                sta snd_filttime1,x
                sta snd_filttime2,x
                inx
                cpx #$20
                bne nukesnd1
                rts

nuketrack:      lda #<CHAN1
                sta trklo
                lda #>CHAN1
                sta trkhi
                ldy #$00
                lda #RESTART
nuketrack1:     sta (trklo),y
                iny
                bne nuketrack1
                inc trkhi
                ldx trkhi
                cpx #>PATTERNS
                bcc nuketrack1
                lda #$00
                sta CHAN1
                sta CHAN2
                sta CHAN3
                rts

nukepatt:       lda #<PATTERNS
                sta trklo
                lda #>PATTERNS
                sta trkhi
nukepattloop:   lda #ENDPATT
                ldy #$00
nukepatt1:      sta (trklo),y
                iny
                bpl nukepatt1
                clc
                lda trklo
                adc #$80
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                lda trkhi
                cmp #$a8
                bcc nukepattloop
                lda #DUR+64
                sta PATTERNS
                lda #REST
                sta PATTERNS+1
                rts

octavetable:    dc.b 0,0,0,0,0,0,0,0,0,0,0,0
                dc.b 1,1,1,1,1,1,1,1,1,1,1,1
                dc.b 2,2,2,2,2,2,2,2,2,2,2,2
                dc.b 3,3,3,3,3,3,3,3,3,3,3,3
                dc.b 4,4,4,4,4,4,4,4,4,4,4,4
                dc.b 5,5,5,5,5,5,5,5,5,5,5,5
                dc.b 6,6,6,6,6,6,6,6,6,6,6,6
notetable:      dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11
                dc.b 0,1,2,3,4,5,6,7,8,9,10,11

octavemultable: dc.b 0*12
                dc.b 1*12
                dc.b 2*12
                dc.b 3*12
                dc.b 4*12
                dc.b 5*12
                dc.b 6*12

notename:       dc.b "C-C#D-D#E-F-F#G-G#A-A#H-"
notestring:     dc.b "C-0  ",0
pptspecial:     dc.b TIEOFF,TIEON,NOPULSEINIT,TIENOPULSEINIT,REST,CONT,ENDPATT
pptspeclo:      dc.b <ps1,<ps2,<ps3,<ps4,<ps5,<ps6,<ps7
pptspechi:      dc.b >ps1,>ps2,>ps3,>ps4,>ps5,>ps6,>ps7
ps1:            dc.b "G+ P+",0
ps2:            dc.b "G- P+",0
ps3:            dc.b "G+ P-",0
ps4:            dc.b "G- P-",0
ps5:            dc.b "REST ",0
ps6:            dc.b "CONT ",0
ps7:            dc.b "ENDPT",0

printtrack:     lda #$02
                sta cursory
                stx storex
                lda #$00
                sta bgcolor
                clc
                lda trackadrlo,x
                adc trackviewlo,x
                sta trklo
                lda trackadrhi,x
                adc trackviewhi,x
                sta trkhi
                cpx #$03
                bne ptr_loop
                jmp printpattern
ptr_loop:       ldx storex
                lda trackxpos,x
                sta cursorx
                lda #$0f
                sta textcolor
                lda trklo
                cmp trackposlo,x
                bne ptr_notwhite
                lda trkhi
                and #$07
                cmp trackposhi,x
                bne ptr_notwhite
                lda #$01
                sta textcolor
ptr_notwhite:   lda trkhi
                and #$07
                tax
                lda trklo
                jsr converthex16
                ldx #<(hexstring+1)
                ldy #>(hexstring+1)
                jsr printtext
                lda #$0c
                sta textcolor
                clc
                lda cursorx
                adc #$04
                sta cursorx
                ldy #$00
                lda (trklo),y
                sta storea
                cmp #REPEAT
                bcc ptr_pattern
                cmp #ENDSONG
                beq ptr_endsong
                bcs ptr_restart
                cmp #TRSTART
                bcs ptr_trans
ptr_repeat:     ldx #<reptext
                ldy #>reptext
                jsr printtext
                clc
                lda cursorx
                adc #$03
                sta cursorx
                sec
                lda storea
                sbc #REPEAT
                and #$1f
                jsr printhex8
                jmp ptr_next
ptr_trans:      ldx #<trtext
                ldy #>trtext
                jsr printtext
                clc
                lda cursorx
                adc #$03
                sta cursorx
                sec
                lda storea
                sbc #TRSTART
                and #$3f
                jsr printhex8
                jmp ptr_next
ptr_endsong:    ldx #<endtext
                ldy #>endtext
                jsr printtext
                jmp ptr_next
ptr_restart:    ldx #<restext
                ldy #>restext
                jsr printtext
                jmp ptr_next
ptr_pattern:    jsr printhex8
                clc
                lda cursorx
                adc #$02
                sta cursorx
                ldx #<emptytxt
                ldy #>emptytxt
                jsr printtext
ptr_next:       ldx storex
                cpx editmode
                bne ptr_nocursor
                lda trklo
                cmp trackposlo,x
                bne ptr_nocursor
                lda trkhi
                and #$07
                cmp trackposhi,x
                bne ptr_nocursor
                ldy cursory
                clc
                lda #$04
                adc trackxpos,x
                adc editcpos
                adc rowtbllo,y
                sta destlo
                lda rowtblhi,y
                adc #$00
                sta desthi
                ldy #$00
                lda (destlo),y
                ora #$c0
                sta (destlo),y
ptr_nocursor:   inc cursory
                inc trklo
                bne ptr_nohigh
                inc trkhi
ptr_nohigh:     lda cursory
                cmp #22
                bcs ptr_ready
                jmp ptr_loop
ptr_ready:      ldx storex
                rts

sndeditmode:    dc.b 0
sndeditcpos:    dc.b 0,0,0,0
sndeditpos:     dc.b 0,0,0,0
sndeditview:    dc.b 0,0,0,0
sndeditlimit:   dc.b 0,253,253,15
sndeditxpos:    dc.b 16,24,31,38
sndeditadrlo:   dc.b <snd_ad,<arptbl,<wavetbl,<arpchgtbl
sndeditadrhi:   dc.b >snd_ad,>arptbl,>wavetbl,>arpchgtbl

pattcopybuf:    ds.b 256,ENDPATT
sndcopybuf:     ds.b 14,0

firsttime:      dc.b 0
editmode:       dc.b 0
editcpos:       dc.b 0,0,0
note:           dc.b 0
octave:         dc.b 0
pattnum:        dc.b 0
soundnum:       dc.b 0
songnum:        dc.b 0
fastfwd:        dc.b 0
hexdigit:       dc.b 0
curraster:      dc.b 0
maxraster:      dc.b 0

trackxpos:      dc.b 0,10,20,30
trackadrlo:     dc.b <CHAN1,<CHAN2,<CHAN3,<PATTERNS
trackadrhi:     dc.b >CHAN1,>CHAN2,>CHAN3,>PATTERNS
trackviewlo:    dc.b 0,0,0,0
trackviewhi:    dc.b 0,0,0,0
trackposlo:     dc.b 0,0,0,0
trackposhi:     dc.b 0,0,0,0

trkeditkeytbl:  dc.b KEY_F1
                dc.w tr_nexttrack
                dc.b KEY_F3
                dc.w gotosound
                dc.b KEY_F5
                dc.w diskmenu
                dc.b KEY_F7
                dc.w help
                dc.b KEY_UP
                dc.w tr_moveup
                dc.b KEY_DOWN
                dc.w tr_movedown
                dc.b KEY_LEFT
                dc.w tr_moveleft
                dc.b KEY_RIGHT
                dc.w tr_moveright
                dc.b "X"+$80
                dc.w tr_movedownfast
                dc.b "Z"+$80
                dc.w tr_moveupfast
                dc.b "S"+$80
                dc.w tr_setsongstart
                dc.b "G"+$80
                dc.w tr_gosongstart
                dc.b 13
                dc.w tr_gotopatt
                dc.b ","
                dc.w tr_prevsong
                dc.b "."
                dc.w tr_nextsong
                dc.b ":"
                dc.w tr_prevpatt
                dc.b ";"
                dc.w tr_nextpatt
                dc.b " "
                dc.w tr_playstop
                dc.b " "+$80
                dc.w tr_fastforward
                dc.b $21
                dc.w tr_repeat
                dc.b $22
                dc.w tr_trans
                dc.b $23
                dc.w tr_restart
                dc.b KEY_INS
                dc.w tr_ins
                dc.b KEY_DEL
                dc.w tr_del
                dc.b $24
                dc.w tr_endsong
                dc.b $ff

patteditkeytbl: dc.b KEY_F1
                dc.w tr_nexttrack
                dc.b KEY_F3
                dc.w gotosound
                dc.b KEY_F5
                dc.w diskmenu
                dc.b KEY_F7
                dc.w help
                dc.b "N"+$80
                dc.w pt_nukepatt
                dc.b ","
                dc.w tr_prevsong
                dc.b "."
                dc.w tr_nextsong
                dc.b ":"
                dc.w tr_prevpatt
                dc.b ";"
                dc.w tr_nextpatt
                dc.b " "
                dc.w tr_playstop
                dc.b KEY_UP
                dc.w pt_moveup
                dc.b KEY_DOWN
                dc.w pt_movedown
                dc.b KEY_LEFT
                dc.w pt_moveleft
                dc.b KEY_RIGHT
                dc.w pt_moveright
                dc.b " "+$80
                dc.w tr_fastforward
                dc.b $21
                dc.w pt_snd
                dc.b $22
                dc.w pt_arp
                dc.b $23
                dc.w pt_dur
                dc.b $24
                dc.w pt_slide
                dc.b $25
                dc.w pt_pulsetie
                dc.b "R"
                dc.w pt_rest
                dc.b "R"+$80
                dc.w pt_cont
                dc.b KEY_INS
                dc.w pt_ins
                dc.b KEY_DEL
                dc.w pt_del
                dc.b "X"+$80
                dc.w pt_movedownfast
                dc.b "Z"+$80
                dc.w pt_moveupfast
                dc.b "P"+$80
                dc.w pt_putpatt
                dc.b "T"+$80
                dc.w pt_takepatt
                dc.b $ff

sndeditkeytbl:  dc.b KEY_F3
                dc.w gotomusic
                dc.b KEY_F1
                dc.w es_nexttrack
                dc.b KEY_F5
                dc.w diskmenu
                dc.b KEY_F7
                dc.w help
                dc.b KEY_UP
                dc.w es_moveup
                dc.b KEY_DOWN
                dc.w es_movedown
                dc.b KEY_LEFT
                dc.w es_moveleft
                dc.b KEY_RIGHT
                dc.w es_moveright
                dc.b KEY_INS
                dc.w es_ins
                dc.b KEY_DEL
                dc.w es_del
                dc.b ","
                dc.w tr_prevsong
                dc.b "."
                dc.w tr_nextsong
                dc.b ":"
                dc.w es_prevsnd
                dc.b ";"
                dc.w es_nextsnd
                dc.b " "
                dc.w tr_playstop
                dc.b " "+$80
                dc.w tr_fastforward
                dc.b "P"+$80
                dc.w es_putsnd
                dc.b "T"+$80
                dc.w es_takesnd
                dc.b $ff

initpatttbl:    ldx #$00
                lda #<PATTERNS
                sta trklo
                lda #>PATTERNS
                sta trkhi
ipt_loop:       lda trklo
                sta patttbllo,x
                lda trkhi
                sta patttblhi,x
                clc
                lda trklo
                adc #$80
                sta trklo
                lda trkhi
                adc #$00
                sta trkhi
                inx
                cpx #$a0
                bcc ipt_loop
                rts

initscreen:     lda #$00
                sta $d020
                sta $d021
                lda #$0b
                sta $d022
                lda #$0c
                sta $d023
                lda #$03
                sta $dd00
                lda #$08
                sta $d016
                lda #$5b                ;Extended colormode
                sta $d011
                lda #$1e
                sta $d018               ;Switch "own" charset
                lda #$ff
                sta 650
clearscreen:    lda #$20
                ldx #$00
is_loop:        sta $0400,x
                sta $0500,x
                sta $0600,x
                sta $0700,x
                inx
                bne is_loop
                rts

        ;X=xposition, Y=yposition
setxy:          stx cursorx
                sty cursory
                rts

        ;X=text address lo, Y=text address hi
printtext:      stx textlo
                sty texthi
printtextcont:  ldx cursory
                clc
                lda rowtbllo,x
                adc cursorx
                sta destlo
                lda rowtblhi,x
                adc #$00
                sta desthi
                ldy #$00
pt_loop:        lda (textlo),y
                beq pt_done
                and #$3f
                ora bgcolor
                sta (destlo),y
                clc
                lda desthi
                adc #$d4
                sta desthi
                lda textcolor
                sta (destlo),y
                sec
                lda desthi
                sbc #$d4
                sta desthi
                iny
                jmp pt_loop
pt_done:        iny
                tya
                clc
                adc textlo
                sta textlo
                lda texthi
                adc #$00
                sta texthi
                rts

cursorx:        dc.b 0
cursory:        dc.b 0
bgcolor:        dc.b 0
textcolor:      dc.b 1

rowtbllo:
N               SET 0
                REPEAT 25
                dc.b <($400+40*N)
N               SET N+1
                REPEND

rowtblhi:
N               SET 0
                REPEAT 25
                dc.b >($400+40*N)
N               SET N+1
                REPEND

        ;A=hex value
printhex8:      ldy #2
                jsr converthex8
                ldx #<(hexstring+2)
                ldy #>(hexstring+2)
                jsr printtext
                rts

        ;A=hex value lo, X=hex value hi
printhex16:     jsr converthex16
                ldx #<hexstring
                ldy #>hexstring
                jsr printtext
                rts

converthex16:   stx hexvalue2
                ldy #2
                jsr converthex8
                ldy #0
                lda hexvalue2
                jsr converthex8
                rts

converthex8:    sta hexvalue
                lsr
                lsr
                lsr
                lsr
                tax
                lda hexcodes,x
                sta hexstring,y
                lda hexvalue
                and #$0f
                tax
                lda hexcodes,x
                sta hexstring+1,y
                rts

hexvalue:       dc.b 0
hexvalue2:      dc.b 0

hexstring:      dc.b "0000",0
hexcodes:       dc.b "0123456789ABCDEF",0


        ;A table for all C64 instructions. 3 byte long instructions contain an
        ;absolute address and must be relocated.

asmtable:       .byte $69,2 ;ADC immediate
                .byte $65,2 ;ADC zeropage
                .byte $75,2 ;ADC zeropage,X
                .byte $6d,3 ;ADC absolute
                .byte $7d,3 ;ADC absolute,X
                .byte $79,3 ;ADC absolute,Y
                .byte $61,2 ;ADC indirect,X
                .byte $71,2 ;ADC indirect,Y

                .byte $29,2 ;AND immediate
                .byte $25,2 ;AND zeropage
                .byte $35,2 ;AND zeropage,X
                .byte $2d,3 ;AND absolute
                .byte $3d,3 ;AND absolute,X
                .byte $39,3 ;AND absolute,Y
                .byte $21,2 ;AND indirect,X
                .byte $31,2 ;AND indirect,Y

                .byte $0a,1 ;ASL accumulator
                .byte $06,2 ;ASL zeropage
                .byte $16,2 ;ASL zeropage,X
                .byte $0e,3 ;ASL absolute
                .byte $1e,3 ;ASL absolute,X
                .byte $90,2 ;BCC
                .byte $b0,2 ;BCS
                .byte $f0,2 ;BEQ

                .byte $24,2 ;BIT zeropage
                .byte $2c,3 ;BIT absolute
                .byte $30,2 ;BMI
                .byte $d0,2 ;BNE
                .byte $10,2 ;BPL
                .byte $00,1 ;BRK
                .byte $50,2 ;BVC
                .byte $70,2 ;BVS

                .byte $18,1 ;CLC
                .byte $d8,1 ;CLD
                .byte $58,1 ;CLI
                .byte $b8,1 ;CLV
                .byte $c9,2 ;CMP immediate
                .byte $c5,2 ;CMP zeropage
                .byte $d5,2 ;CMP zeropage,X
                .byte $cd,3 ;CMP absolute

                .byte $dd,3 ;CMP absolute,X
                .byte $d9,3 ;CMP absolute,Y
                .byte $c1,2 ;CMP indirect,X
                .byte $d1,2 ;CMP indirect,Y
                .byte $e0,2 ;CPX immediate
                .byte $e4,2 ;CPX zeropage
                .byte $ec,3 ;CPX absolute
                .byte $c0,2 ;CPY immediate

                .byte $c4,2 ;CPY zeropage
                .byte $cc,3 ;CPY absolute
                .byte $c6,2 ;DEC zeropage
                .byte $d6,2 ;DEC zeropage,X
                .byte $ce,3 ;DEC absolute
                .byte $de,3 ;DEC absolute,X
                .byte $ca,1 ;DEX
                .byte $88,1 ;DEY

                .byte $49,2 ;EOR immediate
                .byte $45,2 ;EOR zeropage
                .byte $55,2 ;EOR zeropage,X
                .byte $4d,3 ;EOR absolute
                .byte $5d,3 ;EOR absolute,X
                .byte $59,3 ;EOR absolute,Y
                .byte $41,2 ;EOR indirect,X
                .byte $51,2 ;EOR indirect,Y

                .byte $e6,2 ;INC zeropage
                .byte $f6,2 ;INC zeropage,X
                .byte $ee,3 ;INC absolute
                .byte $fe,3 ;INC absolute,X
                .byte $e8,1 ;INX
                .byte $c8,1 ;INY
                .byte $4c,3 ;JMP absolute
                .byte $6c,3 ;JMP indirect

                .byte $20,3 ;JSR absolute
                .byte $a9,2 ;LDA immediate
                .byte $a5,2 ;LDA zeropage
                .byte $b5,2 ;LDA zeropage,X
                .byte $ad,3 ;LDA absolute
                .byte $bd,3 ;LDA absolute,X
                .byte $b9,3 ;LDA absolute,Y
                .byte $a1,2 ;LDA indirect,X

                .byte $b1,2 ;LDA indirect,Y
                .byte $a2,2 ;LDX immediate
                .byte $a6,2 ;LDX zeropage
                .byte $b6,2 ;LDX zeropage,Y
                .byte $ae,3 ;LDX absolute
                .byte $be,3 ;LDX absolute,Y
                .byte $a0,2 ;LDY immediate
                .byte $a4,2 ;LDY zeropage

                .byte $b4,2 ;LDY zeropage,Y
                .byte $ac,3 ;LDY absolute
                .byte $bc,3 ;LDY absolute,Y
                .byte $4a,1 ;LSR accumulator
                .byte $46,2 ;LSR zeropage
                .byte $56,2 ;LSR zeropage,X
                .byte $4e,3 ;LSR absolute
                .byte $5e,3 ;LSR absolute,X

                .byte $ea,1 ;NOP
                .byte $09,2 ;ORA immediate
                .byte $05,2 ;ORA zeropage
                .byte $15,2 ;ORA zeropage,X
                .byte $0d,3 ;ORA absolute
                .byte $1d,3 ;ORA absolute,X
                .byte $19,3 ;ORA absolute,Y
                .byte $01,2 ;ORA indirect,X

                .byte $11,2 ;ORA indirect,Y
                .byte $48,1 ;PHA
                .byte $08,1 ;PHP
                .byte $68,1 ;PLA
                .byte $28,1 ;PLP
                .byte $2a,1 ;ROL accumulator
                .byte $26,2 ;ROL zeropage

                .byte $36,2 ;ROL zeropage,X
                .byte $2e,3 ;ROL absolute
                .byte $3e,3 ;ROL absolute,X
                .byte $6a,1 ;ROR accumulator
                .byte $66,2 ;ROR zeropage
                .byte $76,2 ;ROR zeropage,X
                .byte $6e,3 ;ROR absolute
                .byte $7e,3 ;ROR absolute,X

                .byte $40,1 ;RTI
                .byte $60,1 ;RTS
                .byte $e9,2 ;SBC immediate
                .byte $e5,2 ;SBC zeropage
                .byte $f5,2 ;SBC zeropage,X
                .byte $ed,3 ;SBC absolute
                .byte $fd,3 ;SBC absolute,X
                .byte $f9,3 ;SBC absolute,Y

                .byte $e1,2 ;SBC indirect,X
                .byte $f1,2 ;SBC indirect,Y
                .byte $38,1 ;SEC
                .byte $f8,1 ;SED
                .byte $78,1 ;SEI
                .byte $85,2 ;STA zeropage
                .byte $95,2 ;STA zeropage,X
                .byte $8d,3 ;STA absolute

                .byte $9d,3 ;STA absolute,X
                .byte $99,3 ;STA absolute,Y
                .byte $81,2 ;STA indirect,X
                .byte $91,2 ;STA indirect,Y
                .byte $86,2 ;STX zeropage
                .byte $96,2 ;STX zeropage,Y
                .byte $8e,3 ;STX absolute
                .byte $84,2 ;STY zeropage

                .byte $94,2 ;STY zeropage,X
                .byte $8c,3 ;STY absolute
                .byte $aa,1 ;TAX
                .byte $a8,1 ;TAY
                .byte $ba,1 ;TSX
                .byte $8a,1 ;TXA
                .byte $9a,1 ;TXS
                .byte $98,1 ;TYA
                .byte $ff,0 ;Taulukon loppu



initraster:     sei
                lda #$7f
                sta $dc0d
                lda #$01
                sta $d01a
                lda #<raster
                sta $0314
                lda #>raster
                sta $0315
                lda #$32
                sta $d012
                lda $dc0d
                cli
                rts

raster:         inc $d019
                lda mus_play+1
                beq ras_noplay
                nop
                nop
                nop
                nop
                nop
                nop
                inc $d020
                jsr music+3
                dec $d020
                lda $d012
                sec
                sbc #$32
                sta curraster
                lda curraster
                cmp maxraster
                bcc ras_notmax
                sta maxraster
ras_notmax:     lda fastfwd
                beq ras_noplay
                dec fastfwd
                jsr music+3
                jsr music+3
                jsr music+3
ras_noplay:     lda cursorcolor
                and #$1f
                tax
                lda cursorcolortbl,x
                sta $d024
                inc cursorcolor
                jmp $ea81

cursorcolor:    dc.b 0
cursorcolortbl: dc.b 0,0,9,9,2,2,8,8
                dc.b 10,10,15,15,7,7,1,1
                dc.b 1,1,7,7,15,15,10,10
                dc.b 8,8,2,2,9,9,0,0

        ;Editor's music player
music:          jmp mus_init
                jmp mus_play
                jmp mus_stop

mus_init:       ldx #$00                        ;Set flag: don't play
                stx mus_play+1
                asl                             ;Multiply tune-number by 6
                sta temp1
                asl
                adc temp1
                tay
mus_initloop:   lda songtbl,y                   ;Set address of channel's
                sta chn_songlo,x                ;sequence data
                lda songtbl+1,y
                sta chn_songhi,x
                tya
                sta chn_songtblindex,x
                iny
                iny
                sty temp3
                lda #$00                        ;Reset duration, waveform,
                sta chn_pattrep,x               ;pattern position & channel
                sta chn_wave,x                  ;bits
                sta chn_bits,x
                sta chn_trans,x
                sta chn_counter,x
                jsr mus_getpattern
                ldy temp3
                inx                             ;All channels done?
                cpx #$03
                bne mus_initloop
                stx mus_play+1
                lda #$00
                sta mus_filtctrl+1
                lda #$0f
                sta mus_filttype+1
                rts

mus_stop:       lda #$00                        ;Set flag: don't play
                sta mus_play+1
                tax
mus_stoploop:   sta chn_wave,x
                ldy chn_regindex,x
                sta $d404,y
                inx
                cpx #$03
                bne mus_stoploop
                rts

mus_play:       lda #$00                        ;Check playflag
                bne mus_ok
                rts
mus_ok:         ldx #$00
mus_chnloop:    lda chn_counter,x               ;Time to get new note?
                bmi mus_initnote
                beq mus_newnote
                jmp mus_effects
mus_initnote:   lda chn_duration,x
                sec
                sbc #$01
                sta chn_counter,x
                ldy chn_snd,x                   ;Get soundnumber
                lda chn_bits,x                  ;Will we init pulse?
                and #PULSEBIT
                bne mus_nopulseinit
                lda snd_pulse,y
                sta chn_pulselo,x
                and #$0f
                sta chn_pulsehi,x
                lda #$00
                sta chn_pulsedir,x
mus_nopulseinit:lda #$00
                sta chn_vibdir,x
                lda snd_ad,y
                sta chn_ad,x
                lda snd_sr,y
                sta chn_sr,x
                lda snd_wavepos,y
                sta chn_wavepos,x
                lda chn_arpstart,x
                sta chn_arppos,x
                lda snd_filtctrl,y
                beq mus_nofiltinit
                and #$0f
                sta mus_filtctrl+1
                lda snd_filtctrl,y
                ora #$0f
                sta mus_filttype+1
                lda snd_filtcutoff,y
                sta mus_cutoffhi+1
                lda #$00
                sta mus_filttime+1
                sta mus_filtchoose+1
                sty mus_filtsnd+1
mus_nofiltinit: jmp mus_doarp

mus_newnote:    ldy chn_pattnum,x               ;Get address of pattern
                lda patttbllo,y
                sta temp1
                lda patttblhi,y
                sta temp2
                ldy chn_pattpos,x               ;And position within it
mus_newnoteloop:lda (temp1),y                   ;Load next command
                bmi mus_nnneg
                iny
                cmp #SND
                bcs mus_setsnd
                cmp #ARP
                bcs mus_setarp
                jmp mus_note
mus_setarp:     sbc #ARP
                sty temp3
                tay
                lda arpchgtbl,y
                sta chn_arpstart,x
                ldy temp3
                bne mus_newnoteloop
mus_setsnd:     sbc #SND
                sta chn_snd,x
                sty temp3
                tay
                lda snd_arppos,y
                sta chn_arpstart,x
                ldy temp3
                bne mus_newnoteloop
mus_nnneg:      iny
                cmp #REST
                bcs mus_rest
                cmp #DUR
                bcc mus_setslide
mus_setdur:     sbc #DUR
                sta chn_duration,x
                bne mus_newnoteloop
mus_setslide:   cmp #TIEOFF
                bcc mus_nosetbit
                and #$03
                sta chn_bits,x
                jmp mus_newnoteloop
mus_nosetbit:   sty temp3
                sbc #SLIDE-1
                jsr mus_calcfreq
                lda chn_bits,x
                ora #SLIDEBIT
                sta chn_bits,x
                ldy temp3
                lda (temp1),y
                clc
                adc chn_trans,x
                asl
                sta chn_note,x
                iny
mus_rest:       bne mus_contnote
                lda chn_wave,x
                and #$fe
                sta chn_wave,x
mus_contnote:   jsr mus_checkendpatt
                lda chn_duration,x
                sta chn_counter,x
                jmp mus_effects
mus_note:       clc
                adc chn_trans,x
                asl
                sta chn_note,x
                lda chn_bits,x
                and #TIEBIT
                bne mus_nohard
                lda #$00
                sta chn_wave,x
                sta chn_ad,x
                sta chn_sr,x
mus_nohard:     lda #$ff
                sta chn_counter,x
                jsr mus_checkendpatt
                jsr mus_vibinit
                jmp mus_nextchn
mus_checkendpatt:lda (temp1),y
                cmp #ENDPATT
                bne mus_noendpatt
                tay
mus_noendpatt:  tya
                sta chn_pattpos,x
                rts

mus_effects:    lda chn_wave,x
                bne mus_dopulse
                jmp mus_fxdone
mus_dopulse:    ldy chn_snd,x
                lda chn_pulsedir,x
                bmi mus_pulsedown
mus_pulseup:    lda snd_pulselimit,y
                and #$0f
                sta temp1
                lda chn_pulselo,x
                clc
                adc snd_pulsespd,y
                sta chn_pulselo,x
                bcc mus_punotover
                inc chn_pulsehi,x
mus_punotover:  lda chn_pulsehi,x
                cmp temp1
                bcc mus_doarp
mus_pulsedir:   lda chn_pulsedir,x
                eor #$80
                sta chn_pulsedir,x
                jmp mus_doarp
mus_pulsedown:  lda snd_pulselimit,y
                lsr
                lsr
                lsr
                lsr
                sta temp1
                lda chn_pulselo,x
                sec
                sbc snd_pulsespd,y
                sta chn_pulselo,x
                bcs mus_pdnotover
                dec chn_pulsehi,x
mus_pdnotover:  lda chn_pulsehi,x
                cmp temp1
                bcc mus_pulsedir
mus_doarp:      lda chn_arppos,x
                cmp #$fe
                bcs mus_dovib
mus_arpback:    tay
                inc chn_arppos,x
                lda arptbl,y
                bmi mus_absarp
                asl
                adc chn_note,x
mus_arpfreq:    tay
                lda freqtbl,y
                sta chn_freqlo,x
                lda freqtbl+1,y
                sta chn_freqhi,x
                jmp mus_dowave
mus_absarp:     cmp #$fe
                bcs mus_arpjump
                asl
                jmp mus_arpfreq
mus_arpjump:    beq mus_arpstop
                lda arptbl+1,y
                sta chn_arppos,x
                jmp mus_arpback
mus_arpstop:    sta chn_arppos,x
                jmp mus_dowave
mus_dovib:      lda chn_bits,x
                and #SLIDEBIT
                bne mus_doslide
                lda snd_vibdepth,y
                beq mus_novib
                lda chn_vibdelay,x
                bne mus_vibdelay
mus_novibdelay: lda chn_vibdir,x
                bmi mus_vibdown
mus_vibup:      jsr mus_frequp
                dec chn_vibtime,x
                beq mus_vibdir
                jmp mus_dowave
mus_vibdelay:   dec chn_vibdelay,x
mus_novib:      jmp mus_dowave
mus_vibdir:     lda snd_vibdepth,y
                and #$0f
                asl
                sta chn_vibtime,x
                lda chn_vibdir,x
                eor #$80
                sta chn_vibdir,x
                jmp mus_dowave
mus_vibdown:    jsr mus_freqdown
                dec chn_vibtime,x
                beq mus_vibdir
                jmp mus_dowave
mus_doslide:    lda chn_note,x                  ;Get target frequency
                tay
                lda freqtbl,y
                sta temp1
                lda freqtbl+1,y
                sta temp2
                jsr mus_16bitcompare            ;Go up or down?
                bcs mus_slidedown
mus_slideup:    jsr mus_frequp
mus_slupcheck:  jsr mus_16bitcompare
                bcs mus_slideready
                bcc mus_dowave
mus_slidedown:  jsr mus_freqdown
mus_sldncheck:  jsr mus_16bitcompare
                bcs mus_dowave
mus_slideready: lda temp1
                sta chn_freqlo,x
                lda temp2
                sta chn_freqhi,x
                ldy chn_snd,x
                jsr mus_vibinit2
mus_dowave:     lda chn_wavepos,x
                cmp #$fe
                beq mus_fxdone
mus_waveback:   tay
                inc chn_wavepos,x
                lda wavetbl,y
                cmp #$fe
                bcs mus_wavejump
                sta chn_wave,x
                jmp mus_fxdone
mus_wavejump:   beq mus_wavestop
                lda wavetbl+1,y
                sta chn_wavepos,x
                jmp mus_waveback
mus_wavestop:   sta chn_wavepos,x
mus_fxdone:     dec chn_counter,x
                bne mus_nextchn
                lda chn_pattpos,x
                bpl mus_nextchn
                jsr mus_getpattern
mus_nextchn:    ldy chn_regindex,x
                lda chn_pulselo,x
                sta $d402,y
                lda chn_pulsehi,x
                sta $d403,y
                lda chn_freqlo,x
                sta $d400,y
                lda chn_freqhi,x
                sta $d401,y
                lda chn_wave,x
                sta $d404,y
                lda chn_ad,x
                sta $d405,y
                lda chn_sr,x
                sta $d406,y
                inx
                cpx #$03
                beq mus_filtsnd
                jmp mus_chnloop
mus_filtsnd:    ldy #$00
                lda mus_filtctrl+1
                beq mus_alldone
mus_filttime:   lda #$00
                bne mus_nofiltturn
                lda mus_filtchoose+1
                eor #$01
                sta mus_filtchoose+1
                bne mus_filtreload1
mus_filtreload2:lda snd_filttime2,y
                sta mus_filttime+1
                jmp mus_nofiltturn
mus_filtreload1:lda snd_filttime1,y
                sta mus_filttime+1
mus_nofiltturn: cmp #$ff
                beq mus_skipfiltdec
                dec mus_filttime+1
mus_skipfiltdec:lda snd_filtspd,y
mus_filtchoose: ldy #$00
                beq mus_filtchoose2
                lsr
                lsr
                lsr
                lsr
mus_filtchoose2:and #$0f
                cmp #$08
                bcc mus_filtok
                ora #$f0
mus_filtok:     clc
                adc mus_cutoffhi+1
                sta mus_cutoffhi+1
mus_alldone:
mus_cutofflo:   lda #$00
                sta $d415
mus_cutoffhi:   lda #$00
                sta $d416
mus_filtctrl:   lda #$00
                sta $d417
mus_filttype:   lda #$00
                sta $d418
                rts

mus_getpattern: lda chn_songlo,x
                sta temp1
                lda chn_songhi,x
                sta temp2
                lda #$00
                sta chn_pattpos,x
                tay
mus_gploop:     lda (temp1),y
                cmp #REPEAT
                bcs mus_special
                sta chn_pattnum,x
                lda chn_pattrep,x
                beq mus_norepeat
                dec chn_pattrep,x
                jmp mus_noadvance
mus_norepeat:   inc temp1
                bne mus_noadvance
                inc temp2
mus_noadvance:  lda temp1
                sta chn_songlo,x
                lda temp2
                sta chn_songhi,x
                rts
mus_special:    inc temp1
                bne mus_spnohigh
                inc temp2
mus_spnohigh:   cmp #TRSTART
                bcc mus_setrepeat
                cmp #$fe
                bcs mus_restart
mus_settrans:   sbc #TR-1
mus_st2:        sta chn_trans,x
                jmp mus_gploop
mus_setrepeat:  sbc #REPEAT
                sta chn_pattrep,x
                jmp mus_gploop
mus_restart:    beq mus_endsong
                ldy chn_songtblindex,x
                lda songtbl,y
                sta temp1
                lda songtbl+1,y
                sta temp2
                ldy #$00
                tya
                sta chn_bits,x
                beq mus_st2
mus_endsong:    pla
                pla
                jmp mus_stop

mus_frequp:     lda chn_freqlo,x
                clc
                adc chn_viblo,x
                sta chn_freqlo,x
                lda chn_freqhi,x
                adc chn_vibhi,x
                sta chn_freqhi,x
                rts

mus_freqdown:   lda chn_freqlo,x
                sec
                sbc chn_viblo,x
                sta chn_freqlo,x
                lda chn_freqhi,x
                sbc chn_vibhi,x
                sta chn_freqhi,x
                rts

mus_16bitcompare:lda chn_freqhi,x
                cmp temp2
                beq mus_checklo
                rts
mus_checklo:    lda chn_freqlo,x
                cmp temp1
                rts

mus_vibinit:    ldy chn_snd,x
                lda snd_vibdelay,y
                sta chn_vibdelay,x
                lda snd_vibdepth,y              ;Initialize vibrato-timecount
                beq mus_novibinit
                and #$0f
                sta chn_vibtime,x
mus_vibinit2:   lda chn_bits,x
                and #255-SLIDEBIT
                sta chn_bits,x
                lda snd_vibdepth,y              ;Isolate vibdepth
                lsr
                lsr
                lsr
                lsr
mus_calcfreq:   sta temp4
                ldy chn_note,x
                lda freqtbl+2,y                 ;Calculate vibrato-speed
                sec                             ;from the difference
                sbc freqtbl,y                   ;between adjacent notes
                sta temp5
                lda freqtbl+3,y
                sbc freqtbl+1,y
                ldy temp4
                beq mus_calcfreqd
mus_calcfreql:  lsr
                ror temp5
                dec temp4
                bne mus_calcfreql
mus_calcfreqd:  sta chn_vibhi,x
                lda temp5
                sta chn_viblo,x
mus_novibinit:  rts

chn_freqlo:     dc.b 0,0,0
chn_freqhi:     dc.b 0,0,0
chn_pulselo:    dc.b 0,0,0
chn_pulsehi:    dc.b 0,0,0
chn_ad:         dc.b 0,0,0
chn_sr:         dc.b 0,0,0
chn_wave:       dc.b 0,0,0
chn_vibdelay:   dc.b 0,0,0
chn_vibtime:    dc.b 0,0,0
chn_viblo:      dc.b 0,0,0
chn_vibhi:      dc.b 0,0,0
chn_vibdir:     dc.b 0,0,0
chn_pulsedir:   dc.b 0,0,0
chn_snd:        dc.b 0,0,0
chn_bits:       dc.b 0,0,0
chn_note:       dc.b 0,0,0
chn_trans:      dc.b 0,0,0
chn_wavepos:    dc.b 0,0,0
chn_arppos:     dc.b 0,0,0
chn_arpstart:   dc.b 0,0,0
chn_songlo:     dc.b 0,0,0
chn_songhi:     dc.b 0,0,0
chn_songtblindex:dc.b 0,0,0
chn_pattpos:    dc.b 0,0,0
chn_pattrep:    dc.b 0,0,0
chn_pattnum:    dc.b 0,0,0
chn_duration:   dc.b 0,0,0
chn_counter:    dc.b 0,0,0
chn_regindex:   dc.b 0,7,14

freqtbl:        .byte 18,1,35,1,52,1,70,1, 90,1,110,1,132,1,155,1, 179,1,205,1,233,1,6,2
                .byte 37,2,69,2,104,2,140,2, 179,2,220,2,8,3,54,3, 103,3,155,3,210,3,12,4
                .byte 73,4,139,4,208,4,25,5, 103,5,185,5,16,6,108,6, 206,6,53,7,163,7,23,8
                .byte 147,8,21,9,159,9,60,10, 205,10,114,11,32,12,216,12, 156,13,107,14,70,15,47,16
                .byte 37,17,42,18,63,19,100,20, 154,21,227,22,63,24,177,25, 56,27,214,28,141,30,94,32
                .byte 75,34,85,36,126,38,200,40, 52,43,198,45,127,48,97,51, 111,54,172,57,126,61,188,64
                .byte 149,68,169,72,252,76,161,81, 105,86,140,91,254,96,194,102, 223,108,88,115,42,122,120,129
              ;  .byte 43,137,83,145,247,153,31,163, 210,172,25,183,252,193,133,205, 189,217, 176,230,103,244,255,255

packsongtbl:    ds.b 32*6,0
packpatttbl:    ds.b 160*2,0
packsndtbl:     ds.b 32*14,0
patttbllo:      ds.b 160,0

                org $3800
                incbin musiced.chr

patttblhi:      ds.b 160,0

                org $3ae0

songtbl:        REPEAT 32
                dc.w CHAN1
                dc.w CHAN2
                dc.w CHAN3
                REPEND

snd_ad:         ds.b 32,0
snd_sr:         ds.b 32,0
snd_pulse:      ds.b 32,0
snd_pulsespd:   ds.b 32,0
snd_pulselimit: ds.b 32,0
snd_vibdelay:   ds.b 32,0
snd_vibdepth:   ds.b 32,0
snd_arppos:     ds.b 32,0
snd_wavepos:    ds.b 32,0
snd_filtctrl:   ds.b 32,0
snd_filtcutoff: ds.b 32,0
snd_filtspd:    ds.b 32,0
snd_filttime1:  ds.b 32,0
snd_filttime2:  ds.b 32,0

arptbl:         ds.b 254,0

wavetbl:        ds.b 254,0

arpchgtbl:      ds.b 16,0

        ;Texts

                org $a800

disktext:       dc.b "DISK MENU",0
                dc.b " ",0
                dc.b "C...CHANGE DEVICE",0
                dc.b "D...DIRECTORY",0
                dc.b "L...LOAD SONG",0
                dc.b "S...SAVE SONG",0
                dc.b "E...ERASE SONG",0
                dc.b "P...PACK & RELOCATE",0
                dc.b "N...NUKE SONG IN MEMORY",0
                dc.b "X...EXIT SADOTRACKER",0
devicetext:     dc.b "DEVICE NUMBER:",0

asknametext:    dc.b "ENTER FILENAME:",0

confirmtext:    dc.b "ARE YOU SURE (Y/N)?",0

packtext:       dc.b "PACK & RELOCATE SONG",0
                dc.b "--------------------",0
                dc.b " ",0
                dc.b "USE CURSORS TO SELECT THE START ADDRESS.",0
                dc.b "PRESS RETURN TO GO OR RUN/STOP TO ABORT.",0
                dc.b "REMEMBER: PACKED MUSIC CAN'T BE LOADED",0
                dc.b "BACK INTO THE EDITOR!",0
packstat1:      dc.b "# OF SONGS.......",0
packstat2:      dc.b "# OF PATTERNS....",0
packstat3:      dc.b "# OF SOUNDS......",0
packstat4:      dc.b "TOTAL DATA SIZE..",0
packmsg1:       dc.b "JSR $     TO INIT (A=SONGNUMBER)",0
packmsg2:       dc.b "JSR $     TO PLAY",0
packmsg3:       dc.b "JSR $     TO STOP",0

soundnumtext:   dc.b "SOUND NUMBER ",0
arptbltext:     dc.b "ARPEG",0
wavetbltext:    dc.b "WAVES",0
arpchgtbltext:  dc.b "ARPCH",0

soundattrtext:  dc.b "ATTACK/DECAY",0
                dc.b "SUSTAIN/RELEASE",0
                dc.b "PULSE LOW/HIGH",0
                dc.b "PULSE SPEED",0
                dc.b "PULSE LIMITS",0
                dc.b "VIBRATO DELAY",0
                dc.b "VIBRATO DEP/SPD",0
                dc.b "ARPTABLE START",0
                dc.b "WAVETABLE START",0
                dc.b "FILT MODE/CHAN",0
                dc.b "FILT CUTOFF",0
                dc.b "FILT SPD1/SPD2",0
                dc.b "FILT TIME1",0
                dc.b "FILT TIME2",0

titletext:      dc.b "SADOTRACKER V1.1 BY CADAVER      F7=HELP",0
chantext:       dc.b " TRACK 1 ",0
patttext:       dc.b "PATTERN ",0

songtext:       dc.b "SONG ",0
songtext2:      dc.b "START:",0

rastertext:     dc.b "RASTER",0
rastertext1:    dc.b "C",0
rastertext2:    dc.b "M",0

emptytext:      dc.b "        ",0

sndtext:        dc.b "SND",0
arptext:        dc.b "ARP",0
slidetext:      dc.b "SLI",0
durtext:        dc.b "DUR",0

trtext:         dc.b "TRN",0
reptext:        dc.b "REP",0
endtext:        dc.b "HALT ",0
restext:        dc.b "LOOP ",0
emptytxt:       dc.b "   ",0

helptext:       dc.b "SADOTRACKER V1.1 HELP",0                  ;0
                dc.b " ",0                                      ;1
                dc.b "GENERAL KEYS",0                           ;2
                dc.b "------------",0                           ;3
                dc.b "F1  - CYCLE THROUGH TRACKS",0             ;4
                dc.b "F3  - SWITCH TRACK & SOUND EDITOR",0      ;5
                dc.b "F5  - ENTER DISK MENU",0                  ;6
                dc.b "F7  - SHOW HELP SCREEN",0                 ;7
                dc.b "SPC - PLAY/STOP (SHIFT+SPC FASTFWD)",0    ;8
                dc.b ",.  - SELECT SONG",0                      ;9
                dc.b " ",0                                      ;10
                dc.b "TRACK EDITOR",0                           ;11
                dc.b "------------",0                           ;12
                dc.b "USE 0-9, A-F TO ENTER HEX NUMBERS.",0     ;13
                dc.b "PRESS RETURN TO EDIT THE PATTERN UNDER",0 ;14
                dc.b "CURSOR. INS & DEL TO ADD/DELETE ROWS.",0  ;15
                dc.b " ",0                                      ;16
                dc.b "SHIFT+Z - MOVE UP FAST",0                 ;17
                dc.b "SHIFT+X - MOVE DOWN FAST",0               ;18
                dc.b "SHIFT+S - SET SONG STARTPOINT",0          ;19
                dc.b "SHIFT+G - GO TO SONG STARTPOINT",0        ;20
                dc.b "SHIFT+1 - REPEAT COMMAND",0               ;21
                dc.b "SHIFT+2 - TRANSPOSE COMMAND (20=MIDDLE)",0 ;22
                dc.b "SHIFT+3 - LOOP COMMAND",0                 ;23
                dc.b "SHIFT+4 - HALT COMMAND",0                 ;24
                dc.b "PATTERN EDITOR",0                         ;0
                dc.b "--------------",0                         ;1
                dc.b "CDEFGAH TO ENTER NOTES (SHIFT FOR #).",0  ;2
                dc.b "0-6 TO SELECT OCTAVE. INS & DEL WORK",0   ;3
                dc.b "HERE TOO...",0                            ;4
                dc.b " ",0                                      ;5
                dc.b "SHIFT+P - PUT PATTERN TO COPYBUFFER",0    ;6
                dc.b "SHIFT+T - TAKE PATTERN FROM COPYBUFFER",0 ;7
                dc.b "SHIFT+N - NUKE PATTERN",0                 ;8
                dc.b "SHIFT+1 - SND COMMAND",0                  ;9
                dc.b "SHIFT+2 - ARP COMMAND",0                  ;10
                dc.b "SHIFT+3 - DURATION COMMAND",0             ;11
                dc.b "SHIFT+4 - SLIDE COMMAND",0                ;12
                dc.b "SHIFT+5 - CYCLE GATE & PULSEINIT-MODE",0  ;13
                dc.b "SHIFT+R - CONTINUE (FOR LONG NOTES)",0    ;14
                dc.b "R       - REST COMMAND",0                 ;15
                dc.b ":;      - SELECT PATTERN",0               ;16
                dc.b " ",0                                      ;17
                dc.b "SOUND EDITOR",0                           ;18
                dc.b "------------",0                           ;19
                dc.b "USE 0-9, A-F FOR HEX NUMBERS. PRESS F1",0 ;20
                dc.b "TO CYCLE THROUGH SOUNDDATA & TABLES.",0   ;21
                dc.b "INS & DEL CAN BE USED IN ARP & WAVE-",0   ;22
                dc.b "TABLES. :; TO SELECT SOUND. SHIFT+P AND",0 ;23
                dc.b "SHIFT+T TO PUT/TAKE SND TO COPYBUFFER.",0 ;24
                dc.b "HOW THE PLAYER WORKS",0                   ;0
                dc.b "--------------------",0                   ;1
                dc.b "EACH CHANNEL WORKS INDIVIDUALLY, EXCEPT",0 ;2
                dc.b "FOR THE HALT COMMAND, WHICH HALTS ALL",0  ;3
                dc.b "CHANNELS. THE PLAYER GOES DOWNWARDS IN",0 ;4
                dc.b "THE TRACK-DATA, TO GET THE NEXT PATTERN",0 ;5
                dc.b "NUMBER TO BE PLAYED.",0                   ;6
                dc.b " ",0                                      ;7
                dc.b "A PATTERN BEGINS TYPICALLY BY SETTING",0  ;8
                dc.b "THE SOUND NUMBER AND DURATION, FOLLOWED",0 ;9
                dc.b "BY NOTES AND/OR RESTS. A SLIDE COMMAND",0 ;10
                dc.b "MUST BE FOLLOWED BY THE TARGET NOTE.",0   ;11
                dc.b "(A BIGGER VALUE IN THE SLIDE COMMAND",0   ;12
                dc.b "PARAMETER FIELD GIVES A SLOWER SLIDE).",0  ;13
                dc.b "GATE & PULSEINIT MODE, LIKE TRANSPOSE,",0 ;14
                dc.b "ARE ONLY RESET ON SONG START/RESTART,",0  ;15
                dc.b "SO USE WITH CARE.",0                      ;16
                dc.b " ",0                                      ;17
                dc.b "SOUND PARAMETERS ARE QUITE STRAIGHT-",0   ;18
                dc.b "FORWARD. PULSE WIDTH HAS THE NYBBLES",0   ;19
                dc.b "REVERSED. VIBRATO DEPTH WORKS LIKE",0     ;20
                dc.b "SLIDE; BIGGER VALUES GIVE LESS DEPTH",0
                dc.b "AND TAKE RASTERTIME! IF THE FILTER MODE",0
                dc.b "BYTE IS NONZERO, THE FILTER PARAMETERS",0
                dc.b "ARE DUMPED TO THE FILTER AT THE START",0
                dc.b "OF A NEW NOTE. (THE CHANNEL WITH THAT",0
                dc.b "SOUND IS CONTROLLING THE FILTER.)",0
                dc.b "HAVE ONLY ONE SUCH SOUND PLAYING AT",0
                dc.b "A TIME, SINCE THERE'S ONLY ONE FILTER!",0
                dc.b " ",0
                dc.b "ARPEGGIOTABLE VALUES 00-7F ARE RELATIVE",0
                dc.b "TO THE NOTE, 80-D3 ARE ABSOLUTE NOTES.",0
                dc.b "VALUE FE STOPS ARPEGGIO AND FF ACTS AS",0
                dc.b "A JUMP, FOLLOWED BY THE DESTINATION",0
                dc.b "POSITION. WAVE TABLE CONTAINS JUST THE",0
                dc.b "VALUES TO BE DUMPED INTO THE CHANNEL'S",0
                dc.b "WAVEFORM REGISTER. FE AND FF WORK LIKE",0
                dc.b "IN ARPEGGIO. ARPCHG-TABLE CONTAINS 16",0
                dc.b "INDEXES TO THE ARPEGGIO TABLE, TO BE",0
                dc.b "USED WITH THE ARP COMMAND.",0
                dc.b " ",0
                dc.b "HOW TO USE YOUR TUNES",0
                dc.b "---------------------",0
                dc.b "TO MAKE AN 'EXECUTABLE' VERSION OF YOUR",0
                dc.b "SONG(S), GO TO THE PACK/RELOCATOR",0
                dc.b "SCREEN FROM THE FILE MENU. THERE YOU",0
                dc.b "MUST GIVE THE ADDRESS WHERE YOU WANT",0
                dc.b "THE PLAYER & MUSICDATA TO BE LOCATED.",0
                dc.b "AFTER THIS WAIT A WHILE AS THE MUSIC",0
                dc.b "DATA IS PROCESSED AND THEN TYPE THE",0
                dc.b "FILENAME. AFTER SAVING IS FINISHED THE",0
                dc.b "JSR ADDRESSES FOR INIT/PLAY/STOP WILL",0
                dc.b "BE SHOWN. THE PLAYER USES ZEROPAGE",0
                dc.b "LOCATIONS $FB-$FF AND TAKES TYPICALLY",0
                dc.b "16-24 LINES OF RASTERTIME.",0
                dc.b " ",0
                dc.b "RESTARTING THE EDITOR",0
                dc.b "---------------------",0
                dc.b "IF YOU MAKE AN ENDLESS LOOP WHICH",0
                dc.b "CAUSES THE EDITOR TO BE STUCK, PRESS",0
                dc.b "RUNSTOP-RESTORE AND TYPE SYS 2064!",0,0

                org PLAYERORIG
                rorg PLAYERVIRT

        ;Player used by relocator
vmusic:         jmp vmus_init
                jmp vmus_play
                jmp vmus_stop

vmus_init:      ldx #$00                        ;Set flag: don't play
                stx vmus_play+1
                asl                             ;Multiply tune-number by 6
                sta temp1
                asl
                adc temp1
                tay
vmus_initloop:  lda SONGTBLVIRT,y                   ;Set address of channel's
                sta vchn_songlo,x                ;sequence data
                lda SONGTBLVIRT+1,y
                sta vchn_songhi,x
                tya
                sta vchn_songtblindex,x
                iny
                iny
                sty temp3
                lda #$00                        ;Reset duration, waveform,
                sta vchn_pattrep,x               ;pattern position & channel
                sta vchn_wave,x                  ;bits
                sta vchn_bits,x
                sta vchn_trans,x
                sta vchn_counter,x
                jsr vmus_getpattern
                ldy temp3
                inx                             ;All channels done?
                cpx #$03
                bne vmus_initloop
                stx vmus_play+1
                lda #$00
                sta vmus_filtctrl+1
                lda #$0f
                sta vmus_filttype+1
                rts

vmus_stop:      lda #$00                        ;Set flag: don't play
                sta vmus_play+1
                tax
vmus_stoploop:  sta vchn_wave,x
                ldy vchn_regindex,x
                sta $d404,y
                inx
                cpx #$03
                bne vmus_stoploop
                rts

vmus_play:      lda #$00                        ;Check playflag
                bne vmus_ok
                rts
vmus_ok:        ldx #$00
vmus_vchnloop:  lda vchn_counter,x               ;Time to get new note?
                bmi vmus_initnote
                beq vmus_newnote
                jmp vmus_effects
vmus_initnote:  lda vchn_duration,x
                sec
                sbc #$01
                sta vchn_counter,x
                ldy vchn_snd,x                   ;Get soundnumber
                lda vchn_bits,x                  ;Will we init pulse?
                and #PULSEBIT
                bne vmus_nopulseinit
                lda SNDVIRT+SNDPULSE,y
                sta vchn_pulselo,x
                and #$0f
                sta vchn_pulsehi,x
                lda #$00
                sta vchn_pulsedir,x
vmus_nopulseinit:lda #$00
                sta vchn_vibdir,x
                lda SNDVIRT+SNDAD,y
                sta vchn_ad,x
                lda SNDVIRT+SNDSR,y
                sta vchn_sr,x
                lda SNDVIRT+SNDWAVEPOS,y
                sta vchn_wavepos,x
                lda vchn_arpstart,x
                sta vchn_arppos,x
                lda SNDVIRT+SNDFILTCTRL,y
                beq vmus_nofiltinit
                and #$0f
                sta vmus_filtctrl+1
                lda SNDVIRT+SNDFILTCTRL,y
                ora #$0f
                sta vmus_filttype+1
                lda SNDVIRT+SNDFILTCUTOFF,y
                sta vmus_cutoffhi+1
                lda #$00
                sta vmus_filttime+1
                sta vmus_filtchoose+1
                sty vmus_filtsnd+1
vmus_nofiltinit:jmp vmus_doarp

vmus_newnote:   ldy vchn_pattnum,x               ;Get address of pattern
                lda PATTTBLLOVIRT,y
                sta temp1
                lda PATTTBLHIVIRT,y
                sta temp2
                ldy vchn_pattpos,x               ;And position within it
vmus_newnoteloop:lda (temp1),y                   ;Load next command
                bmi vmus_nnneg
                iny
                cmp #SND
                bcs vmus_setsnd
                cmp #ARP
                bcs vmus_setarp
                jmp vmus_note
vmus_setarp:     sbc #ARP
                sty temp3
                tay
                lda ARPCHTBLVIRT,y
                sta vchn_arpstart,x
                ldy temp3
                bne vmus_newnoteloop
vmus_setsnd:     sbc #SND
                sta vchn_snd,x
                sty temp3
                tay
                lda SNDVIRT+SNDARPPOS,y
                sta vchn_arpstart,x
                ldy temp3
                bne vmus_newnoteloop
vmus_nnneg:      iny
                cmp #REST
                bcs vmus_rest
                cmp #DUR
                bcc vmus_setslide
vmus_setdur:     sbc #DUR
                sta vchn_duration,x
                bne vmus_newnoteloop
vmus_setslide:   cmp #TIEOFF
                bcc vmus_nosetbit
                and #$03
                sta vchn_bits,x
                jmp vmus_newnoteloop
vmus_nosetbit:   sty temp3
                sbc #SLIDE-1
                jsr vmus_calcfreq
                lda vchn_bits,x
                ora #SLIDEBIT
                sta vchn_bits,x
                ldy temp3
                lda (temp1),y
                clc
                adc vchn_trans,x
                asl
                sta vchn_note,x
                iny
vmus_rest:       bne vmus_contnote
                lda vchn_wave,x
                and #$fe
                sta vchn_wave,x
vmus_contnote:   jsr vmus_checkendpatt
                lda vchn_duration,x
                sta vchn_counter,x
                jmp vmus_effects
vmus_note:       clc
                adc vchn_trans,x
                asl
                sta vchn_note,x
                lda vchn_bits,x
                and #TIEBIT
                bne vmus_nohard
                lda #$00
                sta vchn_wave,x
                sta vchn_ad,x
                sta vchn_sr,x
vmus_nohard:     lda #$ff
                sta vchn_counter,x
                jsr vmus_checkendpatt
                jsr vmus_vibinit
                jmp vmus_nextvchn
vmus_checkendpatt:lda (temp1),y
                cmp #ENDPATT
                bne vmus_noendpatt
                tay
vmus_noendpatt: tya
                sta vchn_pattpos,x
                rts

vmus_effects:   lda vchn_wave,x
                bne vmus_dopulse
                jmp vmus_fxdone
vmus_dopulse:   ldy vchn_snd,x
                lda vchn_pulsedir,x
                bmi vmus_pulsedown
vmus_pulseup:   lda SNDVIRT+SNDPULSELIMIT,y
                and #$0f
                sta temp1
                lda vchn_pulselo,x
                clc
                adc SNDVIRT+SNDPULSESPD,y
                sta vchn_pulselo,x
                bcc vmus_punotover
                inc vchn_pulsehi,x
vmus_punotover: lda vchn_pulsehi,x
                cmp temp1
                bcc vmus_doarp
vmus_pulsedir:  lda vchn_pulsedir,x
                eor #$80
                sta vchn_pulsedir,x
                jmp vmus_doarp
vmus_pulsedown: lda SNDVIRT+SNDPULSELIMIT,y
                lsr
                lsr
                lsr
                lsr
                sta temp1
                lda vchn_pulselo,x
                sec
                sbc SNDVIRT+SNDPULSESPD,y
                sta vchn_pulselo,x
                bcs vmus_pdnotover
                dec vchn_pulsehi,x
vmus_pdnotover: lda vchn_pulsehi,x
                cmp temp1
                bcc vmus_pulsedir
vmus_doarp:     lda vchn_arppos,x
                cmp #$fe
                bcs vmus_dovib
vmus_arpback:   tay
                inc vchn_arppos,x
                lda ARPTBLVIRT,y
                bmi vmus_absarp
                asl
                adc vchn_note,x
vmus_arpfreq:   tay
                lda vfreqtbl,y
                sta vchn_freqlo,x
                lda vfreqtbl+1,y
                sta vchn_freqhi,x
                jmp vmus_dowave
vmus_absarp:     cmp #$fe
                bcs vmus_arpjump
                asl
                jmp vmus_arpfreq
vmus_arpjump:   beq vmus_arpstop
                lda ARPTBLVIRT+1,y
                sta vchn_arppos,x
                jmp vmus_arpback
vmus_arpstop:   sta vchn_arppos,x
                jmp vmus_dowave
vmus_dovib:     lda vchn_bits,x
                and #SLIDEBIT
                bne vmus_doslide
                lda SNDVIRT+SNDVIBDEPTH,y
                beq vmus_novib
                lda vchn_vibdelay,x
                bne vmus_vibdelay
vmus_novibdelay:lda vchn_vibdir,x
                bmi vmus_vibdown
vmus_vibup:     jsr vmus_frequp
                dec vchn_vibtime,x
                beq vmus_vibdir
                jmp vmus_dowave
vmus_vibdelay:  dec vchn_vibdelay,x
vmus_novib:     jmp vmus_dowave
vmus_vibdir:    lda SNDVIRT+SNDVIBDEPTH,y
                and #$0f
                asl
                sta vchn_vibtime,x
                lda vchn_vibdir,x
                eor #$80
                sta vchn_vibdir,x
                jmp vmus_dowave
vmus_vibdown:   jsr vmus_freqdown
                dec vchn_vibtime,x
                beq vmus_vibdir
                jmp vmus_dowave
vmus_doslide:    lda vchn_note,x                  ;Get target frequency
                tay
                lda vfreqtbl,y
                sta temp1
                lda vfreqtbl+1,y
                sta temp2
                jsr vmus_16bitcompare            ;Go up or down?
                bcs vmus_slidedown
vmus_slideup:   jsr vmus_frequp
vmus_slupcheck: jsr vmus_16bitcompare
                bcs vmus_slideready
                bcc vmus_dowave
vmus_slidedown: jsr vmus_freqdown
vmus_sldncheck: jsr vmus_16bitcompare
                bcs vmus_dowave
vmus_slideready:lda temp1
                sta vchn_freqlo,x
                lda temp2
                sta vchn_freqhi,x
                ldy vchn_snd,x
                jsr vmus_vibinit2
vmus_dowave:    lda vchn_wavepos,x
                cmp #$fe
                beq vmus_fxdone
vmus_waveback:  tay
                inc vchn_wavepos,x
                lda WAVETBLVIRT,y
                cmp #$fe
                bcs vmus_wavejump
                sta vchn_wave,x
                jmp vmus_fxdone
vmus_wavejump:  beq vmus_wavestop
                lda WAVETBLVIRT+1,y
                sta vchn_wavepos,x
                jmp vmus_waveback
vmus_wavestop:  sta vchn_wavepos,x
vmus_fxdone:    dec vchn_counter,x
                bne vmus_nextvchn
                lda vchn_pattpos,x
                bpl vmus_nextvchn
                jsr vmus_getpattern
vmus_nextvchn:  ldy vchn_regindex,x
                lda vchn_pulselo,x
                sta $d402,y
                lda vchn_pulsehi,x
                sta $d403,y
                lda vchn_freqlo,x
                sta $d400,y
                lda vchn_freqhi,x
                sta $d401,y
                lda vchn_wave,x
                sta $d404,y
                lda vchn_ad,x
                sta $d405,y
                lda vchn_sr,x
                sta $d406,y
                inx
                cpx #$03
                beq vmus_filtsnd
                jmp vmus_vchnloop
vmus_filtsnd:   ldy #$00
                lda vmus_filtctrl+1
                beq vmus_alldone
vmus_filttime:  lda #$00
                bne vmus_nofiltturn
                lda vmus_filtchoose+1
                eor #$01
                sta vmus_filtchoose+1
                bne vmus_filtreload1
vmus_filtreload2:lda SNDVIRT+SNDFILTTIME2,y
                sta vmus_filttime+1
                jmp vmus_nofiltturn
vmus_filtreload1:lda SNDVIRT+SNDFILTTIME1,y
                sta vmus_filttime+1
vmus_nofiltturn: cmp #$ff
                beq vmus_skipfiltdec
                dec vmus_filttime+1
vmus_skipfiltdec:lda SNDVIRT+SNDFILTSPD,y
vmus_filtchoose: ldy #$00
                beq vmus_filtchoose2
                lsr
                lsr
                lsr
                lsr
vmus_filtchoose2:and #$0f
                cmp #$08
                bcc vmus_filtok
                ora #$f0
vmus_filtok:     clc
                adc vmus_cutoffhi+1
                sta vmus_cutoffhi+1
vmus_alldone:
vmus_cutofflo:   lda #$00
                sta $d415
vmus_cutoffhi:   lda #$00
                sta $d416
vmus_filtctrl:   lda #$00
                sta $d417
vmus_filttype:   lda #$00
                sta $d418
                rts

vmus_getpattern: lda vchn_songlo,x
                sta temp1
                lda vchn_songhi,x
                sta temp2
                lda #$00
                sta vchn_pattpos,x
                tay
vmus_gploop:     lda (temp1),y
                cmp #REPEAT
                bcs vmus_special
                sta vchn_pattnum,x
                lda vchn_pattrep,x
                beq vmus_norepeat
                dec vchn_pattrep,x
                jmp vmus_noadvance
vmus_norepeat:   inc temp1
                bne vmus_noadvance
                inc temp2
vmus_noadvance:  lda temp1
                sta vchn_songlo,x
                lda temp2
                sta vchn_songhi,x
                rts
vmus_special:    inc temp1
                bne vmus_spnohigh
                inc temp2
vmus_spnohigh:   cmp #TRSTART
                bcc vmus_setrepeat
                cmp #$fe
                bcs vmus_restart
vmus_settrans:   sbc #TR-1
vmus_st2:        sta vchn_trans,x
                jmp vmus_gploop
vmus_setrepeat:  sbc #REPEAT
                sta vchn_pattrep,x
                jmp vmus_gploop
vmus_restart:    beq vmus_endsong
                ldy vchn_songtblindex,x
                lda SONGTBLVIRT,y
                sta temp1
                lda SONGTBLVIRT+1,y
                sta temp2
                ldy #$00
                tya
                sta vchn_bits,x
                beq vmus_st2
vmus_endsong:    pla
                pla
                jmp vmus_stop

vmus_frequp:     lda vchn_freqlo,x
                clc
                adc vchn_viblo,x
                sta vchn_freqlo,x
                lda vchn_freqhi,x
                adc vchn_vibhi,x
                sta vchn_freqhi,x
                rts

vmus_freqdown:   lda vchn_freqlo,x
                sec
                sbc vchn_viblo,x
                sta vchn_freqlo,x
                lda vchn_freqhi,x
                sbc vchn_vibhi,x
                sta vchn_freqhi,x
                rts

vmus_16bitcompare:lda vchn_freqhi,x
                cmp temp2
                beq vmus_checklo
                rts
vmus_checklo:    lda vchn_freqlo,x
                cmp temp1
                rts

vmus_vibinit:    ldy vchn_snd,x
                lda SNDVIRT+SNDVIBDELAY,y
                sta vchn_vibdelay,x
                lda SNDVIRT+SNDVIBDEPTH,y              ;Initialize vibrato-timecount
                beq vmus_novibinit
                and #$0f
                sta vchn_vibtime,x
vmus_vibinit2:   lda vchn_bits,x
                and #255-SLIDEBIT
                sta vchn_bits,x
                lda SNDVIRT+SNDVIBDEPTH,y              ;Isolate vibdepth
                lsr
                lsr
                lsr
                lsr
vmus_calcfreq:   sta temp4
                ldy vchn_note,x
                lda vfreqtbl+2,y                 ;Calculate vibrato-speed
                sec                             ;from the difference
                sbc vfreqtbl,y                   ;between adjacent notes
                sta temp5
                lda vfreqtbl+3,y
                sbc vfreqtbl+1,y
                ldy temp4
                beq vmus_calcfreqd
vmus_calcfreql:  lsr
                ror temp5
                dec temp4
                bne vmus_calcfreql
vmus_calcfreqd:  sta vchn_vibhi,x
                lda temp5
                sta vchn_viblo,x
vmus_novibinit:  rts

vchn_freqlo:     dc.b 0,0,0
vchn_freqhi:     dc.b 0,0,0
vchn_pulselo:    dc.b 0,0,0
vchn_pulsehi:    dc.b 0,0,0
vchn_ad:         dc.b 0,0,0
vchn_sr:         dc.b 0,0,0
vchn_wave:       dc.b 0,0,0
vchn_vibdelay:   dc.b 0,0,0
vchn_vibtime:    dc.b 0,0,0
vchn_viblo:      dc.b 0,0,0
vchn_vibhi:      dc.b 0,0,0
vchn_vibdir:     dc.b 0,0,0
vchn_pulsedir:   dc.b 0,0,0
vchn_snd:        dc.b 0,0,0
vchn_bits:       dc.b 0,0,0
vchn_note:       dc.b 0,0,0
vchn_trans:      dc.b 0,0,0
vchn_wavepos:    dc.b 0,0,0
vchn_arppos:     dc.b 0,0,0
vchn_arpstart:   dc.b 0,0,0
vchn_songlo:     dc.b 0,0,0
vchn_songhi:     dc.b 0,0,0
vchn_songtblindex:dc.b 0,0,0
vchn_pattpos:    dc.b 0,0,0
vchn_pattrep:    dc.b 0,0,0
vchn_pattnum:    dc.b 0,0,0
vchn_duration:   dc.b 0,0,0
vchn_counter:    dc.b 0,0,0
vchn_regindex:   dc.b 0,7,14

vfreqtbl:       .byte 18,1,35,1,52,1,70,1, 90,1,110,1,132,1,155,1, 179,1,205,1,233,1,6,2
                .byte 37,2,69,2,104,2,140,2, 179,2,220,2,8,3,54,3, 103,3,155,3,210,3,12,4
                .byte 73,4,139,4,208,4,25,5, 103,5,185,5,16,6,108,6, 206,6,53,7,163,7,23,8
                .byte 147,8,21,9,159,9,60,10, 205,10,114,11,32,12,216,12, 156,13,107,14,70,15,47,16
                .byte 37,17,42,18,63,19,100,20, 154,21,227,22,63,24,177,25, 56,27,214,28,141,30,94,32
                .byte 75,34,85,36,126,38,200,40, 52,43,198,45,127,48,97,51, 111,54,172,57,126,61,188,64
                .byte 149,68,169,72,252,76,161,81, 105,86,140,91,254,96,194,102, 223,108,88,115,42,122,120,129
               ; .byte 43,137,83,145,247,153,31,163, 210,172,25,183,252,193,133,205, 189,217, 176,230,103,244,255,255

vmusic_end:

PLAYERSIZE       = vmusic_end - vmusic

                rend
