Files
rabbitc64/music.asm
T
2026-07-16 12:50:21 +02:00

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