I started working on this again, and I implemented a "sample scaling" algorithm to allow a full frequency range of pulse waves without the low notes being effected by Gaussian interpolation.
I also implemented frequency sweeping.
define temp($00)
define tempo_delay($02)
define channel($03)
define key_on($04)
define pitch_mod($05)
define beat($06)
define pattern($07)
define song($09)
define key_off($0a)
define echo($0b)
define noise($0c)
define frequency($0e)
define track($10)
define left_volume($20)
define right_volume($21)
define detune($30)
define pitch($31)
define instrument($40)
define effects($41)
define octave($50)
define sweep($51)
define address($80)
define scale_factor($82)
define blocks_left($83)
define C-0($00)
define D-0($02)
define E-0($04)
define F-0($05)
define G-0($07)
define A-0($09)
define B-0($0b)
define C-1($0c)
define D-1($0e)
define E-1($10)
define F-1($11)
define G-1($13)
define A-1($15)
define B-1($17)
define C-2($18)
define D-2($1a)
define E-2($1c)
define F-2($1d)
define G-2($1f)
define A-2($21)
define B-2($23)
define C-3($24)
define D-3($26)
define E-3($28)
define F-3($29)
define G-3($2b)
define A-3($2d)
define B-3($2f)
define C-4($30)
define D-4($32)
define E-4($34)
define F-4($35)
define G-4($37)
define A-4($39)
define B-4($3b)
define C-5($3c)
define D-5($3e)
define E-5($40)
define F-5($41)
define G-5($43)
define A-5($45)
define B-5($47)
define C-6($48)
define D-6($4a)
define E-6($4c)
define F-6($4d)
define G-6($4f)
define A-6($51)
define B-6($53)
define C-7($54)
define D-7($56)
define E-7($58)
define F-7($59)
define G-7($5b)
define A-7($5d)
define B-7($5e)
str $fa=#$80
str $f1=#$11
str $f2=#$0f
str $f3=#$7f //FIR filter is all pass
str $f2=#$0c
str $f3=#$7f //left volume 100%
str $f2=#$1c
str $f3=#$80 //right volume 100%
str $f2=#$2c
str $f3=#$7f //echo volume 0%
str $f2=#$3c
str $f3=#$7f //echo volume 0%
str $f2=#$6c
str $f3=#$18
str $f2=#$0d
str $f3=#$20 //feedback 0%
str $f2=#$4d
str $f3=#$00 //no channel with echo
str $f2=#$5d
str $f3=#$80 //directory
str $f2=#$6d
str $f3=#$c0 //echo buffer
str $f2=#$7d
str $f3=#$01 //shortest delay possible
str {tempo_delay}=#$08
lda #$00
ldy #$81
stw {address}
ldx #$00
lda #$40
sta {scale_factor}
sample_scaling_loop:
sta {blocks_left}
ldw {address}
sta $8000,x
sta $8002,x
tya
sta $8001,x
sta $8003,x
inx
inx
inx
inx
phx
ldx #$00
ldy #$00
-;
lda wave,x
inx
phx
ldx {scale_factor}
-;
iny
sta ({address}),y
dex
cpy #$08
bne +
dec {blocks_left}
beq ++
pha
ldy #$00
lda #$82
sta ({address}),y
lda #$09
adw {address}
stw {address}
ldy #$00
pla
+;
cpx #$00
bne -
plx
bra --
+;
plx
plx
ldy #$00
lda #$83
sta ({address}),y
lda #$09
adw {address}
stw {address}
lsr {scale_factor}
lda {scale_factor}
bcc sample_scaling_loop
big_loop:
str {beat}=#$20
ldx {song}
lda song+2,x
sta {pattern}
inx
lda song+2,x
sta {pattern}+1
inx
cpx song
bne +
ldx song+1
+;
stx {song}
ldy #$00
ldx #$00
-
lda ({pattern}),y
sta {track},x
iny
inx
cpx #$10
bne -
spc_loop:
lda $fd
beq spc_loop
channel_processing:
str {channel}=#$00
ldx #$00
-;
lda {effects},x
lsr
ror {key_on}
lsr
ror {key_off}
lsr
ror {echo}
lsr
ror {noise}
lsr
ror {pitch_mod}
lda {effects},x
and #$fc
sta {effects},x
lda {channel}
sta $f2
lda {left_volume},x
sta $f3
lda {right_volume},x
inc $f2
sta $f3
lda {detune},x
sta {temp}
lda {pitch},x
phx
ldy #$00
ldx #$0c
div
tax
lda note_scale,y
str {frequency}=#$00
sta {frequency}+1
lda note_scale+1,y
sec
sbc note_scale,y
ldy {temp}
mul
adw {frequency}
pha
lda octave_scale,x
mul
stw {frequency}
lda octave_scale,x
ply
mul
tya
ldy #$00
adw {frequency}
plx
inc $f2
sta $f3
inc $f2
sty $f3
lda {instrument},x
tay
lda instrument_data,y
clc
adc {octave},x
inc $f2
sta $f3
lda instrument_data+1,y
inc $f2
sta $f3
lda instrument_data+2,y
inc $f2
sta $f3
lda instrument_data+3,y
inc $f2
sta $f3
lda {sweep},x
clc
adc {detune},x
sta {detune},x
lda {pitch},x
adc #$00
sta {pitch},x
inx
inx
lda {channel}
clc
adc #$10
sta {channel}
cmp #$80
beq +
jmp -
+;
str $f2=#$5c
str $f3={key_off}
str $f2=#$4d
str $f3={echo}
str $f2=#$2d
str $f3={pitch_mod}
str $f2=#$3d
str $f3={noise}
str $f2=#$4c
str $f3={key_on} //key on
dec {tempo_delay}
beq +
jmp spc_loop
+;
music_tracking:
ldx #$00
-;
lda ({track},x)
sta {effects},x
inc {track},x
lda ({track},x)
sta {left_volume},x
inc {track},x
lda ({track},x)
sta {right_volume},x
inc {track},x
lda ({track},x)
sta {detune},x
inc {track},x
lda ({track},x)
sta {pitch},x
inc {track},x
lda ({track},x)
sta {octave},x
inc {track},x
lda ({track},x)
sta {instrument},x
inc {track},x
lda ({track},x)
sta {sweep},x
inc {track},x
inx
inx
cpx #$10
beq +
jmp -
+;
str {tempo_delay}=#$08
dec {beat}
bne +
jmp big_loop
+;
jmp spc_loop
instrument_data:
db $00,$fe,$a4,$00
song:
db $02,$00
dw pattern
pattern:
dw $4100,$4200,$4000,$4000,$4000,$4000,$4000,$4000
note_scale:
db 64,68,72,76,81,85,91,96,102,108,114,121,128
octave_scale:
db 1,2,4,8,16,32,64,128
wave:
db $88,$88,$88,$88,$88,$77,$77,$77
seek($834000)
//track format: effects, left volume, right volume, detune, pitch, octave, instrument, sweep
track:
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 1,127,127,0,{C-6},4,0,0
db 1,127,127,0,{E-6},4,0,8
db 1,127,127,0,{G-6},4,0,8
db 1,127,127,0,{B-6},4,0,0
db 1,127,127,0,{C-6},4,0,0
db 1,127,127,0,{E-6},4,0,8
db 1,127,127,0,{G-6},4,0,8
db 1,127,127,0,{B-6},4,0,0
db 1,127,127,0,{C-6},4,0,0
db 1,127,127,0,{E-6},4,0,8
db 1,127,127,0,{G-6},4,0,8
db 1,127,127,0,{B-6},4,0,0
db 1,127,127,0,{C-6},4,0,0
db 1,127,127,0,{E-6},4,0,8
db 1,127,127,0,{G-6},4,0,8
db 1,127,127,0,{B-6},4,0,0
db 1,127,127,0,{D-6},4,0,0
db 1,127,127,0,{F-6},4,0,8
db 1,127,127,0,{A-6},4,0,8
db 1,127,127,0,{C-7},4,0,0
db 1,127,127,0,{D-6},4,0,0
db 1,127,127,0,{F-6},4,0,8
db 1,127,127,0,{A-6},4,0,8
db 1,127,127,0,{C-7},4,0,0
db 1,127,127,0,{D-6},4,0,0
db 1,127,127,0,{F-6},4,0,8
db 1,127,127,0,{A-6},4,0,8
db 1,127,127,0,{C-7},4,0,0
db 1,127,127,0,{D-6},4,0,0
db 1,127,127,0,{F-6},4,0,8
db 1,127,127,0,{A-6},4,0,8
db 1,127,127,0,{C-7},4,0,0
db 9,16,8,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,8,4,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,16,8,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,8,4,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,16,8,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,8,4,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,8,4,0,0,0,0,0
db 9,16,8,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 9,8,4,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
db 2,0,0,0,0,0,0,0
seek($838000)
directory: