ys2-intro/loader/samples/minexample/furC64/asm/furC64.asm
2025-11-26 20:54:53 +07:00

2202 lines
26 KiB
NASM

.feature c_comments
.define chnum 3
.define use_zp 0
.define porta_once 0
.define compat_hr 0
.define CHIP_AMT 1
.define DIGI 0
.define HR_ADSR 1
TEST_AD := $00
TEST_SR := $00
;.define compat_hr 1
;TEST_AD := $0f
;TEST_SR := $0f
.if DIGI = 0
.define outch chnum
.else
.define outch 4
.endif
.macro variables
start_vars = *
mframeW: .res chnum
doMacroW: .res chnum
; why
env_reset_buf: .res chnum
env_reset: .res chnum
fil_lo_n2: .res CHIP_AMT
fil_hi_n2: .res CHIP_AMT
fil_st2: .res CHIP_AMT
legato: .res chnum
test_reset: .res chnum
note_tick: .res chnum
dur: .res chnum
vibrato_param: .res chnum
vibrato_phase: .res chnum
absfil: .res CHIP_AMT
doMacroC: .res CHIP_AMT
mframeC: .res CHIP_AMT
instF: .res CHIP_AMT
wav: .res chnum
hrframe: .res chnum
hrc: .res chnum
ad: .res chnum
sr: .res chnum
patseq: .res chnum*2
duty_lo: .res chnum
duty_hi: .res chnum
nextpat: .res 1
patind: .res 1
jumppat: .res 1
ch: .res 1
chm: .res 1
tick: .res 1
ins: .res chnum
inst_prev: .res chnum
mframeA: .res chnum
mframeD: .res chnum
doMacroA: .res chnum
doMacroD: .res chnum
arp: .res chnum
absarp: .res chnum
effects_temp: .res 2
tick_speeds: .res 2
tick_sel: .res 1
slide_amt: .res chnum
slide_amt_sign: .res chnum
slide_buffer_lo: .res chnum
slide_buffer_hi: .res chnum
note_pitch_lo: .res chnum
note_pitch_hi: .res chnum
note_n: .res chnum
note_temp: .res chnum
note_dest: .res chnum
finepitch: .res chnum
cut_dur: .res chnum
pw_mod_lo: .res chnum
pw_mod_hi: .res chnum
abspw: .res chnum
retrigger_pw: .res chnum
retrigger_fil: .res CHIP_AMT
triggered_fil: .res CHIP_AMT
.if porta_once = 1
didporta: .res chnum
.endif
arpeff1: .res chnum
arpeff2: .res chnum
arpind: .res chnum
vol: .res CHIP_AMT
res: .res CHIP_AMT
fil_lo: .res CHIP_AMT
fil_hi: .res CHIP_AMT
fil_lo_n: .res CHIP_AMT
fil_hi_n: .res CHIP_AMT
base: .res 1
chipnum: .res 1
has_played: .res chnum
extin: .res 1
vars_len = *-start_vars
.endmacro
inst_buffer = ins
.if chnum > 4
.define actual_use_zp 0
.else
.define actual_use_zp use_zp
.endif
.ZEROPAGE
.if actual_use_zp = 1
.org $10
variables
.endif
patzp := $fe
macroIns := patzp
temp := patzp-4
flags_temp := temp+3
patloop = 0
.segment "CODE"
.org $080D
jmp $900
.res $0900-*
.import __PLAYER_LOAD__, __PLAYER_RUN__, __PLAYER_SIZE__
main:
sei
lda #$35
sta $01
lda #<__PLAYER_LOAD__
sta temp
lda #>__PLAYER_LOAD__
sta temp+1
lda #<__PLAYER_RUN__
sta temp+2
lda #>__PLAYER_RUN__
sta temp+3
ldy #0
ldx #>__PLAYER_SIZE__
beq :+++
:
lda (temp),y
sta (temp+2),y
iny
bne :-
inc temp+1
inc temp+3
dex
bne :-
beq :++
:
lda (temp),y
sta (temp+2),y
iny
:
cpy #<__PLAYER_SIZE__
bne :--
lda #127
sta $dc0d
and $d011
sta $d011
lda $dc0d
lda $dd0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
.if DIGI <> 0
lda #$0b
sta $d011
lda #$00
.else
lda #$10
.endif
sta $d012
lda #0
sta $d01a
lda #$63; <(985248/100)
sta $dc04
lda #$26;>(985248/100)
sta $dc05
lda $dc0d
and #$81
sta $dc0d
lda #$40
sta $dc0c
lda #$81
sta $dc0d
.if DIGI <> 0
ldx #0
:
lda real_addr, x
sta $2, x
inx
cpx #nmi_end-nmi
bne :-
.endif
lda #0
jsr init
.if DIGI <> 0
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #$01
sta $dd0d
sta $dd0e
lda #$88 ; lo
sta $dd04
lda #0
sta $dd05 ; hi
lda $dd0d
lda #$81
sta $dd0d
lda #$40
sta $dd0c
.endif
cli
jmp *
irq:
pha
txa
pha
tya
pha
.if DIGI = 0
inc $d020
.endif
;lda $d012
;sta rastertime
jsr play
.if DIGI = 0
dec $d020
.endif
;lda $d012
;sec
;sbc rastertime
;sta rastertime
;asl $d019
pla
tay
pla
tax
pla
;rti
jmp $dc0c
;rastertime: .res 1
.if DIGI <> 0
real_addr = *
.org $2
nmi:
sta z:ldat+1
ldn:
lda $200
sta $d418
inc ldn+1
ldat:
lda #0
jmp $dd0c
NMI_BUFFER:
ldy #0
NMI_LOOP:
lda z:nmi_add+2
nmi_cmp:
cmp #0
bcc nmi_store
nmi_cmp2:
lda #0
sta z:nmi_add+2
nmi_none:
lda vol
and #$f0
ora #10
sta $200, y
jmp NMI_LOOP_END
nmi_store:
lda vol
and #$f0
nmi_add:
ora $1000
sta $200, y
clc
nmi_freq_lo2:
lda #0
nmi_freq_lo:
adc #0
sta nmi_freq_lo2+1
lda nmi_add+1
nmi_freq_hi:
adc #1
sta nmi_add+1
bcc NMI_LOOP_END
inc nmi_add+2
NMI_LOOP_END:
iny
cpy #144
bne NMI_LOOP
rts
nmi_end:
.org real_addr+(nmi_end-nmi)
.endif
.segment "PLAYER"
.reloc
init:
jmp initaddr
play:
jmp playaddr
jmp extaddr
.byte " furC64 driver by AArt1256"
.if actual_use_zp = 0
variables
.endif
table_1_to_ff:
table_fil:
.byte 0
.res 15, $ff
.proc initaddr
.if actual_use_zp = 1
ldx #vars_len
lda #0
:
sta start_vars-1, x
dex
bne :-
.endif
ldx #(CHIP_AMT)-1
:
lda #$7f
sta vol, x
lda #$00
sta res, x
sta retrigger_fil, x
sta triggered_fil, x
lda #$ff
sta fil_lo, x
sta fil_lo_n, x
lda #$07
sta fil_hi, x
sta fil_hi_n, x
lda #0
sta doMacroC, x
sta absfil, x
sta fil_lo_n2, x
sta fil_hi_n2, x
sta fil_st2, x
sta mframeC, x
sta has_played, x
dex
bpl :-
lda #0
sta tick_sel
lda ticks_init
sta tick_speeds
lda ticks_init+1
sta tick_speeds+1
lda #0
sta patind
ldx #chnum-1
:
lda #$80
sta finepitch, x
sta finepitch, x
lda #1
sta dur, x
lda #$ff
sta cut_dur, x
lda #0
sta pw_mod_lo, x
sta pw_mod_hi, x
.if porta_once = 1
sta didporta, x
.endif
sta wav, x
sta retrigger_pw, x
sta abspw, x
sta ins, x
sta inst_prev, x
sta arp, x
sta slide_amt, x
sta slide_amt_sign, x
sta slide_buffer_lo, x
sta slide_buffer_hi, x
sta vibrato_phase, x
sta vibrato_param, x
sta note_dest, x
sta mframeA, x
sta mframeW, x
sta mframeD, x
sta doMacroA, x
sta doMacroW, x
sta doMacroD, x
lda #$ff
sta env_reset_buf, x
lda #8
sta test_reset, x
lda #4
sta hrframe, x
sta note_tick, x
dex
bpl :-
ldx #0
jsr set_patseq_init
lda #0
sta tick
sta jumppat
rts
.endproc
.macro get_patzp
.local skipW
inc patzp
bne skipW
inc patzp+1
skipW:
lda (patzp), y
.endmacro
.macro get_patzp_vol
.local skipW
inc patzp
bne skipW
inc patzp+1
skipW:
lda vol
and #$f0
ora (patzp), y
.endmacro
.macro add_09xx
effectE0:
get_patzp
sta tick_speeds
jmp begnote
.endmacro
.macro add_0Fxx
effectE1:
get_patzp
sta tick_speeds+1
jmp begnote
.endmacro
.macro add_0Bxx
effectED:
get_patzp
sta patind
lda #$ff
sta jumppat
jmp begnote
.endmacro
.macro add_00xx
effectE2:
get_patzp
sta effects_temp+1
ldx ch
lda #0
sta arpind, x
lda effects_temp+1
and #$0f
sta arpeff2, x
lda effects_temp+1
lsr
lsr
lsr
lsr
sta arpeff1, x
jmp begnote
.endmacro
.macro add_01xx
effectE3:
get_patzp
ldx ch
sta slide_amt, x
lda #$ff
sta slide_amt_sign, x
ldx ch
lda #88
sta note_dest, x
.if porta_once = 1
lda #$00
sta didporta, x
.endif
jmp begnote
.endmacro
.macro add_02xx
effectE4:
get_patzp
ldx ch
sta slide_amt, x
lda #$00
sta slide_amt_sign, x
ldx ch
lda #0
sta note_dest, x
.if porta_once = 1
lda #$00
sta didporta, x
.endif
jmp begnote
.endmacro
.macro add_03xx
effectE5:
get_patzp
ldx ch
sta slide_amt, x
ldy #0
get_patzp
ldx ch
sta note_dest, x
.if porta_once = 1
lda #$ff
sta didporta, x
.endif
lda note_n, x
cmp note_dest, x
bne :+
lda #0
sta slide_amt, x
sta slide_amt_sign, x
jmp begnote
:
bcc :+
lda #$00
sta slide_amt_sign, x
jmp begnote
:
lda #$ff
sta slide_amt_sign, x
jmp begnote
.endmacro
.macro add_04xx
.local retskip
effectE6:
get_patzp
ldx ch
sta vibrato_param, x
beq retskip
sta vibrato_phase, x
retskip:
jmp begnote
.endmacro
.macro add_1Axx
effectF1:
get_patzp
ldx ch
eor #$ff
sta env_reset_buf, x
jmp begnote
.endmacro
.macro add_1Bxx
.local retskip
effectE7:
get_patzp
sta effects_temp+1
and #$0f
tax
lda table_fil, x
ldx ch
beq :+
ldx chipnum
lda fil_lo_n, x
sta fil_lo, x
lda fil_hi_n, x
sta fil_hi, x
ldx ch
:
lda effects_temp+1
lsr
lsr
lsr
lsr
tax
lda table_fil, x
ldx chipnum
sta retrigger_fil, x
jmp begnote
.endmacro
.macro add_1Cxx
.local retskip
effectE8:
get_patzp
sta effects_temp+1
and #$0f
tax
lda table_fil, x
ldx ch
beq :+
lda #0
sta pw_mod_lo, x
sta pw_mod_hi, x
:
lda effects_temp+1
lsr
lsr
lsr
lsr
tax
lda table_fil, x
ldx ch
sta retrigger_pw, x
jmp begnote
.endmacro
.macro add_E1xx
effectE9:
get_patzp
ldx ch
asl
asl
sta slide_amt, x
lda #$ff
sta slide_amt_sign, x
ldy #0
get_patzp
ldx ch
ora #$80
sta note_dest, x
.if porta_once = 1
lda #$00
sta didporta, x
.endif
jmp begnote
.endmacro
.macro add_E2xx
effectEA:
get_patzp
ldx ch
asl
asl
sta slide_amt, x
lda #$00
sta slide_amt_sign, x
ldy #0
get_patzp
ldx ch
ora #$80
sta note_dest, x
.if porta_once = 1
lda #$00
sta didporta, x
.endif
jmp begnote
.endmacro
.macro add_E5xx
effectEB:
get_patzp
ldx ch
sta finepitch, x
jmp begnote
.endmacro
.macro add_ECxx
effectEC:
get_patzp
ldx ch
clc
.if compat_hr = 0
adc #3
.else
adc #2
.endif
sta cut_dur, x
jmp begnote
.endmacro
.macro add_4xxx
effectEE:
ldx chipnum
lda #0
sta doMacroC, x
sta fil_hi_n2, x
lda #$ff
sta fil_st2, x
get_patzp
ldx chipnum
sta fil_lo_n2, x
clc
asl fil_lo_n2, x
rol fil_hi_n2, x
clc
asl fil_lo_n2, x
rol fil_hi_n2, x
clc
asl fil_lo_n2, x
rol fil_hi_n2, x
jmp begnote
.endmacro
.macro add_EAxx
effectEF:
ldx ch
lda #0
sta legato, x
jmp begnote
effectF0:
ldx ch
lda #$ff
sta legato, x
jmp begnote
.endmacro
.macro add_EExx
effectF2:
get_patzp
ldx extin
beq :+
sta patind
lda #$ff
sta jumppat
:
jmp begnote
.endmacro
add_09xx
add_0Fxx
add_00xx
add_01xx
add_02xx
add_03xx
add_04xx
add_0Bxx
add_1Axx
add_1Bxx
add_1Cxx
add_E1xx
add_E2xx
add_E5xx
add_EAxx
add_ECxx
add_4xxx
add_EExx
other_effects:
lda effects_temp
cmp #$FB
bne :+
ldx ch
get_patzp
sta ins, x
jmp begnote
:
cmp #$FC
bne :+
ldx chipnum
get_patzp_vol
sta vol, x
jmp begnote
:
cmp #$FD
bne :+
ldx ch
ldy ins, x
lda insArel, y
sta mframeA, x
lda insDrel, y
sta mframeD, x
ldx ch
.if compat_hr = 0
lda #3
.else
lda #2
.endif
sta cut_dur, x
lda #1
sta dur, x
ldy #0
jmp end_advance
:
cmp #$FE
bne :+
ldx ch
.if compat_hr = 0
lda #3
.else
lda #2
.endif
sta cut_dur, x
lda #1
sta dur, x
ldy #0
jmp end_advance
:
lda effects_temp
cmp #224
bcc cont_advance
lda effects_temp
and #$1f
tax
lda eff_lo, x
sta effect_smc+1
lda eff_hi, x
sta effect_smc+2
ldx ch
lda effects_temp
effect_smc:
jmp cont_advance
eff_lo:
.repeat $13, I
.lobytes .ident(.concat ("effect", .sprintf("%02X",I+$e0)))
.endrepeat
eff_hi:
.repeat $13, I
.hibytes .ident(.concat ("effect", .sprintf("%02X",I+$e0)))
.endrepeat
.macro add_advance_routine
advance:
.local skipD, noIns, noVol, beg, blank2, blank3, hasNote, wait
beg:
lda ch
asl
tax
lda patseq, x
sta patzp
lda patseq+1, x
sta patzp+1
ldx ch
dec dur, x
lda dur, x
beq begnote
jmp end_advance
begnote:
ldy #0
get_patzp
sta temp
sta effects_temp
and #$80
beq wait
lda temp
cmp #$ff
beq blank2
jmp other_effects
cont_advance:
lda temp
and #$7f
ldx ch
ldy env_reset_buf, x
beq :+
sta note_n, x
:
sta note_temp, x
lda note_tick, x
cmp #96
bne :+
lda #0
sta slide_amt, x
sta slide_amt_sign, x
:
lda note_tick, x
cmp #2
bcc :+
lda legato, x
bne :+
lda #0
sta hrframe, x
lda #$ff
sta hrc, x
:
lda #0
sta slide_buffer_lo, x
sta slide_buffer_hi, x
sta note_tick, x
.if porta_once = 1
cmp didporta, x
beq :+
sta didporta, x
sta slide_amt, x
sta slide_amt_sign, x
:
.endif
ldx ch
lda env_reset_buf, x
sta env_reset, x
lda #1
sta dur, x
sta has_played, x
ldy #0
jmp end_advance
wait:
lda temp
and #$40
beq :+
ldx ch
lda temp
and #$3f
sta ins, x
jmp begnote
:
lda temp
ldx ch
sta dur, x
blank2:
lda temp
cmp #$ff
bne end_advance
lda #$ff
sta nextpat
end_advance:
lda ch
asl
tax
lda patzp
sta patseq, x
lda patzp+1
sta patseq+1, x
rts
.endmacro
add_advance_routine
.macro add_insarp
insarp:
.local end, skip1, beg, skip2
beg:
ldx ch
lda doMacroA, x
beq end
ldx ch
ldy inst_buffer, x
lda insAL, y
sta macroIns
lda insAH, y
sta macroIns+1
ldx ch
ldy mframeA, x
lda (macroIns), y
cmp #$fe
beq skip2
cmp #$ff
bne skip1
iny
lda (macroIns), y
cmp #$ff
beq :+
sta mframeA, x
jmp beg
:
lda #0
sta doMacroA, x
rts
skip1:
sec
sbc #128
sta arp, x
lda #0
sta absarp, x
inc mframeA, x
rts
skip2:
iny
lda (macroIns), y
sta arp, x
lda #$ff
sta absarp, x
inc mframeA, x
inc mframeA, x
end:
rts
.endmacro
add_insarp
.macro add_insduty
insduty:
.local end, skip1, beg, skip2
beg:
ldx ch
lda doMacroD, x
beq end
ldx ch
ldy inst_buffer, x
lda insDL, y
sta macroIns
lda insDH, y
sta macroIns+1
;ldx ch
ldy mframeD, x
lda (macroIns), y
sta temp
cmp #$ff
bne skip1
iny
lda (macroIns), y
cmp #$ff
beq :+
sta mframeD, x
jmp beg
:
lda #0
sta doMacroD, x
rts
skip1:
iny
lda (macroIns), y
sta temp+1
lda abspw, x
bne :+
lda temp+1
sec
sbc #$80
sta temp+1
lda pw_mod_lo, x
clc
adc temp
sta pw_mod_lo, x
lda pw_mod_hi, x
adc temp+1
sta pw_mod_hi, x
inc mframeD, x
inc mframeD, x
rts
:
lda temp
sta duty_lo, x
lda temp+1
sta duty_hi, x
lda #0
sta pw_mod_lo, x
sta pw_mod_hi, x
inc mframeD, x
inc mframeD, x
end:
rts
.endmacro
add_insduty
.macro add_inswave
inswave:
.local end, skip1, beg, skip2
beg:
ldx ch
lda doMacroW, x
beq end
ldx ch
ldy inst_buffer, x
lda insWL, y
sta macroIns
lda insWH, y
sta macroIns+1
ldx ch
ldy mframeW, x
lda (macroIns), y
cmp #$ff
bne skip1
iny
lda (macroIns), y
cmp #$ff
beq :+
sta mframeW, x
jmp beg
:
lda #0
sta doMacroW, x
rts
skip1:
ldx ch
pha
lda wav, x
and #$0f
sta wav, x
pla
ora wav, x
sta wav, x
inc mframeW, x
end:
rts
.endmacro
add_inswave
.macro add_inscut
inscut:
.local end, skip1, beg, skip2
beg:
ldx ch
lda doMacroC, x
beq end
ldx ch
ldy instF, x
lda insCL, y
sta macroIns
lda insCH, y
sta macroIns+1
ldx ch
ldy mframeC, x
lda (macroIns), y
sta temp
cmp #$ff
bne skip1
iny
lda (macroIns), y
cmp #$ff
beq :+
sta mframeC, x
jmp beg
:
lda #0
sta doMacroC, x
rts
skip1:
iny
lda (macroIns), y
sta temp+1
lda absfil, x
bne :+
lda temp+1
sec
sbc #$80
sta temp+1
lda fil_lo, x
clc
adc temp
sta fil_lo, x
lda fil_hi, x
adc temp+1
sta fil_hi, x
jmp :++
:
lda temp
sta fil_lo, x
lda temp+1
sta fil_hi, x
:
inc mframeC, x
inc mframeC, x
end:
rts
.endmacro
add_inscut
.macro cmp16 val1, val2
/*
.if 0
lda val1
sec
sbc val2
php
lda val1+1
sbc val2+1
php
pla
sta macroIns
pla
and #%00000010
ora #%11111101
and macroIns
pha
plp
.else
lda val1
sec
sbc val2
lda val1+1
sbc val2+1
.endif
*/
lda val1
sec
sbc val2
lda val1+1
sbc val2+1
.endmacro
doFinepitch:
lda vibrato_param, x
lsr
lsr
lsr
lsr
clc
adc vibrato_phase, x
and #63
sta vibrato_phase, x
tay
lda vibrato_param, x
and #$0f
ora triangle_lookup, y
tay
; this is NOT a typo!
sec
lda note_pitch_lo, x
sbc finepitch, x
sta temp
lda note_pitch_hi, x
sbc #$fe
sta temp+1
; bcs skip_pitch
; lda #0
; sta temp
; sta temp+1
;skip_pitch:
.repeat 3
lda tri_vibrato_lookup, y
;lsr
;clc
;adc tri_vibrato_lookup, y
eor #$ff
clc
adc temp
sta temp
lda temp+1
adc #$ff
sta temp+1
.endrepeat
rts
.macro add_do_ch
do_ch_jsr:
.local skipHR1, skipHR2, end
ldx ch
lda hrc, x
beq skipHR1
lda #0
sta hrc, x
.if HR_ADSR <> 0
lda env_reset, x
beq :+
lda #0
sta env_reset, x
lda #TEST_AD
sta ad, x
lda #TEST_SR
sta sr, x
lda wav, x
and #255^1
ora test_reset, x
sta wav, x
:
.else
lda inst_buffer, x
tax
lda insFL, x
sta patzp
lda insFH, x
sta patzp+1
ldx ch
ldy #1
lda (patzp), y
sta ad, x
iny
lda (patzp), y
ldy base
sta sr, x
lda wav, x
and #255^1
ora test_reset, x
sta wav, x
.endif
lda #0
sta doMacroA, x
sta doMacroD, x
sta doMacroW, x
skipHR1:
lda hrframe, x
cmp #4
bne :+
jmp skipHR2
:
inc hrframe, x
.if compat_hr = 0
cmp #2
.else
cmp #1
.endif
beq :+
jmp skipHR2
:
ldx ch
; for 1Axx
lda note_temp, x
sta note_n, x
lda #0
sta mframeA, x
sta mframeD, x
sta mframeW, x
lda #$ff
sta doMacroA, x
sta doMacroD, x
sta doMacroW, x
lda inst_buffer, x
tax
lda insFL, x
sta patzp
lda insFH, x
sta patzp+1
ldx ch
ldy #1
lda (patzp), y
sta ad, x
iny
lda (patzp), y
sta sr, x
iny
lda (patzp), y
sta duty_lo, x
iny
lda (patzp), y
sta duty_hi, x
iny
lda (patzp), y
sta flags_temp
and #1
;tay
;lda table_1_to_ff, y
sta abspw, x
lda flags_temp
and #2
beq :+
lda #0
sta pw_mod_lo, x
sta pw_mod_hi, x
:
lda flags_temp
and #4
tay
ldx chipnum
lda res, x
ldx chm
and ch_filter_enable_inv, x
cpy #0
beq :+
ora ch_filter_enable, x
:
ldx chipnum
sta res, x
lda flags_temp
and #8
beq :++
ldx chipnum
lda #0
sta doMacroC, x
lda res, x
and #$0f
ldy #6
ora (patzp), y
sta res, x
iny
lda vol, x
and #$0f
ora (patzp), y
sta vol, x
iny
lda (patzp), y
sta fil_lo_n, x
iny
lda (patzp), y
sta fil_hi_n, x
lda flags_temp
and #32
bne :++
lda triggered_fil, x
beq :+
lda retrigger_fil, x
beq :++
:
lda #$ff
sta triggered_fil, x
lda fil_lo_n, x
sta fil_lo, x
lda fil_hi_n, x
sta fil_hi, x
:
ldx ch
lda inst_buffer, x
cmp inst_prev, x
beq :+
ldx chipnum
lda fil_lo_n, x
sta fil_lo, x
lda fil_hi_n, x
sta fil_hi, x
ldx ch
lda inst_buffer, x
sta inst_prev, x
:
lda flags_temp
and #32
beq :+
ldx ch
lda inst_buffer, x
ldx chipnum
sta instF, x
lda #0
sta mframeC, x
lda #$ff
sta doMacroC, x
lda flags_temp
and #16
lsr
tay
lda table_1_to_ff, y
ldy chipnum
sta absfil, y
:
lda flags_temp
and #64
lsr
lsr
lsr
ldx ch
sta test_reset, x
lda retrigger_pw, x
beq :+
lda #0
sta pw_mod_lo, x
sta pw_mod_hi, x
:
lda mframeW, x
beq :+
ldy #0
lda (patzp), y
and #$0f
sta temp
lda wav, x
and #%11110000
ora #1
ora temp
sta wav, x
jmp skipHR2
:
ldx ch
ldy #0
lda (patzp), y
ora #1
sta wav, x
skipHR2:
rts
.endmacro
add_do_ch
.macro add_do_ch_DIGI
do_ch_DIGI:
.local skipHR1, skipHR2, skipHR_ADSR, end
ldx #3
jsr doFinepitch
.repeat 4
clc
lsr temp+1
ror temp
.endrepeat
lda temp
sta nmi_freq_lo+1
lda temp+1
sta nmi_freq_hi+1
ldx ch
lda hrc, x
beq skipHR1
lda #0
sta hrc, x
sta doMacroA, x
sta doMacroD, x
sta doMacroW, x
skipHR1:
lda hrframe, x
cmp #4
bne :+
jmp skipHR2
:
inc hrframe, x
.if compat_hr = 0
cmp #2
.else
cmp #1
.endif
beq :+
jmp skipHR_ADSR
:
ldx ch
lda #0
sta mframeA, x
sta mframeD, x
sta mframeW, x
lda #$ff
sta doMacroA, x
sta doMacroD, x
sta doMacroW, x
lda inst_buffer, x
tax
lda insSI, x
tax
lda sampleHS, x
sta nmi_add+2
lda #0
sta nmi_add+1
lda sampleHE, x
sta nmi_cmp+1
sta nmi_cmp2+1
skipHR_ADSR:
skipHR2:
rts
.endmacro
.if DIGI <> 0
add_do_ch_DIGI
.endif
.proc playaddr
.if DIGI <> 0
lda #0
sta ldn+1
jsr NMI_BUFFER
.endif
ldx tick_sel
inc tick
lda tick
cmp tick_speeds, x
bcs :+
jmp skipseq
:
lda #0
sta tick
advance_tick:
lda tick_sel
eor #1
sta tick_sel
ldx #(CHIP_AMT)-1
lda #0
:
sta fil_st2, x
dex
bpl :-
.repeat chnum, I
lda #I
sta ch
lda #I/3
sta chipnum
jsr advance
.endrepeat
lda nextpat
beq skipnextpat
lda #0
sta nextpat
lda jumppat
beq :+
lda #0
sta jumppat
jmp :++
:
inc patind
lda patind
cmp #order0len
bne :+
lda #0 ; #patloop
sta patind
:
jsr set_patseq
ldx #chnum-1
lda #1
durloop:
sta dur, x
dex
bpl durloop
jmp advance_tick
skipnextpat:
lda jumppat
beq :+
lda #$ff
sta nextpat
:
skipseq:
.if DIGI = 0
.repeat chnum, I
ldx #I
stx ch
lda #I .mod 3
sta chm
lda #(I .mod 3)*7+(I/3)*$20
sta base
lda #I/3
sta chipnum
jsr do_ch_jsr
ldx ch
lda #$ff
sta env_reset_buf, x
.endrepeat
.else
.repeat 4, I
ldx #I
stx ch
lda #I .mod 3
sta chm
lda #(I .mod 3)*7+(I/3)*$20
sta base
lda #I/3
sta chipnum
.if I = 3
jsr do_ch_DIGI
.else
jsr do_ch_jsr
.endif
ldx ch
lda #$ff
sta env_reset_buf, x
.endrepeat
.endif
.repeat chnum, I
lda #I
sta ch
jsr insarp
jsr inswave
jsr insduty
.endrepeat
.repeat CHIP_AMT, I
lda #I
sta ch
jsr inscut
ldx ch
lda fil_st2, x
beq :+
lda fil_lo_n2, x
sta fil_lo, x
lda fil_hi_n2, x
sta fil_hi, x
:
.endrepeat
ldx #chnum-1
note_cut_loop:
lda cut_dur, x
cmp #$ff
beq note_cut_loop_end
dec cut_dur, x
lda cut_dur, x
bne note_cut_loop_end
lda #$ff
sta cut_dur, x
lda wav, x
and #%11111110
sta wav, x
note_cut_loop_end:
dex
bpl note_cut_loop
ldx #chnum-1
relslide_loop:
lda note_dest, x
and #$80
beq slide_skip
eor note_dest, x
sta macroIns
lda slide_amt_sign, x
beq positive_slide2
lda note_n, x
clc
adc macroIns
jsr clamp_note
sta note_dest, x
jmp slide_skip
positive_slide2:
lda note_n, x
sec
sbc macroIns
jsr clamp_note
sta note_dest, x
slide_skip:
dex
bpl relslide_loop
ldx #chnum-1
note_loop:
lda absarp, x
beq nrel
lda arp, x
and #127
jmp nout
nrel:
lda note_n, x
clc
;adc arp, x
nout:
;clc
jsr add_arpeff
jsr clamp_note
tay
clc
lda note_table_lo, y
adc slide_buffer_lo, x
sta note_pitch_lo, x
lda note_table_hi, y
adc slide_buffer_hi, x
sta note_pitch_hi, x
dex
bpl note_loop
ldx #chnum-1
slide_loop:
lda slide_amt, x
beq slide_loop2
lda slide_amt_sign, x
bne positive_slide
sec
lda slide_buffer_lo, x
sbc slide_amt, x
sta slide_buffer_lo, x
bcs :+
dec slide_buffer_hi, x
:
ldy note_dest, x
lda note_table_lo, y
sec
sbc note_pitch_lo, x
lda note_table_hi, y
sbc note_pitch_hi, x
bcc slide_loop2
jmp finish_slide
positive_slide:
clc
lda slide_buffer_lo, x
adc slide_amt, x
sta slide_buffer_lo, x
bcc :+
inc slide_buffer_hi, x
:
jmp :+
finish_slide:
lda note_dest, x
sta note_n, x
lda #0
sta slide_buffer_lo, x
sta slide_buffer_hi, x
sta slide_amt, x
sta slide_amt_sign, x
jmp slide_loop2
:
ldy note_dest, x
lda note_pitch_lo, x
sec
sbc note_table_lo, y
lda note_pitch_hi, x
sbc note_table_hi, y
bcc slide_loop2
jmp finish_slide
slide_loop2:
dex
bpl slide_loop
ldx #chnum-1
:
lda note_tick, x
cmp #96
beq note_tick_loop
inc note_tick, x
note_tick_loop:
lda has_played, x
bne note_tick_loop2
lda #3
sta note_tick, x
note_tick_loop2:
dex
bpl :-
.if DIGI = 0
lda vol
sta $d418
.if chnum >= 6
lda vol+1
sta $d438
.endif
.if chnum >= 9
lda vol+2
sta $d458
.endif
.if chnum >= 12
lda vol+3
sta $d478
.endif
.endif
lda res
sta $d417
.if chnum >= 6
lda res+1
sta $d437
.endif
.if chnum >= 9
lda res+2
sta $d457
.endif
.if chnum >= 12
lda res+3
sta $d477
.endif
lda fil_lo
sta temp
lda fil_hi
sta temp+1
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
lda temp
sta $d416
.if chnum >= 6
lda fil_lo+1
sta temp
lda fil_hi+1
sta temp+1
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
lda temp
sta $d436
.endif
.if chnum >= 9
lda fil_lo+2
sta temp
lda fil_hi+2
sta temp+1
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
lda temp
sta $d456
.endif
.if chnum >= 12
lda fil_lo+2
sta temp
lda fil_hi+2
sta temp+1
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
clc
lsr temp+1
ror temp
lda temp
sta $d476
.endif
ldx #chnum-1
note_loop3:
lda absarp, x
beq nrel3
lda arp, x
and #127
jmp nout3
nrel3:
lda note_n, x
clc
adc arp, x
nout3:
clc
jsr add_arpeff
jsr clamp_note
tay
clc
lda note_table_lo, y
adc slide_buffer_lo, x
sta note_pitch_lo, x
lda note_table_hi, y
adc slide_buffer_hi, x
sta note_pitch_hi, x
dex
bpl note_loop3
.repeat CHIP_AMT, J
ldx #2
:
txa
clc
adc #J*3
tax
jsr doFinepitch
txa
sec
sbc #J*3
tax
ldy ch_mul_tabl, x
lda temp
sta $d400+J*$20,y
lda temp+1
sta $d401+J*$20, y
lda ad+J*3, x
sta $d405+J*$20, y
lda sr+J*3, x
sta $d406+J*$20, y
lda wav+J*3, x
sta $d404+J*$20, y
lda duty_lo+J*3, x
clc
adc pw_mod_lo+J*3, x
sta $d402+J*$20, y
lda duty_hi+J*3, x
adc pw_mod_hi+J*3, x
and #$0f
sta $d403+J*$20, y
dex
bpl :-
.endrepeat
rts
.endproc
set_patseq:
stx temp+2
ldx patind
.repeat chnum, I
lda .ident(.concat ("order", .sprintf("%d",I), "L")), x
sta patseq+0+2*I
lda .ident(.concat ("order", .sprintf("%d",I), "H")), x
sta patseq+1+2*I
.endrepeat
ldx temp+2
rts
set_patseq_init:
.repeat chnum, I
ldx patind
lda .ident(.concat ("order", .sprintf("%d",I), "L")), x
sta patseq+0+2*I
lda .ident(.concat ("order", .sprintf("%d",I), "H")), x
sta patseq+1+2*I
.endrepeat
rts
add_arpeff:
pha
inc arpind, x
ldy arpind, x
lda arp_mod, y
sta arpind, x
tay
pla
cpy #1
beq arp1
cpy #2
beq arp2
rts
arp1:
clc
adc arpeff1, x
rts
arp2:
clc
adc arpeff2, x
rts
arp_mod:
.byte 0,1,2,0
ch_mul_tabl:
.byte 0,7,14
clamp_note:
cmp #95
bcc :+
lda #95
:
rts
.proc extaddr
sta extin
lda patind
rts
.endproc
note_table_lo:
.incbin "note_lo.bin"
note_table_hi:
.incbin "note_hi.bin"
ch_filter_enable:
.byte 1, 2, 4
ch_filter_enable_inv:
.byte 255^1, 255^2, 255^4
triangle_lookup:
.repeat 64, I
.if (I+0)&32
.byte ((32-(((I+0)&63)-32)-1)>>1)<<4
.else
.byte (((I+0)&63)>>1)<<4
.endif
.endrepeat
tri_vibrato_lookup:
.repeat 16, J
.repeat 16, I
;.byte ((I*((J>>1)-15)*2)/15)+$1f
VAL .set ((I*((J<<1)-15)*2)/3)
.if (VAL+$80) < 0
.byte 0
.elseif (VAL+$80) > 255
.byte $ff
.else
.byte VAL+$80
.endif
.endrepeat
.endrepeat
.include "song.asm"
;.res 4096, $00