-
Notifications
You must be signed in to change notification settings - Fork 1
/
s5b.s
238 lines (228 loc) · 3.71 KB
/
s5b.s
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
;
; Sunsoft 5B expansion sound
;
ft_init_s5b:
lda #$40
sta var_ch_DutyDefault + S5B_OFFSET
sta var_ch_DutyDefault + S5B_OFFSET + 1
sta var_ch_DutyDefault + S5B_OFFSET + 2
lda #$FF
sta var_Noise_Prev
sta var_AutoEnv_Channel
lda #$00
sta var_EnvelopeRate
sta var_EnvelopeRate + 1
lda #$07
sta $C000
lda #%00111000
sta var_Pul_Noi
sta $E000 ; see n163.s
rts
ft_update_s5b:
lda var_PlayerFlags
bne :+
ldx #$08
stx $C000
sta $E000
inx
stx $C000
sta $E000
inx
stx $C000
sta $E000
rts
:
ldx #$00
stx var_Pul_Noi
@UpdateNoise:
lda var_ch_Trigger + S5B_OFFSET, x
beq :+
lda var_ch_DutyCurrent + S5B_OFFSET, x
bpl :+ ; no noise
and #$1F
sta var_Noise_Period
: inx
cpx #CH_COUNT_S5B
bcc @UpdateNoise
ldx #(CH_COUNT_S5B - 1)
@UpdateNoiseMask:
asl var_Pul_Noi
lda var_ch_DutyCurrent + S5B_OFFSET, x
bmi :+
inc var_Pul_Noi
: dex
bpl @UpdateNoiseMask
ldx #(CH_COUNT_S5B - 1)
@UpdateToneMask:
asl var_Pul_Noi
lda var_ch_DutyCurrent + S5B_OFFSET, x
and #$40
bne :+
inc var_Pul_Noi
: dex
bpl @UpdateToneMask
.if .defined(USE_LINEARPITCH) ;;; ;; ;
lda var_SongFlags
and #FLAG_LINEARPITCH
beq :+
jsr ft_load_ntsc_table
ldx #S5B_OFFSET
jsr ft_linear_fetch_pitch
jsr ft_linear_fetch_pitch
jsr ft_linear_fetch_pitch
:
.endif ; ;; ;;;
ldx #$00
ldy #$00
@ChannelLoop:
lda var_ch_Note + S5B_OFFSET, x ; Kill channel if note = off
bne :+
txa
ora #$08
; clc
; adc #$08
sta $C000
lda #$00
sta $E000
iny
iny
bpl @S5B_next ; always
; Load volume
: txa
ora #$08
; clc
; adc #$08
sta $C000
lda var_ch_VolColumn + S5B_OFFSET, x
beq @StoreVolume
lsr a
lsr a
lsr a
sta var_Temp
lda var_ch_Volume + S5B_OFFSET, x
beq @StoreVolume
clc
adc var_Temp
sec
sbc #$0F
sec
sbc var_ch_TremoloResult + S5B_OFFSET, x
bpl :+
lda #$00
: bne :+
lda var_ch_VolColumn + S5B_OFFSET, x
beq :+
lda #$01
:
@StoreVolume:
; Volume / envelope enable
sta var_Temp
lda var_ch_DutyCurrent + S5B_OFFSET, x
and #$20 ; E
lsr
ora var_Temp
sta $E000
; Frequency
inc var_ch_PeriodCalcLo + S5B_OFFSET, x ; correction
bne :+
inc var_ch_PeriodCalcHi + S5B_OFFSET, x
: sty $C000
iny
lda var_ch_PeriodCalcLo + S5B_OFFSET, x
sta $E000
sty $C000
iny
lda var_ch_PeriodCalcHi + S5B_OFFSET, x
sta $E000
lda var_ch_DutyCurrent + S5B_OFFSET, x
and #$20
beq @S5B_next
lda var_ch_Trigger + S5B_OFFSET, x
beq @S5B_next
sta var_EnvelopeTrigger ; should be 1 anyway
@S5B_next:
inx
cpx #CH_COUNT_S5B
bcs :+
jmp @ChannelLoop
:
; Global variables
ldx #$06
lda var_Noise_Period
eor #$1F
cmp var_Noise_Prev
beq :+
sta var_Noise_Prev
stx $C000
sta $E000
: inx
stx $C000
lda var_Pul_Noi
sta $E000
ldx var_AutoEnv_Channel
bpl @AutoEnv
ldx #$0B
stx $C000
lda var_EnvelopeRate
sta $E000
inx
stx $C000
lda var_EnvelopeRate + 1
sta $E000
jmp @Finished
@AutoEnv:
lda var_ch_PeriodCalcLo, x
sta var_Temp16
lda var_ch_PeriodCalcHi, x
sta var_Temp16 + 1
lda var_EnvelopeType ;;; ;; ; 050B
lsr
lsr
lsr
lsr
cmp #$08
beq @Write
bcc @LowerOctave
@RaiseOctave:
sec
sbc #$08
tay
: lsr var_Temp16 + 1
ror var_Temp16
dey
bne :-
bcc @Write
inc var_Temp16
bne @Write
inc var_Temp16 + 1
bne @Write ; always
@LowerOctave:
sta var_Temp
sec
lda #$08
sbc var_Temp
tay
: asl var_Temp16
rol var_Temp16 + 1
dey
bne :-
@Write:
ldx #$0B
stx $C000
lda var_Temp16
sta $E000
inx
stx $C000
lda var_Temp16 + 1
sta $E000
@Finished:
lda var_EnvelopeTrigger
beq :+
lda #$00
sta var_EnvelopeTrigger
lda #$0D
sta $C000
lda var_EnvelopeType
and #$0F
sta $E000
: rts