224 lines
5.2 KiB
NASM
224 lines
5.2 KiB
NASM
; -----------------------------------------------------------
|
|
; music.asm - SID music driver (adapted from the c64-demo)
|
|
; voice 1: bass (pulse), voice 2: drums (noise),
|
|
; voice 3: echo lead (triangle)
|
|
; music_init: clear SID, set instruments, restart song
|
|
; music_play: call once per frame
|
|
; music_stop: silence everything
|
|
; -----------------------------------------------------------
|
|
|
|
; ---- waveform control values ----
|
|
BASS_ON = $41 ; pulse + gate
|
|
BASS_OFF = $40
|
|
DRUM_ON = $81 ; noise + gate
|
|
DRUM_OFF = $80
|
|
LEAD_ON = $11 ; triangle + gate
|
|
LEAD_OFF = $10
|
|
|
|
SONG_LEN = 128
|
|
|
|
; ---- initialize SID and restart the song ----
|
|
music_init:
|
|
ldx #24
|
|
lda #0
|
|
mi_clr:
|
|
sta SID_BASE,x
|
|
dex
|
|
bpl mi_clr
|
|
|
|
lda #$00 ; bass: instant attack, full sustain
|
|
sta SID_V1AD
|
|
lda #$f3
|
|
sta SID_V1SR
|
|
lda #$08 ; bass pulse width 50%
|
|
sta SID_V1PH
|
|
lda #$00
|
|
sta SID_V1PL
|
|
lda #$04 ; drums: instant attack, ~110 ms decay
|
|
sta SID_V2AD
|
|
lda #$00
|
|
sta SID_V2SR
|
|
lda #$06 ; lead: pluck, ~200 ms decay
|
|
sta SID_V3AD
|
|
lda #$00
|
|
sta SID_V3SR
|
|
|
|
lda #$0f ; master volume = 15
|
|
sta SID_VOL
|
|
|
|
lda #0
|
|
sta mus_row
|
|
sta mus_spd_ix
|
|
sta mus_bcut
|
|
lda #1
|
|
sta mus_tick
|
|
rts
|
|
|
|
; ---- play one tick: called once per frame ----
|
|
music_play:
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
jsr mp_core
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
rts
|
|
|
|
mp_core:
|
|
lda mus_bcut
|
|
beq mp_tick
|
|
dec mus_bcut
|
|
bne mp_tick
|
|
lda #BASS_OFF
|
|
sta SID_V1CR
|
|
mp_tick:
|
|
dec mus_tick
|
|
beq mp_row
|
|
rts
|
|
|
|
mp_row:
|
|
ldx mus_spd_ix
|
|
lda mus_spd_tbl,x
|
|
sta mus_tick
|
|
inx
|
|
cpx #6
|
|
bne mp_spd_ok
|
|
ldx #0
|
|
mp_spd_ok:
|
|
stx mus_spd_ix
|
|
|
|
ldx mus_row
|
|
|
|
; ---- voice 1: bass ----
|
|
lda bass_pat,x
|
|
beq mp_drums
|
|
cmp #1
|
|
bne mp_bass_note
|
|
lda #BASS_OFF
|
|
sta SID_V1CR
|
|
jmp mp_drums
|
|
mp_bass_note:
|
|
and #$7f
|
|
tay
|
|
lda bass_flo,y
|
|
sta SID_V1FL
|
|
lda bass_fhi,y
|
|
sta SID_V1FH
|
|
lda #BASS_OFF
|
|
sta SID_V1CR
|
|
lda #BASS_ON
|
|
sta SID_V1CR
|
|
|
|
; ---- voice 2: drums ----
|
|
mp_drums:
|
|
lda drum_pat,x
|
|
beq mp_lead
|
|
cmp #1
|
|
bne mp_drum_note
|
|
lda #DRUM_OFF
|
|
sta SID_V2CR
|
|
jmp mp_lead
|
|
mp_drum_note:
|
|
and #$7f
|
|
tay
|
|
lda drum_flo,y
|
|
sta SID_V2FL
|
|
lda drum_fhi,y
|
|
sta SID_V2FH
|
|
lda #DRUM_OFF
|
|
sta SID_V2CR
|
|
lda #DRUM_ON
|
|
sta SID_V2CR
|
|
|
|
; ---- voice 3: lead echo ----
|
|
mp_lead:
|
|
lda lead_pat,x
|
|
beq mp_next
|
|
and #$7f
|
|
tay
|
|
lda lead_flo,y
|
|
sta SID_V3FL
|
|
lda lead_fhi,y
|
|
sta SID_V3FH
|
|
lda #LEAD_OFF
|
|
sta SID_V3CR
|
|
lda #LEAD_ON
|
|
sta SID_V3CR
|
|
|
|
mp_next:
|
|
inx
|
|
cpx #SONG_LEN
|
|
bne mp_store
|
|
ldx #0
|
|
stx mus_spd_ix
|
|
mp_store:
|
|
stx mus_row
|
|
lda bass_pat,x
|
|
bpl mp_nocut
|
|
lda mus_tick
|
|
sec
|
|
sbc #2
|
|
sta mus_bcut
|
|
mp_nocut:
|
|
rts
|
|
|
|
; ---- stop: silence SID, restore for SFX use ----
|
|
music_stop:
|
|
ldx #24
|
|
lda #0
|
|
ms_clr:
|
|
sta SID_BASE,x
|
|
dex
|
|
bpl ms_clr
|
|
rts
|
|
|
|
; ---- state ----
|
|
mus_row: !byte 0
|
|
mus_tick: !byte 1
|
|
mus_spd_ix: !byte 0
|
|
mus_bcut: !byte 0
|
|
|
|
mus_spd_tbl: !byte 4,4,4,4,4,4
|
|
|
|
; ---- note tables (PAL SID) ----
|
|
bass_flo: !byte $5a,$e0,$2d,$cf
|
|
bass_fhi: !byte $04,$03,$05,$05
|
|
drum_flo: !byte $9c,$ff
|
|
drum_fhi: !byte $45,$ff
|
|
lead_flo: !byte $ce,$02,$64,$76,$9c,$04,$c8,$eb
|
|
lead_fhi: !byte $22,$1f,$29,$2e,$45,$3e,$52,$5c
|
|
|
|
; ---- pattern data ----
|
|
bass_pat:
|
|
!byte $80,$00,$00,$00,$01,$00,$80,$00,$01,$00,$00,$00,$81,$00,$80,$00
|
|
!byte $01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$01,$00,$80,$00,$01,$00,$00,$00,$81,$00,$80,$00
|
|
!byte $01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$01,$00,$80,$00,$01,$00,$00,$00,$81,$00,$80,$00
|
|
!byte $01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $82,$00,$82,$00,$01,$00,$82,$00,$01,$00,$00,$00,$82,$00,$83,$00
|
|
!byte $01,$00,$83,$00,$01,$00,$83,$00,$83,$00,$01,$00,$83,$00,$01,$00
|
|
drum_pat:
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$80,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$80,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$80,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$80,$00,$81,$00,$00,$00,$00,$00,$00,$00
|
|
lead_pat:
|
|
!byte $00,$00,$80,$00,$00,$00,$00,$00,$84,$00,$00,$00,$00,$00,$81,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $00,$00,$84,$00,$00,$00,$00,$00,$80,$00,$00,$00,$00,$00,$81,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $00,$00,$84,$00,$00,$00,$00,$00,$80,$00,$00,$00,$00,$00,$81,$00
|
|
!byte $80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
!byte $00,$00,$82,$00,$86,$00,$00,$00,$82,$00,$00,$00,$00,$00,$86,$00
|
|
!byte $83,$00,$00,$00,$87,$00,$00,$00,$83,$00,$87,$00,$00,$00,$83,$00
|