Skip to content

Instantly share code, notes, and snippets.

@alannakelly
Created August 27, 2020 19:19
Show Gist options
  • Save alannakelly/f2bea45c39b94b06c36d7aeef35cb6d6 to your computer and use it in GitHub Desktop.
Save alannakelly/f2bea45c39b94b06c36d7aeef35cb6d6 to your computer and use it in GitHub Desktop.
ACME assembler source for a bare minimum C64 music sequencer. Single Voice only.
!to "music.prg", cbm
IRQ_VECTOR = $fffe
!macro push {
pha
txa
pha
tya
pha
}
!macro pull {
pla
tay
pla
tax
pla
}
!macro next_raster_irq .line, .vector {
lda #.line ;Next
sta $d012
lda #$ff
sta $d019 ;Ack
+poke16 IRQ_VECTOR, .vector
}
!macro stabilize {
+poke16 IRQ_VECTOR, .wedge
inc $d012
lda #1
sta $d019
tsx
cli
nop
nop
nop
nop
nop
nop
nop
nop
.wedge
txs
ldx #$8
dex
bne *-1
bit $0
lda $d012
cmp $d012
beq *+2
}
!macro init_raster_irq .irq {
sei
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda #$01
sta $d01a
lda #$1b
sta $d011
lda #$35
sta $01
+next_raster_irq 250, .irq
cli
}
; Puts an 8-bit value at .mem
!macro poke .mem, .v {
lda #.v
sta .mem
}
; Puts a 16-bit value at .mem
!macro poke16 .mem, .v {
lda #<.v
sta .mem
lda #>.v
sta .mem+1
}
!macro border .c {
lda #.c
sta $d020
}
; ZERO PAGE
COUNTDOWN=$40
POS=$41
; CONSTANTS
NOTE_C=0
NOTE_CS=1
NOTE_D=2
NOTE_DS=3
NOTE_E=4
NOTE_F=5
NOTE_FS=6
NOTE_G=7
NOTE_GS=8
NOTE_A=9
NOTE_AS=10
NOTE_B=11
O1=0
O2=12
O3=24
O4=36
O5=48
O6=60
O7=72
O8=84
REST_25=254
LOOP=255
*=$0801
; BASIC Autoboot
!08 $0c, $08, $0a, $00, $9e, $20, $32, $33, $30, $34, $00, $00, $00
* = $0900
lda #1
sta COUNTDOWN
lda #0
sta POS
sta $d020
sta $d021
lda #7
sta $d418
+init_raster_irq music_irq
jmp *
music_irq:
+push
+border 1
clv
dec COUNTDOWN
bne next_frame
jsr note_off
lda POS
inc POS
tax
lda TUNE,x
bmi command ; Negative is command
jsr note_on
bvc next_frame
command:
cmp #LOOP
beq +
jsr rest
bvc next_frame
+
lda #0
sta POS
lda #1
sta COUNTDOWN
next_frame:
+next_raster_irq 250, music_irq
+border 0
+pull
rti
note_on:
; Note frequency
tax
lda PAL_LO,x
sta $d400
lda PAL_HI,x
sta $d401
; Pulse Width ~50%
lda #$ff
sta $d402
lda #$07
sta $d403
; ADSR
lda #$09
sta $d405
lda #$00
sta $d406
; Duration
lda #50
sta COUNTDOWN
; Gate On
lda #65
sta $d404
rts
note_off:
; Gate off
lda #0
sta $d404
rts
rest:
lda #25
sta COUNTDOWN
rts
!align 255,0
TUNE:
!08 NOTE_C+O4, REST_25, NOTE_D+O4, REST_25, NOTE_E+O4, REST_25, NOTE_F+O4, REST_25, NOTE_G+O4, REST_25, NOTE_A+O4, REST_25, NOTE_B+O4, REST_25, NOTE_C+O5, REST_25, LOOP
!align 255,0
PAL_LO:
; C C# D D# E F F# G G# A A# B
!08 $17,$27,$39,$4b,$5f,$74,$8a,$a1,$ba,$d4,$f0,$0e ; 1
!08 $2d,$4e,$71,$96,$be,$e8,$14,$43,$74,$a9,$e1,$1c ; 2
!08 $5a,$9c,$e2,$2d,$7c,$cf,$28,$85,$e8,$52,$c1,$37 ; 3
!08 $b4,$39,$c5,$5a,$f7,$9e,$4f,$0a,$d1,$a3,$82,$6e ; 4
!08 $68,$71,$8a,$b3,$ee,$3c,$9e,$15,$a2,$46,$04,$dc ; 5
!08 $d0,$e2,$14,$67,$dd,$79,$3c,$29,$44,$8d,$08,$b8 ; 6
!08 $a1,$c5,$28,$cd,$ba,$f1,$78,$53,$87,$1a,$10,$71 ; 7
!08 $42,$89,$4f,$9b,$74,$e2,$f0,$a6,$0e,$33,$20,$ff ; 8
!align 255,0
PAL_HI:
; C C# D D# E F F# G G# A A# B
!08 $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$02 ; 1
!08 $02,$02,$02,$02,$02,$02,$03,$03,$03,$03,$03,$04 ; 2
!08 $04,$04,$04,$05,$05,$05,$06,$06,$06,$07,$07,$08 ; 3
!08 $08,$09,$09,$0a,$0a,$0b,$0c,$0d,$0d,$0e,$0f,$10 ; 4
!08 $11,$12,$13,$14,$15,$17,$18,$1a,$1b,$1d,$1f,$20 ; 5
!08 $22,$24,$27,$29,$2b,$2e,$31,$34,$37,$3a,$3e,$41 ; 6
!08 $45,$49,$4e,$52,$57,$5c,$62,$68,$6e,$75,$7c,$83 ; 7
!08 $8b,$93,$9c,$a5,$af,$b9,$c4,$d0,$dd,$ea,$f8,$ff ; 8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment