2 ; Copyright (C) 2004, 2005 Kent Hansen.
4 ; This file is part of Neotoxin.
6 ; Neotoxin is free software; you can redistribute it and/or modify
7 ; it under the terms of the GNU General Public License as published by
8 ; the Free Software Foundation; either version 2 of the License, or
9 ; (at your option) any later version.
11 ; Neotoxin is distributed in the hope that it will be useful,
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ; GNU General Public License for more details.
16 ; You should have received a copy of the GNU General Public License
17 ; along with this program; if not, write to the Free Software
18 ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 ; MOD-style music effect generators.
23 ; Each effect modifies the period in a certain way.
31 .
include <common
/tablecall.h
>
44 .extrn
period_table_lo:byte
45 .extrn
period_table_hi:byte
46 .extrn
mixer:mixer_state
47 .extrn
tracks:track_state
48 .extrn
table_call:proc
50 ; Do one tick of effect.
51 ; Params: X = channel number
54 lda mixer.tonals.effect.kind
,x
58 TC_SLOT slide_down_tick
59 TC_SLOT portamento_tick
62 TC_SLOT volume_slide_tick
68 ; Command 0 is no effect.
74 ;-------------------------[ Vibrato implementation ]--------------------------
78 lda mixer.tonals.effect.vibrato.counter
,x
80 dec mixer.tonals.effect.vibrato.counter
,x
84 ; reset channel frequency
85 lda mixer.tonals.period_index
,x
89 lda mixer.tonals.effect.vibrato.pos
,x
95 ; *** convert sine value to real delta freq, according to vibrato depth ***
100 lda mixer.tonals.effect.vibrato.param
,x
101 and #
$0F ; VibratoDepth in lower 4 bits
104 ; this loop performs SineValue*VibratoDepth
114 ; this stores the result of (SineValue*VibratoDepth)/128 in temp.hi
118 lda mixer.tonals.effect.vibrato.pos
,x
123 lda mixer.tonals.period.lo
,x
126 sta mixer.tonals.period.lo
,x
128 dec mixer.tonals.period.hi
,x
132 lda mixer.tonals.period.lo
,x
135 sta mixer.tonals.period.lo
,x
137 inc mixer.tonals.period.hi
,x
140 ; increment vibrato pos
141 lda mixer.tonals.effect.vibrato.param
,x
147 adc mixer.tonals.effect.vibrato.pos
,x
; add VibratoSpeed to VibratoPos
148 sta mixer.tonals.effect.vibrato.pos
,x
152 ; ProTracker sine table used for vibrato
155 .
db $00,$18,$31,$4A,$61,$78,$8D,$A1
156 .
db $B4,$C5,$D4,$E0,$EB,$F4,$FA,$FD
157 .
db $FF,$FD,$FA,$F4,$EB,$E0,$D4,$C5
158 .
db $B4,$A1,$8D,$78,$61,$4A,$31,$18
160 ;----------------------[ Slide to note implementation ]-----------------------
162 .
proc portamento_tick
163 lda mixer.tonals.effect.portamento.ctrl
,x
164 bpl
@@portamento_exit
166 bcc
@@portamento_down
169 ; check if slide frequency has been reached
170 lda mixer.tonals.period.lo
,x
171 cmp mixer.tonals.effect.portamento.target.lo
,x
172 lda mixer.tonals.period.hi
,x
173 sbc mixer.tonals.effect.portamento.target.hi
,x
174 bpl
@@portamento_exit
178 lda mixer.tonals.effect.portamento.target.lo
,x
179 sta mixer.tonals.period.lo
,x
180 lda mixer.tonals.effect.portamento.target.hi
,x
181 sta mixer.tonals.period.hi
,x
184 sta mixer.tonals.effect.portamento.ctrl
,x
189 ; check if slide frequency has been reached
190 lda mixer.tonals.period.lo
,x
191 cmp mixer.tonals.effect.portamento.target.lo
,x
192 lda mixer.tonals.period.hi
,x
193 sbc mixer.tonals.effect.portamento.target.hi
,x
194 bpl
@@portamento_done
200 ;-----------------------[ Slide down implementation ]-------------------------
202 .
proc slide_down_tick
203 ; slide down by adding slide amount to channel frequency
204 lda mixer.tonals.period.lo
,x
206 adc mixer.tonals.effect.slide.amount
,x
207 sta mixer.tonals.period.lo
,x
209 inc mixer.tonals.period.hi
,x
213 ;------------------------[ Slide up implementation ]--------------------------
216 ; slide up by subtracting slide amount from channel frequency
217 lda mixer.tonals.period.lo
,x
219 sbc mixer.tonals.effect.slide.amount
,x
220 sta mixer.tonals.period.lo
,x
222 dec mixer.tonals.period.hi
,x
226 ;------------------------[ Arpeggio implementation ]--------------------------
229 lda mixer.tonals.effect.arpeggio.pos
,x
241 lda mixer.tonals.period_index
,x
245 lda mixer.tonals.effect.arpeggio.param
,x
251 adc mixer.tonals.period_index
,x
255 lda mixer.tonals.effect.arpeggio.param
,x
258 adc mixer.tonals.period_index
,x
262 lda period_table_lo
,y
263 sta mixer.tonals.period.lo
,x
264 lda period_table_hi
,y
265 sta mixer.tonals.period.hi
,x
267 inc mixer.tonals.effect.arpeggio.pos
,x
268 lda mixer.tonals.effect.arpeggio.pos
,x
272 sta mixer.tonals.effect.arpeggio.pos
,x
276 ;------------------------[ Volume slide implementation ]--------------------------
278 .
proc volume_slide_tick
279 lda mixer.tonals.effect.slide.amount
,x
283 lda mixer.envelopes.master
,x
285 sbc mixer.tonals.effect.slide.amount
,x
288 ++ sta mixer.envelopes.master
,x
291 + lda mixer.tonals.effect.slide.amount
,x
297 adc mixer.envelopes.master
,x
300 ++ sta mixer.envelopes.master
,x
304 ;------------------------[ Tremolo implementation ]--------------------------
308 lda mixer.tonals.effect.tremolo.pos
,x
317 lda mixer.tonals.effect.tremolo.param
,x
318 and #
$0F ; TremoloDepth in lower 4 bits
321 ; this loop performs SineValue*TremoloDepth
331 ; compute (SineValue*TremoloDepth)/16
341 lda mixer.tonals.effect.tremolo.pos
,x
351 + sta mixer.envelopes.master
,x
360 + sta mixer.envelopes.master
,x
363 lda mixer.tonals.effect.tremolo.param
,x
; speed in upper 4 bits
369 adc mixer.tonals.effect.tremolo.pos
,x
370 sta mixer.tonals.effect.tremolo.pos
,x
375 ; Reusing the vibrato struct because I'm lazy...
377 lda mixer.tonals.effect.vibrato.pos
,x
378 cmp mixer.tonals.effect.vibrato.param
,x
381 inc mixer.tonals.effect.vibrato.pos
,x
385 sta mixer.tonals.period.lo
,x
386 sta mixer.tonals.period.hi
,x
390 ; ------ Pulse width (duty cycle) modulation
391 ; NB: can only be used on channels 0 and 1
392 ; Reusing the vibrato struct because I'm lazy...
397 sta mixer.tonals.square.counter
,x
398 lda mixer.tonals.effect.vibrato.param
,x
; new duty cycle in lower 2 bits
403 sta mixer.tonals.square.duty_ctrl
,x