|
16 | 16 | ;;; You should have received a copy of the GNU Lesser General Public License
|
17 | 17 | ;;; along with ngdevkit. If not, see <http://www.gnu.org/licenses/>.
|
18 | 18 |
|
19 |
| -;;; SSG vibrato effect. This file is included by nss-ssg.s |
| 19 | +;;; Vibrato effect, common functions for FM and SSG |
20 | 20 | ;;;
|
21 | 21 |
|
22 |
| - .equ VIBRATO_SPEED,(state_vibrato_speed-state_mirrored_ssg) |
23 |
| - .equ VIBRATO_DEPTH,(state_vibrato_depth-state_mirrored_ssg) |
24 |
| - .equ VIBRATO_POS,(state_vibrato_pos-state_mirrored_ssg) |
25 |
| - .equ VIBRATO_PREV,(state_vibrato_prev-state_mirrored_ssg) |
26 |
| - .equ VIBRATO_NEXT,(state_vibrato_next-state_mirrored_ssg) |
| 22 | + .module nullsound |
27 | 23 |
|
| 24 | + .include "ym2610.inc" |
| 25 | + .include "struct-fx.inc" |
28 | 26 |
|
29 |
| -;;; Update the vibrato for the current SSG channel |
30 |
| -;;; Vibrato oscillates the current note's frequency between the previou |
| 27 | + .area CODE |
| 28 | + |
| 29 | + |
| 30 | +;;; Setup prev and next increments for vibrato |
| 31 | +;;; ------ |
| 32 | +;;; IN: |
| 33 | +;;; ix : fm state for channel |
| 34 | +;;; the note semitone must be already configured |
| 35 | +;;; [ hl ]: prev semitone distance |
| 36 | +;;; [hl+1]: next semitone distance |
| 37 | +;;; OUT: |
| 38 | +;;; de : prev increment (fixed-point) |
| 39 | +;;; hl : prev increment (fixed-point) |
| 40 | +;;; bc, de, hl modified |
| 41 | +vibrato_setup_increments:: |
| 42 | + ;; bc: prev distance from current note |
| 43 | + push hl ; +(prev distance) |
| 44 | + ld b, (hl) |
| 45 | + ;; de: output prev increment, scaled by depth (a) |
| 46 | + ld a, VIBRATO_DEPTH(ix) |
| 47 | + call vibrato_scale_increment |
| 48 | + ld e, l |
| 49 | + ld d, h |
| 50 | + |
| 51 | + ;; bc: next distance from current note |
| 52 | + pop hl ; (prev distance) |
| 53 | + inc hl |
| 54 | + ld b, (hl) |
| 55 | + ;; hl: output next increment, scaled by depth (a) |
| 56 | + ld a, VIBRATO_DEPTH(ix) |
| 57 | + call vibrato_scale_increment |
| 58 | + |
| 59 | + ret |
| 60 | + |
| 61 | + |
| 62 | +;;; Scale a fixed point 16bit value into x/16 fraction |
| 63 | +;;; ------ |
| 64 | +;;; IN: |
| 65 | +;;; bc : distance |
| 66 | +;;; a : scale factor [1..16] |
| 67 | +;;; OUT: |
| 68 | +;;; hl : scaled base increment |
| 69 | +;;; bc, hl modified |
| 70 | +vibrato_scale_increment: |
| 71 | + ;; bc: base increment (fixed point) |
| 72 | + ;; there are 8 possible levels, so bc = fixed point distance / 8 |
| 73 | + ld c, #0 |
| 74 | + srl b |
| 75 | + rr c |
| 76 | + srl b |
| 77 | + rr c |
| 78 | + srl b |
| 79 | + rr c |
| 80 | + |
| 81 | + ;; scale the base increment based on the vibrato depth |
| 82 | + ;; depth has 16 possible levels [1..16], so parse 4 bits |
| 83 | + ld h, #0 |
| 84 | + ld l, h |
| 85 | + bit 4, a |
| 86 | + jr z, _post_bit4 |
| 87 | + add hl, bc |
| 88 | +_post_bit4: |
| 89 | + ;; shift bc 1 bit to the right |
| 90 | + srl b |
| 91 | + rr c |
| 92 | + bit 3, a |
| 93 | + jr z, _post_bit3 |
| 94 | + add hl, bc |
| 95 | +_post_bit3: |
| 96 | + srl b |
| 97 | + rr c |
| 98 | + bit 2, a |
| 99 | + jr z, _post_bit2 |
| 100 | + add hl, bc |
| 101 | +_post_bit2: |
| 102 | + srl b |
| 103 | + rr c |
| 104 | + bit 1, a |
| 105 | + jr z, _post_bit1 |
| 106 | + add hl, bc |
| 107 | +_post_bit1: |
| 108 | + ret |
| 109 | + |
| 110 | + |
| 111 | +;;; Update the vibrato for the current channel |
| 112 | +;;; Vibrato oscillates the current note's frequency between the previous |
31 | 113 | ;;; and the next semitones of the current note, and follows a sine wave.
|
32 | 114 | ;;; This function update the frequency by one step among the 64 steps
|
33 | 115 | ;;; defined in the sine wave.
|
34 | 116 | ;;; ------
|
35 |
| -;;; hl: mirrored state of the current ssg channel |
36 |
| -eval_ssg_vibrato_step:: |
37 |
| - push hl |
38 |
| - push de |
39 |
| - push bc |
40 |
| - |
41 |
| - ;; ix: mirrored_ssg for current channel |
42 |
| - push hl |
43 |
| - pop ix |
44 |
| - |
| 117 | +;;; IN: |
| 118 | +;;; ix: mirrored state of the current fm channel |
| 119 | +;;; OUT: |
| 120 | +;;; hl: new note for step (FM: f-num, SSG: period) |
| 121 | +;;; bc, de, hl modified |
| 122 | +vibrato_eval_step:: |
45 | 123 | ;; e: next vibrato pos
|
46 | 124 | ld a, VIBRATO_POS(ix)
|
47 | 125 | add a, VIBRATO_SPEED(ix)
|
@@ -106,117 +184,4 @@ _post_mul_a0:
|
106 | 184 | ;; hl: new note
|
107 | 185 | add hl, de
|
108 | 186 |
|
109 |
| - ;; configure SSG channel with new note |
110 |
| - ;; TODO, update the mirror state only |
111 |
| - ld a, (state_ssg_channel) |
112 |
| - sla a |
113 |
| - ld b, a |
114 |
| - ld c, l |
115 |
| - call ym2610_write_port_a |
116 |
| - inc b |
117 |
| - ld c, h |
118 |
| - call ym2610_write_port_a |
119 |
| - |
120 |
| - pop bc |
121 |
| - pop de |
122 |
| - pop hl |
123 |
| - |
124 |
| - ret |
125 |
| - |
126 |
| - |
127 |
| -;;; Setup prev and next increments for vibrato |
128 |
| -;;; ------ |
129 |
| -;;; ix : ssg state for channel |
130 |
| -;;; the note semitone must be already configured |
131 |
| -ssg_vibrato_setup_increments:: |
132 |
| - push bc |
133 |
| - push hl |
134 |
| - |
135 |
| - ;; reset vibrato sine pos |
136 |
| - ld VIBRATO_POS(ix), #0 |
137 |
| - |
138 |
| - ;; bc: prev distance from current note, fix point |
139 |
| - ld hl, #ssg_semitone_distance |
140 |
| - ld l, NOTE_SEMITONE_OFFSET(ix) |
141 |
| - push hl ; +prev distance |
142 |
| - ld b, (hl) |
143 |
| - ld c, #0 |
144 |
| - ;; a: vibrato depth |
145 |
| - ld a, VIBRATO_DEPTH(ix) |
146 |
| - ;; hl: output prev increment, scaled by depth (a) |
147 |
| - ld h, #0 |
148 |
| - ld l, h |
149 |
| - call ssg_vibrato_scale_increment |
150 |
| - ld VIBRATO_PREV(ix), l |
151 |
| - ld VIBRATO_PREV+1(ix), h |
152 |
| - |
153 |
| - ;; bc: next distance |
154 |
| - pop hl ; prev distance |
155 |
| - inc hl |
156 |
| - ld b, (hl) |
157 |
| - ld c, #0 |
158 |
| - ;; a: vibrato depth |
159 |
| - ld a, VIBRATO_DEPTH(ix) |
160 |
| - ;; hl: output next increment, scaled by depth (a) |
161 |
| - ld h, #0 |
162 |
| - ld l, h |
163 |
| - call ssg_vibrato_scale_increment |
164 |
| - ;; hl: -hl (next increment is always negative) |
165 |
| - xor a |
166 |
| - sub l |
167 |
| - ld l, a |
168 |
| - sbc a, a |
169 |
| - sub h |
170 |
| - ld h, a |
171 |
| - ld VIBRATO_NEXT(ix), l |
172 |
| - ld VIBRATO_NEXT+1(ix), h |
173 |
| - |
174 |
| - pop hl |
175 |
| - pop bc |
176 |
| - ret |
177 |
| - |
178 |
| - |
179 |
| -;;; Scale a fixed point 16bit value into x/16 fraction |
180 |
| -;;; ------ |
181 |
| -;;; IN: |
182 |
| -;;; bc : distance |
183 |
| -;;; a : scale factor [1..16] |
184 |
| -;;; OUT: |
185 |
| -;;; hl : scaled base increment |
186 |
| -;;; bc, hl modified |
187 |
| -ssg_vibrato_scale_increment: |
188 |
| - ;; bc: get base increment |
189 |
| - ;; there are 8 possible levels, so bc = distance / 8 |
190 |
| - srl b |
191 |
| - rr c |
192 |
| - srl b |
193 |
| - rr c |
194 |
| - srl b |
195 |
| - rr c |
196 |
| - |
197 |
| - ;; scale the base increment based on the vibrato depth |
198 |
| - ;; depth has 16 possible levels [1..16], so parse 4 bits |
199 |
| - bit 4, a |
200 |
| - jr z, _post_bit4 |
201 |
| - add hl, bc |
202 |
| -_post_bit4: |
203 |
| - ;; shift bc 1 bit to the right |
204 |
| - srl b |
205 |
| - rr c |
206 |
| - bit 3, a |
207 |
| - jr z, _post_bit3 |
208 |
| - add hl, bc |
209 |
| -_post_bit3: |
210 |
| - srl b |
211 |
| - rr c |
212 |
| - bit 2, a |
213 |
| - jr z, _post_bit2 |
214 |
| - add hl, bc |
215 |
| -_post_bit2: |
216 |
| - srl b |
217 |
| - rr c |
218 |
| - bit 1, a |
219 |
| - jr z, _post_bit1 |
220 |
| - add hl, bc |
221 |
| -_post_bit1: |
222 | 187 | ret
|
0 commit comments