Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1088 | alone | 1 | /*************************************************************************** |
2 | |||
3 | Philips SAA1099 Sound driver |
||
4 | |||
5 | By Juergen Buchmueller and Manuel Abadia |
||
6 | |||
7 | SAA1099 register layout: |
||
8 | ======================== |
||
9 | |||
10 | offs | 7654 3210 | description |
||
11 | -----+-----------+--------------------------- |
||
12 | 0x00 | ---- xxxx | Amplitude channel 0 (left) |
||
13 | 0x00 | xxxx ---- | Amplitude channel 0 (right) |
||
14 | 0x01 | ---- xxxx | Amplitude channel 1 (left) |
||
15 | 0x01 | xxxx ---- | Amplitude channel 1 (right) |
||
16 | 0x02 | ---- xxxx | Amplitude channel 2 (left) |
||
17 | 0x02 | xxxx ---- | Amplitude channel 2 (right) |
||
18 | 0x03 | ---- xxxx | Amplitude channel 3 (left) |
||
19 | 0x03 | xxxx ---- | Amplitude channel 3 (right) |
||
20 | 0x04 | ---- xxxx | Amplitude channel 4 (left) |
||
21 | 0x04 | xxxx ---- | Amplitude channel 4 (right) |
||
22 | 0x05 | ---- xxxx | Amplitude channel 5 (left) |
||
23 | 0x05 | xxxx ---- | Amplitude channel 5 (right) |
||
24 | | | |
||
25 | 0x08 | xxxx xxxx | Frequency channel 0 |
||
26 | 0x09 | xxxx xxxx | Frequency channel 1 |
||
27 | 0x0a | xxxx xxxx | Frequency channel 2 |
||
28 | 0x0b | xxxx xxxx | Frequency channel 3 |
||
29 | 0x0c | xxxx xxxx | Frequency channel 4 |
||
30 | 0x0d | xxxx xxxx | Frequency channel 5 |
||
31 | | | |
||
32 | 0x10 | ---- -xxx | Channel 0 octave select |
||
33 | 0x10 | -xxx ---- | Channel 1 octave select |
||
34 | 0x11 | ---- -xxx | Channel 2 octave select |
||
35 | 0x11 | -xxx ---- | Channel 3 octave select |
||
36 | 0x12 | ---- -xxx | Channel 4 octave select |
||
37 | 0x12 | -xxx ---- | Channel 5 octave select |
||
38 | | | |
||
39 | 0x14 | ---- ---x | Channel 0 frequency enable (0 = off, 1 = on) |
||
40 | 0x14 | ---- --x- | Channel 1 frequency enable (0 = off, 1 = on) |
||
41 | 0x14 | ---- -x-- | Channel 2 frequency enable (0 = off, 1 = on) |
||
42 | 0x14 | ---- x--- | Channel 3 frequency enable (0 = off, 1 = on) |
||
43 | 0x14 | ---x ---- | Channel 4 frequency enable (0 = off, 1 = on) |
||
44 | 0x14 | --x- ---- | Channel 5 frequency enable (0 = off, 1 = on) |
||
45 | | | |
||
46 | 0x15 | ---- ---x | Channel 0 noise enable (0 = off, 1 = on) |
||
47 | 0x15 | ---- --x- | Channel 1 noise enable (0 = off, 1 = on) |
||
48 | 0x15 | ---- -x-- | Channel 2 noise enable (0 = off, 1 = on) |
||
49 | 0x15 | ---- x--- | Channel 3 noise enable (0 = off, 1 = on) |
||
50 | 0x15 | ---x ---- | Channel 4 noise enable (0 = off, 1 = on) |
||
51 | 0x15 | --x- ---- | Channel 5 noise enable (0 = off, 1 = on) |
||
52 | | | |
||
53 | 0x16 | ---- --xx | Noise generator parameters 0 |
||
54 | 0x16 | --xx ---- | Noise generator parameters 1 |
||
55 | | | |
||
56 | 0x18 | --xx xxxx | Envelope generator 0 parameters |
||
57 | 0x18 | x--- ---- | Envelope generator 0 control enable (0 = off, 1 = on) |
||
58 | 0x19 | --xx xxxx | Envelope generator 1 parameters |
||
59 | 0x19 | x--- ---- | Envelope generator 1 control enable (0 = off, 1 = on) |
||
60 | | | |
||
61 | 0x1c | ---- ---x | All channels enable (0 = off, 1 = on) |
||
62 | 0x1c | ---- --x- | Synch & Reset generators |
||
63 | |||
64 | ***************************************************************************/ |
||
65 | |||
66 | #include "../std.h" |
||
67 | #include "../emul.h" |
||
68 | #include "../vars.h" |
||
69 | |||
70 | #include "saa1099.h" |
||
71 | |||
72 | |||
73 | #define LEFT 0x00 |
||
74 | #define RIGHT 0x01 |
||
75 | |||
76 | static const int amplitude_lookup[16] = |
||
77 | { |
||
78 | 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16, |
||
79 | 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16, |
||
80 | 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16, |
||
81 | 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16 |
||
82 | }; |
||
83 | |||
84 | static const UINT8 envelope[8][64] = |
||
85 | { |
||
86 | /* zero amplitude */ |
||
87 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
88 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
89 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
90 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
||
91 | /* maximum amplitude */ |
||
92 | {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, |
||
93 | 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, |
||
94 | 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, |
||
95 | 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, }, |
||
96 | /* single decay */ |
||
97 | {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
98 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
99 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
100 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
||
101 | /* repetitive decay */ |
||
102 | {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
103 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
104 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
105 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, |
||
106 | /* single triangular */ |
||
107 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
108 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
109 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
110 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
||
111 | /* repetitive triangular */ |
||
112 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
113 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, |
||
114 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
115 | 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, |
||
116 | /* single attack */ |
||
117 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
118 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
119 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
120 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
||
121 | /* repetitive attack */ |
||
122 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
123 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
124 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, |
||
125 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 } |
||
126 | }; |
||
127 | |||
128 | static void saa1099_envelope(saa1099_state *saa, int ch) |
||
129 | { |
||
130 | if (saa->env_enable[ch]) |
||
131 | { |
||
132 | int step, mode, mask; |
||
133 | /* step from 0..63 and then loop in steps 32..63 */ |
||
134 | step = saa->env_step[ch] = |
||
135 | ((saa->env_step[ch] + 1) & 0x3f) | (saa->env_step[ch] & 0x20); |
||
136 | |||
137 | mode = saa->env_mode[ch]; |
||
138 | |||
139 | if(saa->env_upd[ch]) |
||
140 | { |
||
141 | if( |
||
142 | ((mode == 1 || mode == 3 || mode == 7) && step && ((step & 0xF) == 0)) // 1, 3, 7 |
||
143 | || |
||
144 | ((mode == 5) && step && ((step & 0x1F) == 0)) // 5 |
||
145 | || |
||
146 | ((mode == 0 || mode == 2 || mode == 6) && step > 0x0F) // 0, 2, 6 |
||
147 | || |
||
148 | ((mode == 4) && step > 0x1F) // 4 |
||
149 | ) |
||
150 | { |
||
151 | mode = saa->env_mode[ch] = saa->env_mode_buf[ch]; |
||
152 | saa->env_reverse_right[ch] = saa->env_reverse_right_buf[ch]; |
||
153 | saa->env_clock[ch] = saa->env_clock_buf[ch]; |
||
154 | |||
155 | /* reset the envelope */ |
||
156 | saa->env_step[ch] = 1; |
||
157 | step = 1; |
||
158 | saa->env_upd[ch] = false; |
||
159 | } |
||
160 | } |
||
161 | |||
162 | mask = 15; |
||
163 | if (saa->env_bits[ch]) |
||
164 | mask &= ~1; /* 3 bit resolution, mask LSB */ |
||
165 | |||
166 | saa->channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask; |
||
167 | if (saa->env_reverse_right[ch] & 0x01) |
||
168 | { |
||
169 | saa->channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask; |
||
170 | } |
||
171 | else |
||
172 | { |
||
173 | saa->channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask; |
||
174 | } |
||
175 | } |
||
176 | else |
||
177 | { |
||
178 | /* envelope mode off, set all envelope factors to 16 */ |
||
179 | saa->channels[ch*3+0].envelope[ LEFT] = |
||
180 | saa->channels[ch*3+1].envelope[ LEFT] = |
||
181 | saa->channels[ch*3+2].envelope[ LEFT] = |
||
182 | saa->channels[ch*3+0].envelope[RIGHT] = |
||
183 | saa->channels[ch*3+1].envelope[RIGHT] = |
||
184 | saa->channels[ch*3+2].envelope[RIGHT] = 16; |
||
185 | } |
||
186 | } |
||
187 | |||
188 | |||
189 | void TSaa1099::update(unsigned TimeStamp) |
||
190 | { |
||
191 | saa1099_state *saa = this; |
||
192 | int ch; |
||
193 | |||
194 | /* if the channels are disabled we're done */ |
||
195 | if (!saa->all_ch_enable) |
||
196 | { |
||
197 | /* init output data */ |
||
198 | SNDRENDER::update(TimeStamp, 0, 0); |
||
199 | return; |
||
200 | } |
||
201 | |||
202 | for (ch = 0; ch < 2; ch++) |
||
203 | { |
||
204 | switch (saa->noise_params[ch]) |
||
205 | { |
||
206 | case 0: saa->noise[ch].freq = 31250.0 * 2; break; |
||
207 | case 1: saa->noise[ch].freq = 15625.0 * 2; break; |
||
208 | case 2: saa->noise[ch].freq = 7812.5 * 2; break; |
||
209 | case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; |
||
210 | } |
||
211 | } |
||
212 | |||
213 | /* fill all data needed */ |
||
214 | int output_l = 0, output_r = 0; |
||
215 | |||
216 | /* for each channel */ |
||
217 | for (ch = 0; ch < 6; ch++) |
||
218 | { |
||
219 | if (saa->channels[ch].freq == 0.0) |
||
220 | saa->channels[ch].freq = (double)((2*15625) << saa->channels[ch].octave) / |
||
221 | (511.0 - (double)saa->channels[ch].frequency); |
||
222 | |||
223 | /* check the actual position in the square wave */ |
||
224 | saa->channels[ch].counter -= saa->channels[ch].freq; |
||
225 | while (saa->channels[ch].counter < 0) |
||
226 | { |
||
227 | /* calculate new frequency now after the half wave is updated */ |
||
228 | saa->channels[ch].freq = (double)((2*15625) << saa->channels[ch].octave) / |
||
229 | (511.0 - (double)saa->channels[ch].frequency); |
||
230 | |||
231 | saa->channels[ch].counter += saa->sample_rate; |
||
232 | saa->channels[ch].level ^= 1; |
||
233 | |||
234 | /* eventually clock the envelope counters */ |
||
235 | if (ch == 1 && saa->env_clock[0] == 0) |
||
236 | saa1099_envelope(saa, 0); |
||
237 | if (ch == 4 && saa->env_clock[1] == 0) |
||
238 | saa1099_envelope(saa, 1); |
||
239 | } |
||
240 | |||
241 | /* if the noise is enabled */ |
||
242 | if (saa->channels[ch].noise_enable) |
||
243 | { |
||
244 | /* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */ |
||
245 | if (saa->noise[ch/3].level & 1) |
||
246 | { |
||
247 | /* subtract to avoid overflows, also use only half amplitude */ |
||
248 | output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2; |
||
249 | output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2; |
||
250 | } |
||
251 | } |
||
252 | |||
253 | /* if the square wave is enabled */ |
||
254 | if (saa->channels[ch].freq_enable) |
||
255 | { |
||
256 | /* if the channel level is high */ |
||
257 | if (saa->channels[ch].level & 1) |
||
258 | { |
||
259 | output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16; |
||
260 | output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16; |
||
261 | } |
||
262 | } |
||
263 | else if((ch == 2 || ch == 5) && saa->env_enable[ch/3]) |
||
264 | { |
||
265 | output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16; |
||
266 | output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16; |
||
267 | } |
||
268 | } |
||
269 | |||
270 | for (ch = 0; ch < 2; ch++) |
||
271 | { |
||
272 | /* check the actual position in noise generator */ |
||
273 | saa->noise[ch].counter -= saa->noise[ch].freq; |
||
274 | while (saa->noise[ch].counter < 0) |
||
275 | { |
||
276 | saa->noise[ch].counter += saa->sample_rate; |
||
277 | if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) ) |
||
278 | saa->noise[ch].level = (saa->noise[ch].level << 1) | 1; |
||
279 | else |
||
280 | saa->noise[ch].level <<= 1; |
||
281 | } |
||
282 | } |
||
283 | |||
284 | /* write sound data to the buffer */ |
||
285 | unsigned mix_l = unsigned(output_l / 6); |
||
286 | unsigned mix_r = unsigned(output_r / 6); |
||
287 | if ((mix_l ^ SNDRENDER::mix_l) | (mix_r ^ SNDRENDER::mix_r)) // similar check inside update() |
||
288 | SNDRENDER::update(TimeStamp, mix_l, mix_r); |
||
289 | } |
||
290 | |||
291 | static const u32 SAM_SAA1099_CLK = 8000000; // Hz |
||
292 | |||
293 | TSaa1099::TSaa1099() |
||
294 | { |
||
295 | saa1099_state *saa = this; |
||
296 | |||
297 | memset(saa, 0, sizeof(saa1099_state)); |
||
298 | |||
299 | /* copy global parameters */ |
||
300 | saa1099_state::sample_rate = SAM_SAA1099_CLK / 256; // 31250 Hz |
||
301 | |||
302 | for(unsigned ch = 0; ch < 6; ch++) |
||
303 | { |
||
304 | saa->channels[ch].envelope[ LEFT] = |
||
305 | saa->channels[ch].envelope[RIGHT] = 16; |
||
306 | } |
||
307 | } |
||
308 | |||
309 | void TSaa1099::WrCtl(u8 data) |
||
310 | { |
||
311 | saa1099_state *saa = this; |
||
312 | |||
313 | saa->selected_reg = data & 0x1f; |
||
314 | if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19) |
||
315 | { |
||
316 | /* clock the envelope channels */ |
||
317 | if (saa->env_clock[0]) |
||
318 | saa1099_envelope(saa,0); |
||
319 | if (saa->env_clock[1]) |
||
320 | saa1099_envelope(saa,1); |
||
321 | } |
||
322 | } |
||
323 | |||
324 | |||
325 | void TSaa1099::WrData(unsigned TimeStamp, u8 data) |
||
326 | { |
||
327 | saa1099_state *saa = this; |
||
328 | int reg = saa->selected_reg; |
||
329 | int ch; |
||
330 | |||
331 | /* first update the stream to this point in time */ |
||
332 | if(TimeStamp) |
||
333 | flush((TimeStamp * chip_clock_rate) / system_clock_rate); |
||
334 | |||
335 | switch (reg) |
||
336 | { |
||
337 | /* channel i amplitude */ |
||
338 | case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: |
||
339 | ch = reg & 7; |
||
340 | saa->channels[ch].amp[LEFT] = data & 0x0f; |
||
341 | saa->channels[ch].amp[RIGHT] = (data >> 4) & 0x0f; |
||
342 | |||
343 | saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; |
||
344 | saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; |
||
345 | |||
346 | if(ch == 0) |
||
347 | { |
||
348 | if(saa->env_enable[0]) |
||
349 | { |
||
350 | saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT] & ~1]; |
||
351 | saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT] & ~1]; |
||
352 | } |
||
353 | else |
||
354 | { |
||
355 | saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT]]; |
||
356 | saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT]]; |
||
357 | } |
||
358 | } |
||
359 | else if(ch == 1) |
||
360 | { |
||
361 | if(saa->env_enable[1]) |
||
362 | { |
||
363 | saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT] & ~1]; |
||
364 | saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT] & ~1]; |
||
365 | } |
||
366 | else |
||
367 | { |
||
368 | saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT]]; |
||
369 | saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT]]; |
||
370 | } |
||
371 | } |
||
372 | break; |
||
373 | /* channel i frequency */ |
||
374 | case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: |
||
375 | ch = reg & 7; |
||
376 | saa->channels[ch].frequency = data & 0xff; |
||
377 | break; |
||
378 | /* channel i octave */ |
||
379 | case 0x10: case 0x11: case 0x12: |
||
380 | ch = (reg - 0x10) << 1; |
||
381 | saa->channels[ch + 0].octave = data & 0x07; |
||
382 | saa->channels[ch + 1].octave = (data >> 4) & 0x07; |
||
383 | break; |
||
384 | /* channel i frequency enable */ |
||
385 | case 0x14: |
||
386 | saa->channels[0].freq_enable = data & 0x01; |
||
387 | saa->channels[1].freq_enable = data & 0x02; |
||
388 | saa->channels[2].freq_enable = data & 0x04; |
||
389 | saa->channels[3].freq_enable = data & 0x08; |
||
390 | saa->channels[4].freq_enable = data & 0x10; |
||
391 | saa->channels[5].freq_enable = data & 0x20; |
||
392 | break; |
||
393 | /* channel i noise enable */ |
||
394 | case 0x15: |
||
395 | saa->channels[0].noise_enable = data & 0x01; |
||
396 | saa->channels[1].noise_enable = data & 0x02; |
||
397 | saa->channels[2].noise_enable = data & 0x04; |
||
398 | saa->channels[3].noise_enable = data & 0x08; |
||
399 | saa->channels[4].noise_enable = data & 0x10; |
||
400 | saa->channels[5].noise_enable = data & 0x20; |
||
401 | break; |
||
402 | /* noise generators parameters */ |
||
403 | case 0x16: |
||
404 | saa->noise_params[0] = data & 0x03; |
||
405 | saa->noise_params[1] = (data >> 4) & 0x03; |
||
406 | break; |
||
407 | /* envelope generators parameters */ |
||
408 | case 0x18: case 0x19: |
||
409 | ch = reg - 0x18; |
||
410 | |||
411 | // direct |
||
412 | saa->env_bits[ch] = data & 0x10; |
||
413 | saa->env_enable[ch] = data & 0x80; |
||
414 | if(!(data & 0x80)) |
||
415 | saa->env_step[ch] = 0; // reset envelope |
||
416 | |||
417 | // buffered |
||
418 | saa->env_reverse_right_buf[ch] = data & 0x01; |
||
419 | saa->env_mode_buf[ch] = (data >> 1) & 0x07; |
||
420 | saa->env_clock_buf[ch] = data & 0x20; |
||
421 | saa->env_upd[ch] = true; |
||
422 | |||
423 | |||
424 | if(ch == 0) |
||
425 | { |
||
426 | if(saa->env_enable[0]) |
||
427 | { |
||
428 | saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT] & ~1]; |
||
429 | saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT] & ~1]; |
||
430 | } |
||
431 | else |
||
432 | { |
||
433 | saa->channels[2].amplitude[LEFT] = amplitude_lookup[saa->channels[2].amp[LEFT]]; |
||
434 | saa->channels[2].amplitude[RIGHT] = amplitude_lookup[saa->channels[2].amp[RIGHT]]; |
||
435 | } |
||
436 | } |
||
437 | |||
438 | else if(ch == 1) |
||
439 | { |
||
440 | if(saa->env_enable[1]) |
||
441 | { |
||
442 | saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT] & ~1]; |
||
443 | saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT] & ~1]; |
||
444 | } |
||
445 | else |
||
446 | { |
||
447 | saa->channels[5].amplitude[LEFT] = amplitude_lookup[saa->channels[5].amp[LEFT]]; |
||
448 | saa->channels[5].amplitude[RIGHT] = amplitude_lookup[saa->channels[5].amp[RIGHT]]; |
||
449 | } |
||
450 | } |
||
451 | break; |
||
452 | /* channels enable & reset generators */ |
||
453 | case 0x1c: |
||
454 | saa->all_ch_enable = data & 0x01; |
||
455 | saa->sync_state = data & 0x02; |
||
456 | if (data & 0x02) |
||
457 | { |
||
458 | int i; |
||
459 | |||
460 | /* Synch & Reset generators */ |
||
461 | for (i = 0; i < 6; i++) |
||
462 | { |
||
463 | saa->channels[i].level = 0; |
||
464 | saa->channels[i].counter = 0.0; |
||
465 | } |
||
466 | } |
||
467 | break; |
||
468 | default: /* Error! */ |
||
469 | ; |
||
470 | } |
||
471 | } |
||
472 | |||
473 | void TSaa1099::start_frame(bufptr_t dst) |
||
474 | { |
||
475 | SNDRENDER::start_frame(dst); |
||
476 | } |
||
477 | |||
478 | unsigned TSaa1099::end_frame(unsigned clk_ticks) |
||
479 | { |
||
480 | uint64_t end_chip_tick = ((passed_clk_ticks + clk_ticks) * chip_clock_rate) / system_clock_rate; |
||
481 | |||
482 | flush((unsigned)(end_chip_tick - passed_chip_ticks)); |
||
483 | |||
484 | unsigned Val = SNDRENDER::end_frame(t); |
||
485 | |||
486 | passed_clk_ticks += clk_ticks; |
||
487 | passed_chip_ticks += t; |
||
488 | t = 0; |
||
489 | |||
490 | return Val; |
||
491 | } |
||
492 | |||
493 | void TSaa1099::flush(unsigned chiptick) |
||
494 | { |
||
495 | while(t < chiptick) |
||
496 | { |
||
497 | t++; |
||
498 | update(t); |
||
499 | } |
||
500 | } |
||
501 | |||
502 | void TSaa1099::set_timings(unsigned system_clock_rate, unsigned chip_clock_rate, unsigned sample_rate) |
||
503 | { |
||
504 | chip_clock_rate /= 256; |
||
505 | |||
506 | TSaa1099::system_clock_rate = system_clock_rate; |
||
507 | TSaa1099::chip_clock_rate = chip_clock_rate; |
||
508 | TSaa1099::saa1099_state::sample_rate = chip_clock_rate; |
||
509 | |||
510 | SNDRENDER::set_timings(chip_clock_rate, sample_rate); |
||
511 | passed_chip_ticks = passed_clk_ticks = 0; |
||
512 | t = 0; |
||
513 | } |
||
514 | |||
515 | void TSaa1099::reset(unsigned TimeStamp) |
||
516 | { |
||
517 | WrCtl(0x1C); |
||
518 | WrData(TimeStamp, 2); |
||
519 | } |
||
520 | |||
521 | TSaa1099 Saa1099; |