;ͻ
;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