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