1 // ---------------------------------------------------------------------------
2 // This file is part of reSID, a MOS6581 SID emulator engine.
3 // Copyright (C) 2010 Dag Lem <resid@nimrod.no>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // ---------------------------------------------------------------------------
19
20 #define RESID_FILTER_CC
21
22 #ifdef _M_ARM
23 #undef _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
24 #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1
25 #endif
26
27 #include "filter.h"
28 #include "dac.h"
29 #include "spline.h"
30 #include <math.h>
31
32 namespace reSID
33 {
34
35 // This is the SID 6581 op-amp voltage transfer function, measured on
36 // CAP1B/CAP1A on a chip marked MOS 6581R4AR 0687 14.
37 // All measured chips have op-amps with output voltages (and thus input
38 // voltages) within the range of 0.81V - 10.31V.
39
40 static double_point opamp_voltage_6581[] = {
41 { 0.81, 10.31 }, // Approximate start of actual range
42 { 0.81, 10.31 }, // Repeated point
43 { 2.40, 10.31 },
44 { 2.60, 10.30 },
45 { 2.70, 10.29 },
46 { 2.80, 10.26 },
47 { 2.90, 10.17 },
48 { 3.00, 10.04 },
49 { 3.10, 9.83 },
50 { 3.20, 9.58 },
51 { 3.30, 9.32 },
52 { 3.50, 8.69 },
53 { 3.70, 8.00 },
54 { 4.00, 6.89 },
55 { 4.40, 5.21 },
56 { 4.54, 4.54 }, // Working point (vi = vo)
57 { 4.60, 4.19 },
58 { 4.80, 3.00 },
59 { 4.90, 2.30 }, // Change of curvature
60 { 4.95, 2.03 },
61 { 5.00, 1.88 },
62 { 5.05, 1.77 },
63 { 5.10, 1.69 },
64 { 5.20, 1.58 },
65 { 5.40, 1.44 },
66 { 5.60, 1.33 },
67 { 5.80, 1.26 },
68 { 6.00, 1.21 },
69 { 6.40, 1.12 },
70 { 7.00, 1.02 },
71 { 7.50, 0.97 },
72 { 8.50, 0.89 },
73 { 10.00, 0.81 },
74 { 10.31, 0.81 }, // Approximate end of actual range
75 { 10.31, 0.81 } // Repeated end point
76 };
77
78 // This is the SID 8580 op-amp voltage transfer function, measured on
79 // CAP1B/CAP1A on a chip marked CSG 8580R5 1690 25.
80 static double_point opamp_voltage_8580[] = {
81 { 1.30, 8.91 }, // Approximate start of actual range
82 { 1.30, 8.91 }, // Repeated end point
83 { 4.76, 8.91 },
84 { 4.77, 8.90 },
85 { 4.78, 8.88 },
86 { 4.785, 8.86 },
87 { 4.79, 8.80 },
88 { 4.795, 8.60 },
89 { 4.80, 8.25 },
90 { 4.805, 7.50 },
91 { 4.81, 6.10 },
92 { 4.815, 4.05 }, // Change of curvature
93 { 4.82, 2.27 },
94 { 4.825, 1.65 },
95 { 4.83, 1.55 },
96 { 4.84, 1.47 },
97 { 4.85, 1.43 },
98 { 4.87, 1.37 },
99 { 4.90, 1.34 },
100 { 5.00, 1.30 },
101 { 5.10, 1.30 },
102 { 8.91, 1.30 }, // Approximate end of actual range
103 { 8.91, 1.30 } // Repeated end point
104 };
105
106
107 typedef struct {
108 // Op-amp transfer function.
109 double_point* opamp_voltage;
110 int opamp_voltage_size;
111 // Voice output characteristics.
112 double voice_voltage_range;
113 double voice_DC_voltage;
114 // Capacitor value.
115 double C;
116 // Transistor parameters.
117 double Vdd;
118 double Vth; // Threshold voltage
119 double Ut; // Thermal voltage: Ut = k*T/q = 8.61734315e-5*T ~ 26mV
120 double k; // Gate coupling coefficient: K = Cox/(Cox+Cdep) ~ 0.7
121 double uCox; // u*Cox
122 double WL_vcr; // W/L for VCR
123 double WL_snake; // W/L for "snake"
124 // DAC parameters.
125 double dac_zero;
126 double dac_scale;
127 double dac_2R_div_R;
128 bool dac_term;
129 } model_filter_init_t;
130
131 static model_filter_init_t model_filter_init[2] = {
132 {
133 opamp_voltage_6581,
134 sizeof(opamp_voltage_6581)/sizeof(*opamp_voltage_6581),
135 // The dynamic analog range of one voice is approximately 1.5V,
136 // riding at a DC level of approximately 5.0V.
137 1.5,
138 5.0,
139 // Capacitor value.
140 470e-12,
141 // Transistor parameters.
142 12.18,
143 1.31,
144 26.0e-3,
145 1.0,
146 20e-6,
147 9.0/1,
148 1.0/115,
149 // DAC parameters.
150 6.65,
151 2.63,
152 2.20,
153 false
154 },
155 {
156 opamp_voltage_8580,
157 sizeof(opamp_voltage_8580)/sizeof(*opamp_voltage_8580),
158 // FIXME: Measure for the 8580.
159 1.0,
160 // 4.75,
161 1.30, // FIXME: For now we pretend that the working point is 0V.
162 22e-9,
163 9.09,
164 0.80,
165 26.0e-3,
166 1.0,
167 10e-6,
168 // FIXME: 6581 only
169 0,
170 0,
171 0,
172 0,
173 2.00,
174 true
175 }
176 };
177
178 unsigned short Filter::vcr_kVg[1 << 16];
179 unsigned short Filter::vcr_n_Ids_term[1 << 16];
180
181 #if defined(__amiga__) && defined(__mc68000__)
182 #undef HAS_LOG1P
183 #endif
184
185 #ifndef HAS_LOG1P
log1p(double x)186 static double log1p(double x)
187 {
188 return log(1 + x) - (((1 + x) - 1) - x) / (1 + x);
189 }
190 #endif
191
192 Filter::model_filter_t Filter::model_filter[2];
193
194
195 // ----------------------------------------------------------------------------
196 // Constructor.
197 // ----------------------------------------------------------------------------
Filter()198 Filter::Filter()
199 {
200 static bool class_init;
201
202 if (!class_init) {
203 // Temporary table for op-amp transfer function.
204 unsigned int* voltages = new unsigned int[1 << 16];
205 opamp_t* opamp = new opamp_t[1 << 16];
206
207 for (int m = 0; m < 2; m++) {
208 model_filter_init_t& fi = model_filter_init[m];
209 model_filter_t& mf = model_filter[m];
210
211 // Convert op-amp voltage transfer to 16 bit values.
212 double vmin = fi.opamp_voltage[0][0];
213 double opamp_max = fi.opamp_voltage[0][1];
214 double kVddt = fi.k*(fi.Vdd - fi.Vth);
215 double vmax = kVddt < opamp_max ? opamp_max : kVddt;
216 double denorm = vmax - vmin;
217 double norm = 1.0/denorm;
218
219 // Scaling and translation constants.
220 double N16 = norm*((1u << 16) - 1);
221 double N30 = norm*((1u << 30) - 1);
222 double N31 = norm*((1u << 31) - 1);
223 mf.vo_N16 = (int)(N16); // FIXME: Remove?
224
225 // The "zero" output level of the voices.
226 // The digital range of one voice is 20 bits; create a scaling term
227 // for multiplication which fits in 11 bits.
228 double N14 = norm*(1u << 14);
229 mf.voice_scale_s14 = (int)(N14*fi.voice_voltage_range);
230 mf.voice_DC = (int)(N16*(fi.voice_DC_voltage - vmin));
231
232 // Vdd - Vth, normalized so that translated values can be subtracted:
233 // k*Vddt - x = (k*Vddt - t) - (x - t)
234 mf.kVddt = (int)(N16*(kVddt - vmin) + 0.5);
235
236 // Normalized snake current factor, 1 cycle at 1MHz.
237 // Fit in 5 bits.
238 mf.n_snake = (int)(denorm*(1 << 13)*(fi.uCox/(2*fi.k)*fi.WL_snake*1.0e-6/fi.C) + 0.5);
239
240 // Create lookup table mapping op-amp voltage across output and input
241 // to input voltage: vo - vx -> vx
242 // FIXME: No variable length arrays in ISO C++, hardcoding to max 50
243 // points.
244 // double_point scaled_voltage[fi.opamp_voltage_size];
245 double_point scaled_voltage[50];
246
247 for (int i = 0; i < fi.opamp_voltage_size; i++) {
248 // The target output range is 16 bits, in order to fit in an unsigned
249 // short.
250 //
251 // The y axis is temporarily scaled to 31 bits for maximum accuracy in
252 // the calculated derivative.
253 //
254 // Values are normalized using
255 //
256 // x_n = m*2^N*(x - xmin)
257 //
258 // and are translated back later (for fixed point math) using
259 //
260 // m*2^N*x = x_n - m*2^N*xmin
261 //
262 scaled_voltage[fi.opamp_voltage_size - 1 - i][0] = int(N16*(fi.opamp_voltage[i][1] - fi.opamp_voltage[i][0] + denorm)/2 + 0.5);
263 scaled_voltage[fi.opamp_voltage_size - 1 - i][1] = N31*(fi.opamp_voltage[i][0] - vmin);
264 }
265
266 // Clamp x to 16 bits (rounding may cause overflow).
267 if (scaled_voltage[fi.opamp_voltage_size - 1][0] >= (1 << 16)) {
268 // The last point is repeated.
269 scaled_voltage[fi.opamp_voltage_size - 1][0] =
270 scaled_voltage[fi.opamp_voltage_size - 2][0] = (1 << 16) - 1;
271 }
272
273 interpolate(scaled_voltage, scaled_voltage + fi.opamp_voltage_size - 1,
274 PointPlotter<unsigned int>(voltages), 1.0);
275
276 // Store both fn and dfn in the same table.
277 mf.ak = (int)scaled_voltage[0][0];
278 mf.bk = (int)scaled_voltage[fi.opamp_voltage_size - 1][0];
279 int j;
280 for (j = 0; j < mf.ak; j++) {
281 opamp[j].vx = 0;
282 opamp[j].dvx = 0;
283 }
284 unsigned int f = voltages[j];
285 for (; j <= mf.bk; j++) {
286 unsigned int fp = f;
287 f = voltages[j]; // Scaled by m*2^31
288 // m*2^31*dy/1 = (m*2^31*dy)/(m*2^16*dx) = 2^15*dy/dx
289 int df = f - fp; // Scaled by 2^15
290
291 // 16 bits unsigned: m*2^16*(fn - xmin)
292 opamp[j].vx = f > (0xffff << 15) ? 0xffff : f >> 15;
293 // 16 bits (15 bits + sign bit): 2^11*dfn
294 opamp[j].dvx = df >> (15 - 11);
295 }
296 for (; j < (1 << 16); j++) {
297 opamp[j].vx = 0;
298 opamp[j].dvx = 0;
299 }
300
301 // Create lookup tables for gains / summers.
302
303 // 4 bit "resistor" ladders in the bandpass resonance gain and the audio
304 // output gain necessitate 16 gain tables.
305 // From die photographs of the bandpass and volume "resistor" ladders
306 // it follows that gain ~ vol/8 and 1/Q ~ ~res/8 (assuming ideal
307 // op-amps and ideal "resistors").
308 for (int n8 = 0; n8 < 16; n8++) {
309 int n = n8 << 4; // Scaled by 2^7
310 int x = mf.ak;
311 for (int vi = 0; vi < (1 << 16); vi++) {
312 mf.gain[n8][vi] = solve_gain(opamp, n, vi, x, mf);
313 }
314 }
315
316 // The filter summer operates at n ~ 1, and has 5 fundamentally different
317 // input configurations (2 - 6 input "resistors").
318 //
319 // Note that all "on" transistors are modeled as one. This is not
320 // entirely accurate, since the input for each transistor is different,
321 // and transistors are not linear components. However modeling all
322 // transistors separately would be extremely costly.
323 int offset = 0;
324 int size;
325 for (int k = 0; k < 5; k++) {
326 int idiv = 2 + k; // 2 - 6 input "resistors".
327 int n_idiv = idiv << 7; // n*idiv, scaled by 2^7
328 size = idiv << 16;
329 int x = mf.ak;
330 for (int vi = 0; vi < size; vi++) {
331 mf.summer[offset + vi] = solve_gain(opamp, n_idiv, vi/idiv, x, mf);
332 }
333 offset += size;
334 }
335
336 // The audio mixer operates at n ~ 8/6, and has 8 fundamentally different
337 // input configurations (0 - 7 input "resistors").
338 //
339 // All "on", transistors are modeled as one - see comments above for
340 // the filter summer.
341 offset = 0;
342 size = 1; // Only one lookup element for 0 input "resistors".
343 for (int l = 0; l < 8; l++) {
344 int idiv = l; // 0 - 7 input "resistors".
345 int n_idiv = (idiv << 7)*8/6; // n*idiv, scaled by 2^7
346 if (idiv == 0) {
347 // Avoid division by zero; the result will be correct since
348 // n_idiv = 0.
349 idiv = 1;
350 }
351 int x = mf.ak;
352 for (int vi = 0; vi < size; vi++) {
353 mf.mixer[offset + vi] = solve_gain(opamp, n_idiv, vi/idiv, x, mf);
354 }
355 offset += size;
356 size = (l + 1) << 16;
357 }
358
359 // Create lookup table mapping capacitor voltage to op-amp input voltage:
360 // vc -> vx
361 for (int m = 0; m < (1 << 16); m++) {
362 mf.opamp_rev[m] = opamp[m].vx;
363 }
364
365 mf.vc_max = (int)(N30*(fi.opamp_voltage[0][1] - fi.opamp_voltage[0][0]));
366 mf.vc_min = (int)(N30*(fi.opamp_voltage[fi.opamp_voltage_size - 1][1] - fi.opamp_voltage[fi.opamp_voltage_size - 1][0]));
367
368 // DAC table.
369 int bits = 11;
370 build_dac_table(mf.f0_dac, bits, fi.dac_2R_div_R, fi.dac_term);
371 for (int n = 0; n < (1 << bits); n++) {
372 mf.f0_dac[n] = (unsigned short)(N16*(fi.dac_zero + mf.f0_dac[n]*fi.dac_scale/(1 << bits) - vmin) + 0.5);
373 }
374 }
375
376 // Free temporary tables.
377 delete[] voltages;
378 delete[] opamp;
379
380 // VCR - 6581 only.
381 model_filter_init_t& fi = model_filter_init[0];
382
383 double N16 = model_filter[0].vo_N16;
384 double vmin = N16*fi.opamp_voltage[0][0];
385 double k = fi.k;
386 double kVddt = N16*(k*(fi.Vdd - fi.Vth));
387
388 for (int i = 0; i < (1 << 16); i++) {
389 // The table index is right-shifted 16 times in order to fit in
390 // 16 bits; the argument to sqrt is thus multiplied by (1 << 16).
391 //
392 // The returned value must be corrected for translation. Vg always
393 // takes part in a subtraction as follows:
394 //
395 // k*Vg - Vx = (k*Vg - t) - (Vx - t)
396 //
397 // I.e. k*Vg - t must be returned.
398 double Vg = kVddt - sqrt((double)i*(1 << 16));
399 vcr_kVg[i] = (unsigned short)(k*Vg - vmin + 0.5);
400 }
401
402 /*
403 EKV model:
404
405 Ids = Is*(if - ir)
406 Is = 2*u*Cox*Ut^2/k*W/L
407 if = ln^2(1 + e^((k*(Vg - Vt) - Vs)/(2*Ut))
408 ir = ln^2(1 + e^((k*(Vg - Vt) - Vd)/(2*Ut))
409 */
410 double kVt = fi.k*fi.Vth;
411 double Ut = fi.Ut;
412 double Is = 2*fi.uCox*Ut*Ut/fi.k*fi.WL_vcr;
413 // Normalized current factor for 1 cycle at 1MHz.
414 double N15 = N16/2;
415 double n_Is = N15*1.0e-6/fi.C*Is;
416
417 // kVg_Vx = k*Vg - Vx
418 // I.e. if k != 1.0, Vg must be scaled accordingly.
419 for (int kVg_Vx = 0; kVg_Vx < (1 << 16); kVg_Vx++) {
420 double log_term = log1p(exp((kVg_Vx/N16 - kVt)/(2*Ut)));
421 // Scaled by m*2^15
422 vcr_n_Ids_term[kVg_Vx] = (unsigned short)(n_Is*log_term*log_term);
423 }
424
425 class_init = true;
426 }
427
428 enable_filter(true);
429 set_chip_model(MOS6581);
430 set_voice_mask(0x07);
431 input(0);
432 reset();
433 }
434
435
436 // ----------------------------------------------------------------------------
437 // Enable filter.
438 // ----------------------------------------------------------------------------
enable_filter(bool enable)439 void Filter::enable_filter(bool enable)
440 {
441 enabled = enable;
442 set_sum_mix();
443 }
444
445
446 // ----------------------------------------------------------------------------
447 // Adjust the DAC bias parameter of the filter.
448 // This gives user variable control of the exact CF -> center frequency
449 // mapping used by the filter.
450 // The setting is currently only effective for 6581.
451 // ----------------------------------------------------------------------------
adjust_filter_bias(double dac_bias)452 void Filter::adjust_filter_bias(double dac_bias)
453 {
454 Vw_bias = int(dac_bias*model_filter[sid_model].vo_N16);
455 set_w0();
456 }
457
458 // ----------------------------------------------------------------------------
459 // Set chip model.
460 // ----------------------------------------------------------------------------
set_chip_model(chip_model model)461 void Filter::set_chip_model(chip_model model)
462 {
463 sid_model = model;
464 /* We initialize the state variables again just to make sure that
465 * the earlier model didn't leave behind some foreign, unrecoverable
466 * state. Hopefully set_chip_model() only occurs simultaneously with
467 * reset(). */
468 Vhp = 0;
469 Vbp = Vbp_x = Vbp_vc = 0;
470 Vlp = Vlp_x = Vlp_vc = 0;
471 }
472
473
474 // ----------------------------------------------------------------------------
475 // Mask for voices routed into the filter / audio output stage.
476 // Used to physically connect/disconnect EXT IN, and for test purposes
477 // (voice muting).
478 // ----------------------------------------------------------------------------
set_voice_mask(reg4 mask)479 void Filter::set_voice_mask(reg4 mask)
480 {
481 voice_mask = 0xf0 | (mask & 0x0f);
482 set_sum_mix();
483 }
484
485
486 // ----------------------------------------------------------------------------
487 // SID reset.
488 // ----------------------------------------------------------------------------
reset()489 void Filter::reset()
490 {
491 fc = 0;
492 res = 0;
493 filt = 0;
494 mode = 0;
495 vol = 0;
496
497 Vhp = 0;
498 Vbp = Vbp_x = Vbp_vc = 0;
499 Vlp = Vlp_x = Vlp_vc = 0;
500
501 set_w0();
502 set_Q();
503 set_sum_mix();
504 }
505
506
507 // ----------------------------------------------------------------------------
508 // Register functions.
509 // ----------------------------------------------------------------------------
writeFC_LO(reg8 fc_lo)510 void Filter::writeFC_LO(reg8 fc_lo)
511 {
512 fc = (fc & 0x7f8) | (fc_lo & 0x007);
513 set_w0();
514 }
515
writeFC_HI(reg8 fc_hi)516 void Filter::writeFC_HI(reg8 fc_hi)
517 {
518 fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007);
519 set_w0();
520 }
521
writeRES_FILT(reg8 res_filt)522 void Filter::writeRES_FILT(reg8 res_filt)
523 {
524 res = (res_filt >> 4) & 0x0f;
525 set_Q();
526
527 filt = res_filt & 0x0f;
528 set_sum_mix();
529 }
530
writeMODE_VOL(reg8 mode_vol)531 void Filter::writeMODE_VOL(reg8 mode_vol)
532 {
533 mode = mode_vol & 0xf0;
534 set_sum_mix();
535
536 vol = mode_vol & 0x0f;
537 }
538
539 // Set filter cutoff frequency.
set_w0()540 void Filter::set_w0()
541 {
542 model_filter_t& f = model_filter[sid_model];
543 int Vw = Vw_bias + f.f0_dac[fc];
544 Vddt_Vw_2 = unsigned(f.kVddt - Vw)*unsigned(f.kVddt - Vw) >> 1;
545
546 // FIXME: w0 is temporarily used for MOS 8580 emulation.
547 // MOS 8580 cutoff: 0 - 12.5kHz.
548 // Multiply with 1.048576 to facilitate division by 1 000 000 by right-
549 // shifting 20 times (2 ^ 20 = 1048576).
550 // 1.048576*2*pi*12500 = 82355
551 w0 = 82355*(fc + 1) >> 11;
552 }
553
554 /*
555 Set filter resonance.
556
557 In the MOS 6581, 1/Q is controlled linearly by res. From die photographs
558 of the resonance "resistor" ladder it follows that 1/Q ~ ~res/8
559 (assuming an ideal op-amp and ideal "resistors"). This implies that Q
560 ranges from 0.533 (res = 0) to 8 (res = E). For res = F, Q is actually
561 theoretically unlimited, which is quite unheard of in a filter
562 circuit.
563
564 To obtain Q ~ 1/sqrt(2) = 0.707 for maximally flat frequency response,
565 res should be set to 4: Q = 8/~4 = 8/11 = 0.7272 (again assuming an ideal
566 op-amp and ideal "resistors").
567
568 Q as low as 0.707 is not achievable because of low gain op-amps; res = 0
569 should yield the flattest possible frequency response at Q ~ 0.8 - 1.0
570 in the op-amp's pseudo-linear range (high amplitude signals will be
571 clipped). As resonance is increased, the filter must be clocked more
572 often to keep it stable.
573
574 In the MOS 8580, the resonance "resistor" ladder above the bp feedback
575 op-amp is split in two parts; one ladder for the op-amp input and one
576 ladder for the op-amp feedback.
577
578 input: feedback:
579
580 Rf
581 Ri R4 RC R8 R3
582 R2
583 R1
584
585
586 The "resistors" are switched in as follows by bits in register $17:
587
588 feedback:
589 R1: bit4&!bit5
590 R2: !bit4&bit5
591 R3: bit4&bit5
592 Rf: always on
593
594 input:
595 R4: bit6&!bit7
596 R8: !bit6&bit7
597 RC: bit6&bit7
598 Ri: !(R4|R8|RC) = !(bit6|bit7) = !bit6&!bit7
599
600
601 The relative "resistor" values are approximately (using channel length):
602
603 R1 = 15.3*Ri
604 R2 = 7.3*Ri
605 R3 = 4.7*Ri
606 Rf = 1.4*Ri
607 R4 = 1.4*Ri
608 R8 = 2.0*Ri
609 RC = 2.8*Ri
610
611
612 Approximate values for 1/Q can now be found as follows (assuming an
613 ideal op-amp):
614
615 res feedback input -gain (1/Q)
616 --- -------- ----- ----------
617 0 Rf Ri Rf/Ri = 1/(Ri*(1/Rf)) = 1/0.71
618 1 Rf|R1 Ri (Rf|R1)/Ri = 1/(Ri*(1/Rf+1/R1)) = 1/0.78
619 2 Rf|R2 Ri (Rf|R2)/Ri = 1/(Ri*(1/Rf+1/R2)) = 1/0.85
620 3 Rf|R3 Ri (Rf|R3)/Ri = 1/(Ri*(1/Rf+1/R3)) = 1/0.92
621 4 Rf R4 Rf/R4 = 1/(R4*(1/Rf)) = 1/1.00
622 5 Rf|R1 R4 (Rf|R1)/R4 = 1/(R4*(1/Rf+1/R1)) = 1/1.10
623 6 Rf|R2 R4 (Rf|R2)/R4 = 1/(R4*(1/Rf+1/R2)) = 1/1.20
624 7 Rf|R3 R4 (Rf|R3)/R4 = 1/(R4*(1/Rf+1/R3)) = 1/1.30
625 8 Rf R8 Rf/R8 = 1/(R8*(1/Rf)) = 1/1.43
626 9 Rf|R1 R8 (Rf|R1)/R8 = 1/(R8*(1/Rf+1/R1)) = 1/1.56
627 A Rf|R2 R8 (Rf|R2)/R8 = 1/(R8*(1/Rf+1/R2)) = 1/1.70
628 B Rf|R3 R8 (Rf|R3)/R8 = 1/(R8*(1/Rf+1/R3)) = 1/1.86
629 C Rf RC Rf/RC = 1/(RC*(1/Rf)) = 1/2.00
630 D Rf|R1 RC (Rf|R1)/RC = 1/(RC*(1/Rf+1/R1)) = 1/2.18
631 E Rf|R2 RC (Rf|R2)/RC = 1/(RC*(1/Rf+1/R2)) = 1/2.38
632 F Rf|R3 RC (Rf|R3)/RC = 1/(RC*(1/Rf+1/R3)) = 1/2.60
633
634
635 These data indicate that the following function for 1/Q has been
636 modeled in the MOS 8580:
637
638 1/Q = 2^(1/2)*2^(-x/8) = 2^(1/2 - x/8) = 2^((4 - x)/8)
639
640 */
set_Q()641 void Filter::set_Q()
642 {
643 // Cutoff for MOS 6581.
644 // The coefficient 8 is dispensed of later by right-shifting 3 times
645 // (2 ^ 3 = 8).
646 _8_div_Q = ~res & 0x0f;
647
648 // FIXME: Temporary cutoff code for MOS 8580.
649 // 1024*1/Q = 1024*2^((4 - res)/8)
650 // The coefficient 1024 is dispensed of later by right-shifting 10 times
651 // (2 ^ 10 = 1024).
652 static const int _1024_div_Q_table[] = {
653 1448,
654 1328,
655 1218,
656 1117,
657 1024,
658 939,
659 861,
660 790,
661 724,
662 664,
663 609,
664 558,
665 512,
666 470,
667 431,
668 395
669 };
670
671 _1024_div_Q = _1024_div_Q_table[res];
672 }
673
674 // Set input routing bits.
set_sum_mix()675 void Filter::set_sum_mix()
676 {
677 // NB! voice3off (mode bit 7) only affects voice 3 if it is routed directly
678 // to the mixer.
679 sum = (enabled ? filt : 0x00) & voice_mask;
680 mix =
681 (enabled ? (mode & 0x70) | ((~(filt | (mode & 0x80) >> 5)) & 0x0f) : 0x0f)
682 & voice_mask;
683 }
684
685 } // namespace reSID
686