-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmusic.inc
173 lines (156 loc) · 3.18 KB
/
music.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#importonce
.filenamespace music
.import source "delay.inc"
.import source "pseudocommands.inc"
.import source "music_data.inc"
.import source "init.inc"
.const MELODY_LENGTH = 64
.macro @MUSIC_ZP() {
@music_zp_start:
.errorif (*) != music_lo, "music_lo must be at " + music_lo
.errorif (*+1) != music_hi, "music_lo must be at " + (music_hi+1)
.byte 0
.byte 0 // pattern nr
@music_zp_end:
}
.macro @MUSIC_DATA() {
@music_registers:
// voice 1
.word 0 // freq
.word 0 // pw
.byte $00 // ctrl
.byte $00, $fb // adsr
// voice 2
.word 0 // freq
.word $00c0 // pw
.byte $00 // ctrl
.byte $5b, $0b // adsr
// voice 3
.word 0 // freq
.word $0500 // pw
.byte $11 // ctrl
.byte 0, $7b // adsr
// filter
.byte $00 // cutoff (low)
.byte $00 // cutoff (high)
.byte $f1 // filter resonance & voices
.byte $1f // filter mode
@three:
.byte 3
@fe_or_ff:
.byte $ff, $fe, $fe, $fe
@transposes: TRANSPOSES()
@c1: C1()
@c2: C2()
@c3: C3()
@filt_ofs: FILT_OFS()
@sound_pattern_ofs: SND_PAT_OFS()
@filter_data: SND_PAT_DATA()
@melody: MELODY()
@freq_lo:
.fill 128-12, 0
.byte 140, 254, 194, 223, 88, 52, 120, 43, 83, 247, 31, 210
@freq_hi:
.fill 128-12, 0
.byte 91, 96, 102, 108, 115, 122, 129, 137, 145, 153, 163, 172
}
.macro @MUSIC_INIT_DATA() {
lda #$00
.for (var addr = music_zp_start; addr < music_zp_end; addr++) {
sta addr
}
ldx #$7f-12
!:
lda freq_hi+12, x
lsr
sta freq_hi, x
lda freq_lo+12, x
ror
sta freq_lo, x
dex
bpl !-
}
.macro @MUSIC_INIT_IO() {
ldx #$18
!:
lda music_registers, x
sta $d400, x
dex
bpl !-
}
.macro @MUSIC() {
lax music_lo
bit three
beq note_start
inx
bne to_skip
inc music_hi
// new pattern
ldx music_hi
lda transposes, x
sta transpose
lda c2, x
sta c2_ctrl
to_skip:
jmp skip
note_start:
ldx music_hi
cpx #c2 - c1
bcs noplay
lsr
lsr
pha
alr #$03<<1
tay // full_note & 3
adc sound_pattern_ofs, x
tax
lda #$01
// clc
sbc filter_data, x
sta v1_offset
ldx music_hi
lda c1, x
and fe_or_ff, y
sta $d404 + 7*0
lda c3, x
sta $d404 + 7*2
tya
clc
adc filt_ofs, x
tay
lda filter_data, y
sta $d416
pla
tay // half_note
lax melody, y
bmi skip
adc @transpose:#$00
tax
lda freq_lo + BASE, x
sta $d400 + 7 * 2
lda freq_hi + BASE, x
sta $d401 + 7 * 2
lda c2_ctrl:#$00
beq skipv2
ldy freq_lo + 12*4 + BASE, x
sty $d400 + 7 * 1
ldy freq_hi + 12*4 + BASE, x
sty $d401 + 7 * 1
ldy music_lo
bpl nov2
and #$fe // remove gate bit
nov2:
sta $d404 + 7 * 1
skipv2:
txa
.label @v1_offset = * + 1
sbx #$00
lda freq_lo + BASE, x
adc #$00
sta $d400 + 7 * 0
lda freq_hi + BASE, x
sta $d401 + 7 * 0
skip:
inc music_lo
noplay:
}