libsidplayfp  2.15.0
filter8580new.h
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 #ifndef RESID_FILTER_H
21 #define RESID_FILTER_H
22 
23 #include "resid-config.h"
24 
25 #include <cassert>
26 #include <cstdlib>
27 
28 namespace reSID
29 {
30 
31 // ----------------------------------------------------------------------------
32 // The SID filter is modeled with a two-integrator-loop biquadratic filter,
33 // which has been confirmed by Bob Yannes to be the actual circuit used in
34 // the SID chip.
35 //
36 // Measurements show that excellent emulation of the SID filter is achieved,
37 // except when high resonance is combined with high sustain levels.
38 // In this case the SID op-amps are performing less than ideally and are
39 // causing some peculiar behavior of the SID filter. This however seems to
40 // have more effect on the overall amplitude than on the color of the sound.
41 //
42 // The theory for the filter circuit can be found in "Microelectric Circuits"
43 // by Adel S. Sedra and Kenneth C. Smith.
44 // The circuit is modeled based on the explanation found there except that
45 // an additional inverter is used in the feedback from the bandpass output,
46 // allowing the summer op-amp to operate in single-ended mode. This yields
47 // filter outputs with levels independent of Q, which corresponds with the
48 // results obtained from a real SID.
49 //
50 // We have been able to model the summer and the two integrators of the circuit
51 // to form components of an IIR filter.
52 // Vhp is the output of the summer, Vbp is the output of the first integrator,
53 // and Vlp is the output of the second integrator in the filter circuit.
54 //
55 // According to Bob Yannes, the active stages of the SID filter are not really
56 // op-amps. Rather, simple NMOS inverters are used. By biasing an inverter
57 // into its region of quasi-linear operation using a feedback resistor from
58 // input to output, a MOS inverter can be made to act like an op-amp for
59 // small signals centered around the switching threshold.
60 //
61 // In 2008, Michael Huth facilitated closer investigation of the SID 6581
62 // filter circuit by publishing high quality microscope photographs of the die.
63 // Tommi Lempinen has done an impressive work on re-vectorizing and annotating
64 // the die photographs, substantially simplifying further analysis of the
65 // filter circuit.
66 //
67 // The filter schematics below are reverse engineered from these re-vectorized
68 // and annotated die photographs. While the filter first depicted in reSID 0.9
69 // is a correct model of the basic filter, the schematics are now completed
70 // with the audio mixer and output stage, including details on intended
71 // relative resistor values. Also included are schematics for the NMOS FET
72 // voltage controlled resistors (VCRs) used to control cutoff frequency, the
73 // DAC which controls the VCRs, the NMOS op-amps, and the output buffer.
74 //
75 //
76 // SID 6581 filter / mixer / output
77 // --------------------------------
78 //
79 // ---------------------------------------------------
80 // | |
81 // | --1R1-- \-- D7 |
82 // | ---R1-- | | |
83 // | | | |--2R1-- \--| D6 |
84 // | ------------<A]-----| | $17 |
85 // | | |--4R1-- \--| D5 1=open | (3.5R1)
86 // | | | | |
87 // | | --8R1-- \--| D4 | (7.0R1)
88 // | | | |
89 // $17 | | (CAP2B) | (CAP1B) |
90 // 0=to mixer | --R8-- ---R8-- ---C---| ---C---|
91 // 1=to filter | | | | | | | |
92 // ------R8--|-----[A>--|--Rw-----[A>--|--Rw-----[A>--|
93 // ve (EXT IN) | | | |
94 // D3 \ ---------------R8--| | | (CAP2A) | (CAP1A)
95 // | v3 | | vhp | vbp | vlp
96 // D2 | \ -----------R8--| ----- | |
97 // | | v2 | | | |
98 // D1 | | \ -------R8--| | ---------------- |
99 // | | | v1 | | | |
100 // D0 | | | \ ---R8-- | | ---------------------------
101 // | | | | | | |
102 // R6 R6 R6 R6 R6 R6 R6
103 // | | | | $18 | | | $18
104 // | \ | | D7: 1=open \ \ \ D6 - D4: 0=open
105 // | | | | | | |
106 // --------------------------------- 12V
107 // |
108 // | D3 --/ --1R4-- |
109 // | ---R8-- | | ---R3-- |
110 // | | | D2 |--/ --2R4--| | | ||--
111 // ------[A>---------| |-----[A>-----||
112 // D1 |--/ --4R4--| (4.25R2) ||--
113 // $18 | | |
114 // 0=open D0 --/ --8R4-- (8.75R2) |
115 //
116 // vo (AUDIO
117 // OUT)
118 //
119 //
120 // v1 - voice 1
121 // v2 - voice 2
122 // v3 - voice 3
123 // ve - ext in
124 // vhp - highpass output
125 // vbp - bandpass output
126 // vlp - lowpass output
127 // vo - audio out
128 // [A> - single ended inverting op-amp (self-biased NMOS inverter)
129 // Rn - "resistors", implemented with custom NMOS FETs
130 // Rw - cutoff frequency resistor (VCR)
131 // C - capacitor
132 //
133 // Notes:
134 //
135 // R2 ~ 2.0*R1
136 // R6 ~ 6.0*R1
137 // R8 ~ 8.0*R1
138 // R24 ~ 24.0*R1
139 //
140 // The Rn "resistors" in the circuit are implemented with custom NMOS FETs,
141 // probably because of space constraints on the SID die. The silicon substrate
142 // is laid out in a narrow strip or "snake", with a strip length proportional
143 // to the intended resistance. The polysilicon gate electrode covers the entire
144 // silicon substrate and is fixed at 12V in order for the NMOS FET to operate
145 // in triode mode (a.k.a. linear mode or ohmic mode).
146 //
147 // Even in "linear mode", an NMOS FET is only an approximation of a resistor,
148 // as the apparant resistance increases with increasing drain-to-source
149 // voltage. If the drain-to-source voltage should approach the gate voltage
150 // of 12V, the NMOS FET will enter saturation mode (a.k.a. active mode), and
151 // the NMOS FET will not operate anywhere like a resistor.
152 //
153 //
154 //
155 // NMOS FET voltage controlled resistor (VCR)
156 // ------------------------------------------
157 //
158 // Vw
159 //
160 // |
161 // |
162 // R1
163 // |
164 // --R1--|
165 // | __|__
166 // | -----
167 // | | |
168 // vi ---------- -------- vo
169 // | |
170 // ----R24----
171 //
172 //
173 // vi - input
174 // vo - output
175 // Rn - "resistors", implemented with custom NMOS FETs
176 // Vw - voltage from 11-bit DAC (frequency cutoff control)
177 //
178 // Notes:
179 //
180 // An approximate value for R24 can be found by using the formula for the
181 // filter cutoff frequency:
182 //
183 // FCmin = 1/(2*pi*Rmax*C)
184 //
185 // Assuming that a the setting for minimum cutoff frequency in combination with
186 // a low level input signal ensures that only negligible current will flow
187 // through the transistor in the schematics above, values for FCmin and C can
188 // be substituted in this formula to find Rmax.
189 // Using C = 470pF and FCmin = 220Hz (measured value), we get:
190 //
191 // FCmin = 1/(2*pi*Rmax*C)
192 // Rmax = 1/(2*pi*FCmin*C) = 1/(2*pi*220*470e-12) ~ 1.5MOhm
193 //
194 // From this it follows that:
195 // R24 = Rmax ~ 1.5MOhm
196 // R1 ~ R24/24 ~ 64kOhm
197 // R2 ~ 2.0*R1 ~ 128kOhm
198 // R6 ~ 6.0*R1 ~ 384kOhm
199 // R8 ~ 8.0*R1 ~ 512kOhm
200 //
201 // Note that these are only approximate values for one particular SID chip,
202 // due to process variations the values can be substantially different in
203 // other chips.
204 //
205 //
206 //
207 // Filter frequency cutoff DAC
208 // ---------------------------
209 //
210 //
211 // 12V 10 9 8 7 6 5 4 3 2 1 0 VGND
212 // | | | | | | | | | | | | | Missing
213 // 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R termination
214 // | | | | | | | | | | | | |
215 // Vw ----R---R---R---R---R---R---R---R---R---R---R-- ---
216 //
217 // Bit on: 12V
218 // Bit off: 5V (VGND)
219 //
220 // As is the case with all MOS 6581 DACs, the termination to (virtual) ground
221 // at bit 0 is missing.
222 //
223 // Furthermore, the control of the two VCRs imposes a load on the DAC output
224 // which varies with the input signals to the VCRs. This can be seen from the
225 // VCR figure above.
226 //
227 //
228 //
229 // "Op-amp" (self-biased NMOS inverter)
230 // ------------------------------------
231 //
232 //
233 // 12V
234 //
235 // |
236 // -----------|
237 // | |
238 // | ------|
239 // | | |
240 // | | ||--
241 // | --||
242 // | ||--
243 // ||-- |
244 // vi -----|| |--------- vo
245 // ||-- | |
246 // | ||-- |
247 // |-------|| |
248 // | ||-- |
249 // ||-- | |
250 // --|| | |
251 // | ||-- | |
252 // | | | |
253 // | -----------| |
254 // | | |
255 // | |
256 // | GND |
257 // | |
258 // ----------------------
259 //
260 //
261 // vi - input
262 // vo - output
263 //
264 // Notes:
265 //
266 // The schematics above are laid out to show that the "op-amp" logically
267 // consists of two building blocks; a saturated load NMOS inverter (on the
268 // right hand side of the schematics) with a buffer / bias input stage
269 // consisting of a variable saturated load NMOS inverter (on the left hand
270 // side of the schematics).
271 //
272 // Provided a reasonably high input impedance and a reasonably low output
273 // impedance, the "op-amp" can be modeled as a voltage transfer function
274 // mapping input voltage to output voltage.
275 //
276 //
277 //
278 // Output buffer (NMOS voltage follower)
279 // -------------------------------------
280 //
281 //
282 // 12V
283 //
284 // |
285 // |
286 // ||--
287 // vi -----||
288 // ||--
289 // |
290 // |------ vo
291 // | (AUDIO
292 // Rext OUT)
293 // |
294 // |
295 //
296 // GND
297 //
298 // vi - input
299 // vo - output
300 // Rext - external resistor, 1kOhm
301 //
302 // Notes:
303 //
304 // The external resistor Rext is needed to complete the NMOS voltage follower,
305 // this resistor has a recommended value of 1kOhm.
306 //
307 // Die photographs show that actually, two NMOS transistors are used in the
308 // voltage follower. However the two transistors are coupled in parallel (all
309 // terminals are pairwise common), which implies that we can model the two
310 // transistors as one.
311 //
312 // ----------------------------------------------------------------------------
313 //
314 // SID 8580 filter / mixer / output
315 // --------------------------------
316 //
317 // +---------------------------------------------------+
318 // | $17 +----Rf-+ |
319 // | | | |
320 // | D4&!D5 o- \-R3-o |
321 // | | | $17 |
322 // | !D4&!D5 o- \-R2-o |
323 // | | | +---R8-- \--+ !D6&D7 |
324 // | D4&!D5 o- \-R1-o | | |
325 // | | | o---RC-- \--o D6&D7 |
326 // | +---------o--<A]--o--o | |
327 // | | o---R4-- \--o D6&!D7 |
328 // | | | | |
329 // | | +---Ri-- \--o !D6&!D7 |
330 // | | | |
331 // $17 | | (CAP2B) | (CAP1B) |
332 // 0=to mixer | +--R7--+ +---R7--+ +---C---o +---C---o
333 // 1=to filter | | | | | | | |
334 // +------R7--o--o--[A>--o--Rfc-o--[A>--o--Rfc-o--[A>--o
335 // ve (EXT IN) | | | |
336 // D3 \ --------------R12--o | | (CAP2A) | (CAP1A)
337 // | v3 | | vhp | vbp | vlp
338 // D2 | \ -----------R7--o +-----+ | |
339 // | | v2 | | | |
340 // D1 | | \ -------R7--o | +----------------+ |
341 // | | | v1 | | | |
342 // D0 | | | \ ---R7--+ | | +---------------------------+
343 // | | | | | | |
344 // R9 R5 R5 R5 R5 R5 R5
345 // | | | | $18 | | | $18
346 // | \ | | D7: 1=open \ \ \ D6 - D4: 0=open
347 // | | | | | | |
348 // +---o---o---o-------------o---o---+
349 // |
350 // | D3 +--/ --1R4--+
351 // | +---R8--+ | | +---R2--+
352 // | | | D2 o--/ --2R4--o | |
353 // +---o--[A>--o------o o--o--[A>--o-- vo (AUDIO OUT)
354 // D1 o--/ --4R4--o
355 // $18 | |
356 // 0=open D0 +--/ --8R4--+
357 //
358 //
359 //
360 //
361 // R1 = 15.3*Ri
362 // R2 = 7.3*Ri
363 // R3 = 4.7*Ri
364 // Rf = 1.4*Ri
365 // R4 = 1.4*Ri
366 // R8 = 2.0*Ri
367 // RC = 2.8*Ri
368 //
369 //
370 //
371 // Op-amps
372 // -------
373 // Unlike the 6581, the 8580 has real OpAmps.
374 //
375 // Temperature compensated differential amplifier:
376 //
377 // 9V
378 //
379 // |
380 // +-------o-o-o-------+
381 // | | | |
382 // | R R |
383 // +--|| | | ||--+
384 // ||---o o---||
385 // +--|| | | ||--+
386 // | | | |
387 // o-----+ | | o--- Va
388 // | | | | |
389 // +--|| | | | ||--+
390 // ||-o-+---+---||
391 // +--|| | | ||--+
392 // | | | |
393 // | |
394 // GND | | GND
395 // ||--+ +--||
396 // in- -----|| ||------ in+
397 // ||----o----||
398 // |
399 // 8 Current sink
400 // |
401 //
402 // GND
403 //
404 // Inverter + non-inverting output amplifier:
405 //
406 // Va ---o---||-------------------o--------------------+
407 // | | 9V |
408 // | +----------+----------+ | |
409 // | 9V | | 9V | ||--+ |
410 // | | | 9V | | +-|| |
411 // | R | | | ||--+ ||--+ |
412 // | | | ||--+ +--|| o---o--- Vout
413 // | o---o---|| ||--+ ||--+
414 // | | ||--+ o-----||
415 // | ||--+ | ||--+ ||--+
416 // +-----|| o-----|| |
417 // ||--+ | ||--+
418 // | R | GND
419 // |
420 // GND GND
421 // GND
422 //
423 //
424 //
425 // Virtual ground
426 // --------------
427 // A PolySi resitive voltage divider provides the voltage
428 // for the non-inverting input of the filter op-amps.
429 //
430 // 5V
431 // +----------+
432 // | | |\ |
433 // R1 +---|-\ |
434 // 5V | |A >---o--- Vref
435 // o-------|+/
436 // | | |/
437 // R10 R4
438 // | |
439 // o---+
440 // |
441 // R10
442 // |
443 //
444 // GND
445 //
446 // Rn = n*R1
447 //
448 //
449 //
450 // Rfc - freq control DAC resistance ladder
451 // ----------------------------------------
452 // The resistance for the bandpass and lowpass integrator stages of the filter are determined
453 // by an 11 bit DAC driven by the FC register.
454 // If all 11 bits are '0', the impedance of the DAC would be "infinitely high".
455 // To get around this, there is an 11 input NOR gate below the DAC sensing those 11 bits.
456 // If they are all 0, the NOR gate gives the gate control voltage to the 12 bit DAC LSB.
457 //
458 //
459 //
460 // Crystal stabilized precision switched capacitor voltage divider
461 // ---------------------------------------------------------------
462 // There is a FET working as a temperature sensor close to the DACs which changes the gate voltage
463 // of the frequency control DACs according to the temperature, to reduce its effects on the filter curve.
464 // An asynchronous 3 bit binary counter, running at the speed of PHI2, drives two big capacitors
465 // which AC resistance is then used as a voltage divider.
466 // This implicates that frequency difference between PAL and NTSC might shift the filter curve by 4% or such.
467 //
468 // https://en.wikipedia.org/wiki/Switched_capacitor
469 //
470 // |\ OpAmp has a smaller capacitor
471 // Vref ---|+\ than the other OPs
472 // |A >---o--- Vdac
473 // o-------|-/ |
474 // | |/ |
475 // | |
476 // C1 | C2 |
477 // +---||---o---+ +---o-----||-------o
478 // | | | | | |
479 // o----+ | ----- | |
480 // | | | ----- +----+ +-----+
481 // | ----- | | | |
482 // | ----- | ----- |
483 // | | | ----- |
484 // | +-----------+ | |
485 // | /Q Q | +-------+
486 // GND +-----------+ FET close to DAC
487 // | clk/8 | working as temperature sensor
488 // +-----------+
489 // | |
490 // clk1 clk2
491 //
492 
493 // Compile-time computation of op-amp summer and mixer table offsets.
494 
495 // The highpass summer has 2 - 6 inputs (bandpass, lowpass, and 0 - 4 voices).
496 template<int i>
497 struct summer_offset
498 {
499  enum { value = summer_offset<i - 1>::value + ((2 + i - 1) << 16) };
500 };
501 
502 template<>
503 struct summer_offset<0>
504 {
505  enum { value = 0 };
506 };
507 
508 // The mixer has 0 - 7 inputs (0 - 4 voices and 0 - 3 filter outputs).
509 template<int i>
510 struct mixer_offset
511 {
512  enum { value = mixer_offset<i - 1>::value + ((i - 1) << 16) };
513 };
514 
515 template<>
516 struct mixer_offset<1>
517 {
518  enum { value = 1 };
519 };
520 
521 template<>
522 struct mixer_offset<0>
523 {
524  enum { value = 0 };
525 };
526 
527 
528 class Filter
529 {
530 public:
531  Filter();
532 
533  void enable_filter(bool enable);
534  void adjust_filter_bias(double dac_bias);
535  void set_chip_model(chip_model model);
536  void set_voice_mask(reg4 mask);
537 
538  void clock(int voice1, int voice2, int voice3);
539  void clock(cycle_count delta_t, int voice1, int voice2, int voice3);
540  void reset();
541 
542  // Write registers.
543  void writeFC_LO(reg8);
544  void writeFC_HI(reg8);
545  void writeRES_FILT(reg8);
546  void writeMODE_VOL(reg8);
547 
548  // SID audio input (16 bits).
549  void input(short sample);
550 
551  // SID audio output (16 bits).
552  short output();
553 
554 protected:
555  void set_sum_mix();
556  void set_w0();
557 
558  // Filter enabled.
559  bool enabled;
560 
561  // Filter cutoff frequency.
562  reg12 fc;
563 
564  // Filter resonance.
565  reg8 res;
566 
567  // Selects which voices to route through the filter.
568  reg8 filt;
569 
570  // Selects which filter outputs to route into the mixer.
571  reg4 mode;
572 
573  // Output master volume.
574  reg4 vol;
575 
576  // Used to mask out EXT IN if not connected, and for test purposes
577  // (voice muting).
578  reg8 voice_mask;
579 
580  // Select which inputs to route into the summer / mixer.
581  // These are derived from filt, mode, and voice_mask.
582  reg8 sum;
583  reg8 mix;
584 
585  // State of filter.
586  int Vhp; // highpass
587  int Vbp; // bandpass
588  int Vbp_x, Vbp_vc;
589  int Vlp; // lowpass
590  int Vlp_x, Vlp_vc;
591  // Filter / mixer inputs.
592  int ve;
593  int v3;
594  int v2;
595  int v1;
596 
597  chip_model sid_model;
598 
599  typedef struct {
600  unsigned short vx;
601  short dvx;
602  } opamp_t;
603 
604  typedef struct {
605  int kVddt; // K*(Vdd - Vth)
606  int voice_scale_s14;
607  int voice_DC;
608  int ak;
609  int bk;
610  int vc_min;
611  int vc_max;
612  int filterGain;
613  double vo_N16; // Fixed point scaling for 16 bit op-amp output.
614 
615  // Reverse op-amp transfer function.
616  unsigned short opamp_rev[1 << 16];
617  // Lookup tables for gain and summer op-amps in output stage / filter.
618  unsigned short summer[summer_offset<5>::value];
619  unsigned short gain[16][1 << 16];
620  unsigned short resonance[16][1 << 16];
621  unsigned short mixer[mixer_offset<8>::value];
622  // Cutoff frequency DAC output voltage table. FC is an 11 bit register.
623  unsigned short f0_dac[1 << 11];
624  } model_filter_t;
625 
626  // 6581 only
627  // Cutoff frequency DAC voltage, resonance.
628  int Vddt_Vw_2, Vw_bias;
629 
630  static int n_snake;
631 
632  // 8580 only
633  int n_dac;
634 
635  static int n_param;
636 
637  // DAC gate voltage
638  int nVgt;
639 
640  //int solve_gain(opamp_t* opamp, int n, int vi_t, int& x, model_filter_t& mf);
641  int solve_gain_d(opamp_t* opamp, double n, int vi_t, int& x, model_filter_t& mf);
642  int solve_integrate_6581(int dt, int vi_t, int& x, int& vc, model_filter_t& mf);
643  int solve_integrate_8580(int dt, int vi_t, int& x, int& vc, model_filter_t& mf);
644 
645  // VCR - 6581 only.
646  static unsigned short vcr_kVg[1 << 16];
647  static unsigned short vcr_n_Ids_term[1 << 16];
648  // Common parameters.
649  static model_filter_t model_filter[2];
650 
651 friend class SID;
652 
653 private:
654  class Randomnoise
655  {
656  private:
657  int buffer[1024];
658  mutable int index = 0;
659  public:
660  Randomnoise()
661  {
662  for (int i=0; i<1024; i++)
663  buffer[i] = rand() % (1<<19);
664  }
665  int getNoise() const { index = (index + 1) & 0x3ff; return buffer[index]; }
666  };
667 
668  Randomnoise rnd;
669 };
670 
671 
672 // ----------------------------------------------------------------------------
673 // Inline functions.
674 // The following functions are defined inline because they are called every
675 // time a sample is calculated.
676 // ----------------------------------------------------------------------------
677 
678 #if RESID_INLINING || defined(RESID_FILTER_CC)
679 
680 // ----------------------------------------------------------------------------
681 // SID clocking - 1 cycle.
682 // ----------------------------------------------------------------------------
683 RESID_INLINE
684 void Filter::clock(int voice1, int voice2, int voice3)
685 {
686  model_filter_t& f = model_filter[sid_model];
687 
688  v1 = ((voice1*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
689  v2 = ((voice2*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
690  v3 = ((voice3*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
691 
692  // Sum inputs routed into the filter.
693  int Vi = 0;
694  int offset = 0;
695 
696  switch (sum & 0xf) {
697  case 0x0:
698  Vi = 0;
699  offset = summer_offset<0>::value;
700  break;
701  case 0x1:
702  Vi = v1;
703  offset = summer_offset<1>::value;
704  break;
705  case 0x2:
706  Vi = v2;
707  offset = summer_offset<1>::value;
708  break;
709  case 0x3:
710  Vi = v2 + v1;
711  offset = summer_offset<2>::value;
712  break;
713  case 0x4:
714  Vi = v3;
715  offset = summer_offset<1>::value;
716  break;
717  case 0x5:
718  Vi = v3 + v1;
719  offset = summer_offset<2>::value;
720  break;
721  case 0x6:
722  Vi = v3 + v2;
723  offset = summer_offset<2>::value;
724  break;
725  case 0x7:
726  Vi = v3 + v2 + v1;
727  offset = summer_offset<3>::value;
728  break;
729  case 0x8:
730  Vi = ve;
731  offset = summer_offset<1>::value;
732  break;
733  case 0x9:
734  Vi = ve + v1;
735  offset = summer_offset<2>::value;
736  break;
737  case 0xa:
738  Vi = ve + v2;
739  offset = summer_offset<2>::value;
740  break;
741  case 0xb:
742  Vi = ve + v2 + v1;
743  offset = summer_offset<3>::value;
744  break;
745  case 0xc:
746  Vi = ve + v3;
747  offset = summer_offset<2>::value;
748  break;
749  case 0xd:
750  Vi = ve + v3 + v1;
751  offset = summer_offset<3>::value;
752  break;
753  case 0xe:
754  Vi = ve + v3 + v2;
755  offset = summer_offset<3>::value;
756  break;
757  case 0xf:
758  Vi = ve + v3 + v2 + v1;
759  offset = summer_offset<4>::value;
760  break;
761  }
762 
763  // Calculate filter outputs.
764  if (sid_model == 0) {
765  // MOS 6581.
766  Vlp = solve_integrate_6581(1, Vbp, Vlp_x, Vlp_vc, f);
767  Vbp = solve_integrate_6581(1, Vhp, Vbp_x, Vbp_vc, f);
768  }
769  else {
770  // MOS 8580.
771  Vlp = solve_integrate_8580(1, Vbp, Vlp_x, Vlp_vc, f);
772  Vbp = solve_integrate_8580(1, Vhp, Vbp_x, Vbp_vc, f);
773  }
774 
775  assert((Vbp >= 0) && (Vbp < (1 << 16)));
776  const int idx = offset + f.resonance[res][Vbp] + Vlp + Vi;
777  assert((idx >= 0) && (idx < summer_offset<5>::value));
778  Vhp = f.summer[idx];
779 }
780 
781 // ----------------------------------------------------------------------------
782 // SID clocking - delta_t cycles.
783 // ----------------------------------------------------------------------------
784 RESID_INLINE
785 void Filter::clock(cycle_count delta_t, int voice1, int voice2, int voice3)
786 {
787  model_filter_t& f = model_filter[sid_model];
788 
789  v1 = ((voice1*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
790  v2 = ((voice2*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
791  v3 = ((voice3*f.voice_scale_s14 + rnd.getNoise()) >> 18) + f.voice_DC;
792 
793  // Enable filter on/off.
794  // This is not really part of SID, but is useful for testing.
795  // On slow CPUs it may be necessary to bypass the filter to lower the CPU
796  // load.
797  if (unlikely(!enabled)) {
798  return;
799  }
800 
801  // Sum inputs routed into the filter.
802  int Vi = 0;
803  int offset = 0;
804 
805  switch (sum & 0xf) {
806  case 0x0:
807  Vi = 0;
808  offset = summer_offset<0>::value;
809  break;
810  case 0x1:
811  Vi = v1;
812  offset = summer_offset<1>::value;
813  break;
814  case 0x2:
815  Vi = v2;
816  offset = summer_offset<1>::value;
817  break;
818  case 0x3:
819  Vi = v2 + v1;
820  offset = summer_offset<2>::value;
821  break;
822  case 0x4:
823  Vi = v3;
824  offset = summer_offset<1>::value;
825  break;
826  case 0x5:
827  Vi = v3 + v1;
828  offset = summer_offset<2>::value;
829  break;
830  case 0x6:
831  Vi = v3 + v2;
832  offset = summer_offset<2>::value;
833  break;
834  case 0x7:
835  Vi = v3 + v2 + v1;
836  offset = summer_offset<3>::value;
837  break;
838  case 0x8:
839  Vi = ve;
840  offset = summer_offset<1>::value;
841  break;
842  case 0x9:
843  Vi = ve + v1;
844  offset = summer_offset<2>::value;
845  break;
846  case 0xa:
847  Vi = ve + v2;
848  offset = summer_offset<2>::value;
849  break;
850  case 0xb:
851  Vi = ve + v2 + v1;
852  offset = summer_offset<3>::value;
853  break;
854  case 0xc:
855  Vi = ve + v3;
856  offset = summer_offset<2>::value;
857  break;
858  case 0xd:
859  Vi = ve + v3 + v1;
860  offset = summer_offset<3>::value;
861  break;
862  case 0xe:
863  Vi = ve + v3 + v2;
864  offset = summer_offset<3>::value;
865  break;
866  case 0xf:
867  Vi = ve + v3 + v2 + v1;
868  offset = summer_offset<4>::value;
869  break;
870  }
871 
872  // Maximum delta cycles for filter fixpoint iteration to converge
873  // is approximately 3.
874  cycle_count delta_t_flt = 3;
875 
876  if (sid_model == 0) {
877  // MOS 6581.
878  while (delta_t) {
879  if (unlikely(delta_t < delta_t_flt)) {
880  delta_t_flt = delta_t;
881  }
882 
883  // Calculate filter outputs.
884  Vlp = solve_integrate_6581(delta_t_flt, Vbp, Vlp_x, Vlp_vc, f);
885  Vbp = solve_integrate_6581(delta_t_flt, Vhp, Vbp_x, Vbp_vc, f);
886  assert((Vbp >= 0) && (Vbp < (1 << 16)));
887  const int idx = offset + f.resonance[res][Vbp] + Vlp + Vi;
888  assert((idx >= 0) && (idx < summer_offset<5>::value));
889  Vhp = f.summer[idx];
890 
891  delta_t -= delta_t_flt;
892  }
893  }
894  else {
895  // MOS 8580.
896  while (delta_t) {
897  if (unlikely(delta_t < delta_t_flt)) {
898  delta_t_flt = delta_t;
899  }
900 
901  // Calculate filter outputs.
902  Vlp = solve_integrate_8580(delta_t_flt, Vbp, Vlp_x, Vlp_vc, f);
903  Vbp = solve_integrate_8580(delta_t_flt, Vhp, Vbp_x, Vbp_vc, f);
904  assert((Vbp >= 0) && (Vbp < (1 << 16)));
905  const int idx = offset + f.resonance[res][Vbp] + Vlp + Vi;
906  assert((idx >= 0) && (idx < summer_offset<5>::value));
907  Vhp = f.summer[idx];
908 
909  delta_t -= delta_t_flt;
910  }
911  }
912 }
913 
914 
915 // ----------------------------------------------------------------------------
916 // SID audio input (16 bits).
917 // ----------------------------------------------------------------------------
918 RESID_INLINE
919 void Filter::input(short sample)
920 {
921  // Scale to three times the peak-to-peak for one voice and add the op-amp
922  // "zero" DC level.
923  // NB! Adding the op-amp "zero" DC level is a (wildly inaccurate)
924  // approximation of feeding the input through an AC coupling capacitor.
925  // This could be implemented as a separate filter circuit, however the
926  // primary use of the emulator is not to process external signals.
927  // The upside is that the MOS8580 "digi boost" works without a separate (DC)
928  // input interface.
929  // Note that the input is 16 bits, compared to the 20 bit voice output.
930  model_filter_t& f = model_filter[sid_model];
931  ve = (sample*f.voice_scale_s14*3 >> 14) + f.mixer[0];
932 }
933 
934 
935 // ----------------------------------------------------------------------------
936 // SID audio output (16 bits).
937 // ----------------------------------------------------------------------------
938 RESID_INLINE
939 short Filter::output()
940 {
941  model_filter_t& f = model_filter[sid_model];
942 
943  // Writing the switch below manually would be tedious and error-prone;
944  // it is rather generated by the following Perl program:
945 
946  /*
947 my @i = qw(v1 v2 v3 ve Vlp Vbp Vhp);
948 for my $mix (0..2**@i-1) {
949  print sprintf(" case 0x%02x:\n", $mix);
950  my @sumVoice;
951  my @sumFilt;
952  my $bit = 0;
953  for (@i) {
954  if ($bit < 4) {
955  unshift(@sumVoice, $_) if $mix & (1 << $bit);
956  } else {
957  unshift(@sumFilt, $_) if $mix & (1 << $bit);
958  }
959  $bit += 1;
960  }
961  my $sum;
962  if (@sumFilt) {
963  $sumV = (@sumVoice) ? " + ".join(" + ", @sumVoice) : "";
964  $sum = "(((".join(" + ", @sumFilt).") * mf.filterGain) >> 12)" . $sumV;
965  } else {
966  $sum = join(" + ", @sumVoice) || "0";
967  }
968  print " Vi = $sum;\n";
969  print " offset = mixer_offset<" . (@sumVoice+@sumFilt) . ">::value;\n";
970  print " break;\n";
971 }
972  */
973 
974  // Sum inputs routed into the mixer.
975  int Vi = 0;
976  int offset = 0;
977 
978  switch (mix & 0x7f) {
979  case 0x00:
980  Vi = 0;
981  offset = mixer_offset<0>::value;
982  break;
983  case 0x01:
984  Vi = v1;
985  offset = mixer_offset<1>::value;
986  break;
987  case 0x02:
988  Vi = v2;
989  offset = mixer_offset<1>::value;
990  break;
991  case 0x03:
992  Vi = v2 + v1;
993  offset = mixer_offset<2>::value;
994  break;
995  case 0x04:
996  Vi = v3;
997  offset = mixer_offset<1>::value;
998  break;
999  case 0x05:
1000  Vi = v3 + v1;
1001  offset = mixer_offset<2>::value;
1002  break;
1003  case 0x06:
1004  Vi = v3 + v2;
1005  offset = mixer_offset<2>::value;
1006  break;
1007  case 0x07:
1008  Vi = v3 + v2 + v1;
1009  offset = mixer_offset<3>::value;
1010  break;
1011  case 0x08:
1012  Vi = ve;
1013  offset = mixer_offset<1>::value;
1014  break;
1015  case 0x09:
1016  Vi = ve + v1;
1017  offset = mixer_offset<2>::value;
1018  break;
1019  case 0x0a:
1020  Vi = ve + v2;
1021  offset = mixer_offset<2>::value;
1022  break;
1023  case 0x0b:
1024  Vi = ve + v2 + v1;
1025  offset = mixer_offset<3>::value;
1026  break;
1027  case 0x0c:
1028  Vi = ve + v3;
1029  offset = mixer_offset<2>::value;
1030  break;
1031  case 0x0d:
1032  Vi = ve + v3 + v1;
1033  offset = mixer_offset<3>::value;
1034  break;
1035  case 0x0e:
1036  Vi = ve + v3 + v2;
1037  offset = mixer_offset<3>::value;
1038  break;
1039  case 0x0f:
1040  Vi = ve + v3 + v2 + v1;
1041  offset = mixer_offset<4>::value;
1042  break;
1043  case 0x10:
1044  Vi = (((Vlp) * f.filterGain) >> 12);
1045  offset = mixer_offset<1>::value;
1046  break;
1047  case 0x11:
1048  Vi = (((Vlp) * f.filterGain) >> 12) + v1;
1049  offset = mixer_offset<2>::value;
1050  break;
1051  case 0x12:
1052  Vi = (((Vlp) * f.filterGain) >> 12) + v2;
1053  offset = mixer_offset<2>::value;
1054  break;
1055  case 0x13:
1056  Vi = (((Vlp) * f.filterGain) >> 12) + v2 + v1;
1057  offset = mixer_offset<3>::value;
1058  break;
1059  case 0x14:
1060  Vi = (((Vlp) * f.filterGain) >> 12) + v3;
1061  offset = mixer_offset<2>::value;
1062  break;
1063  case 0x15:
1064  Vi = (((Vlp) * f.filterGain) >> 12) + v3 + v1;
1065  offset = mixer_offset<3>::value;
1066  break;
1067  case 0x16:
1068  Vi = (((Vlp) * f.filterGain) >> 12) + v3 + v2;
1069  offset = mixer_offset<3>::value;
1070  break;
1071  case 0x17:
1072  Vi = (((Vlp) * f.filterGain) >> 12) + v3 + v2 + v1;
1073  offset = mixer_offset<4>::value;
1074  break;
1075  case 0x18:
1076  Vi = (((Vlp) * f.filterGain) >> 12) + ve;
1077  offset = mixer_offset<2>::value;
1078  break;
1079  case 0x19:
1080  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v1;
1081  offset = mixer_offset<3>::value;
1082  break;
1083  case 0x1a:
1084  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v2;
1085  offset = mixer_offset<3>::value;
1086  break;
1087  case 0x1b:
1088  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v2 + v1;
1089  offset = mixer_offset<4>::value;
1090  break;
1091  case 0x1c:
1092  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v3;
1093  offset = mixer_offset<3>::value;
1094  break;
1095  case 0x1d:
1096  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v3 + v1;
1097  offset = mixer_offset<4>::value;
1098  break;
1099  case 0x1e:
1100  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v3 + v2;
1101  offset = mixer_offset<4>::value;
1102  break;
1103  case 0x1f:
1104  Vi = (((Vlp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1105  offset = mixer_offset<5>::value;
1106  break;
1107  case 0x20:
1108  Vi = (((Vbp) * f.filterGain) >> 12);
1109  offset = mixer_offset<1>::value;
1110  break;
1111  case 0x21:
1112  Vi = (((Vbp) * f.filterGain) >> 12) + v1;
1113  offset = mixer_offset<2>::value;
1114  break;
1115  case 0x22:
1116  Vi = (((Vbp) * f.filterGain) >> 12) + v2;
1117  offset = mixer_offset<2>::value;
1118  break;
1119  case 0x23:
1120  Vi = (((Vbp) * f.filterGain) >> 12) + v2 + v1;
1121  offset = mixer_offset<3>::value;
1122  break;
1123  case 0x24:
1124  Vi = (((Vbp) * f.filterGain) >> 12) + v3;
1125  offset = mixer_offset<2>::value;
1126  break;
1127  case 0x25:
1128  Vi = (((Vbp) * f.filterGain) >> 12) + v3 + v1;
1129  offset = mixer_offset<3>::value;
1130  break;
1131  case 0x26:
1132  Vi = (((Vbp) * f.filterGain) >> 12) + v3 + v2;
1133  offset = mixer_offset<3>::value;
1134  break;
1135  case 0x27:
1136  Vi = (((Vbp) * f.filterGain) >> 12) + v3 + v2 + v1;
1137  offset = mixer_offset<4>::value;
1138  break;
1139  case 0x28:
1140  Vi = (((Vbp) * f.filterGain) >> 12) + ve;
1141  offset = mixer_offset<2>::value;
1142  break;
1143  case 0x29:
1144  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v1;
1145  offset = mixer_offset<3>::value;
1146  break;
1147  case 0x2a:
1148  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v2;
1149  offset = mixer_offset<3>::value;
1150  break;
1151  case 0x2b:
1152  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v2 + v1;
1153  offset = mixer_offset<4>::value;
1154  break;
1155  case 0x2c:
1156  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v3;
1157  offset = mixer_offset<3>::value;
1158  break;
1159  case 0x2d:
1160  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v3 + v1;
1161  offset = mixer_offset<4>::value;
1162  break;
1163  case 0x2e:
1164  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v3 + v2;
1165  offset = mixer_offset<4>::value;
1166  break;
1167  case 0x2f:
1168  Vi = (((Vbp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1169  offset = mixer_offset<5>::value;
1170  break;
1171  case 0x30:
1172  Vi = (((Vbp + Vlp) * f.filterGain) >> 12);
1173  offset = mixer_offset<2>::value;
1174  break;
1175  case 0x31:
1176  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v1;
1177  offset = mixer_offset<3>::value;
1178  break;
1179  case 0x32:
1180  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v2;
1181  offset = mixer_offset<3>::value;
1182  break;
1183  case 0x33:
1184  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v2 + v1;
1185  offset = mixer_offset<4>::value;
1186  break;
1187  case 0x34:
1188  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v3;
1189  offset = mixer_offset<3>::value;
1190  break;
1191  case 0x35:
1192  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v3 + v1;
1193  offset = mixer_offset<4>::value;
1194  break;
1195  case 0x36:
1196  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v3 + v2;
1197  offset = mixer_offset<4>::value;
1198  break;
1199  case 0x37:
1200  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + v3 + v2 + v1;
1201  offset = mixer_offset<5>::value;
1202  break;
1203  case 0x38:
1204  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve;
1205  offset = mixer_offset<3>::value;
1206  break;
1207  case 0x39:
1208  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v1;
1209  offset = mixer_offset<4>::value;
1210  break;
1211  case 0x3a:
1212  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v2;
1213  offset = mixer_offset<4>::value;
1214  break;
1215  case 0x3b:
1216  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v2 + v1;
1217  offset = mixer_offset<5>::value;
1218  break;
1219  case 0x3c:
1220  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v3;
1221  offset = mixer_offset<4>::value;
1222  break;
1223  case 0x3d:
1224  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v1;
1225  offset = mixer_offset<5>::value;
1226  break;
1227  case 0x3e:
1228  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2;
1229  offset = mixer_offset<5>::value;
1230  break;
1231  case 0x3f:
1232  Vi = (((Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1233  offset = mixer_offset<6>::value;
1234  break;
1235  case 0x40:
1236  Vi = (((Vhp) * f.filterGain) >> 12);
1237  offset = mixer_offset<1>::value;
1238  break;
1239  case 0x41:
1240  Vi = (((Vhp) * f.filterGain) >> 12) + v1;
1241  offset = mixer_offset<2>::value;
1242  break;
1243  case 0x42:
1244  Vi = (((Vhp) * f.filterGain) >> 12) + v2;
1245  offset = mixer_offset<2>::value;
1246  break;
1247  case 0x43:
1248  Vi = (((Vhp) * f.filterGain) >> 12) + v2 + v1;
1249  offset = mixer_offset<3>::value;
1250  break;
1251  case 0x44:
1252  Vi = (((Vhp) * f.filterGain) >> 12) + v3;
1253  offset = mixer_offset<2>::value;
1254  break;
1255  case 0x45:
1256  Vi = (((Vhp) * f.filterGain) >> 12) + v3 + v1;
1257  offset = mixer_offset<3>::value;
1258  break;
1259  case 0x46:
1260  Vi = (((Vhp) * f.filterGain) >> 12) + v3 + v2;
1261  offset = mixer_offset<3>::value;
1262  break;
1263  case 0x47:
1264  Vi = (((Vhp) * f.filterGain) >> 12) + v3 + v2 + v1;
1265  offset = mixer_offset<4>::value;
1266  break;
1267  case 0x48:
1268  Vi = (((Vhp) * f.filterGain) >> 12) + ve;
1269  offset = mixer_offset<2>::value;
1270  break;
1271  case 0x49:
1272  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v1;
1273  offset = mixer_offset<3>::value;
1274  break;
1275  case 0x4a:
1276  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v2;
1277  offset = mixer_offset<3>::value;
1278  break;
1279  case 0x4b:
1280  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v2 + v1;
1281  offset = mixer_offset<4>::value;
1282  break;
1283  case 0x4c:
1284  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v3;
1285  offset = mixer_offset<3>::value;
1286  break;
1287  case 0x4d:
1288  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v3 + v1;
1289  offset = mixer_offset<4>::value;
1290  break;
1291  case 0x4e:
1292  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v3 + v2;
1293  offset = mixer_offset<4>::value;
1294  break;
1295  case 0x4f:
1296  Vi = (((Vhp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1297  offset = mixer_offset<5>::value;
1298  break;
1299  case 0x50:
1300  Vi = (((Vhp + Vlp) * f.filterGain) >> 12);
1301  offset = mixer_offset<2>::value;
1302  break;
1303  case 0x51:
1304  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v1;
1305  offset = mixer_offset<3>::value;
1306  break;
1307  case 0x52:
1308  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v2;
1309  offset = mixer_offset<3>::value;
1310  break;
1311  case 0x53:
1312  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v2 + v1;
1313  offset = mixer_offset<4>::value;
1314  break;
1315  case 0x54:
1316  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v3;
1317  offset = mixer_offset<3>::value;
1318  break;
1319  case 0x55:
1320  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v3 + v1;
1321  offset = mixer_offset<4>::value;
1322  break;
1323  case 0x56:
1324  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v3 + v2;
1325  offset = mixer_offset<4>::value;
1326  break;
1327  case 0x57:
1328  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + v3 + v2 + v1;
1329  offset = mixer_offset<5>::value;
1330  break;
1331  case 0x58:
1332  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve;
1333  offset = mixer_offset<3>::value;
1334  break;
1335  case 0x59:
1336  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v1;
1337  offset = mixer_offset<4>::value;
1338  break;
1339  case 0x5a:
1340  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v2;
1341  offset = mixer_offset<4>::value;
1342  break;
1343  case 0x5b:
1344  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v2 + v1;
1345  offset = mixer_offset<5>::value;
1346  break;
1347  case 0x5c:
1348  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v3;
1349  offset = mixer_offset<4>::value;
1350  break;
1351  case 0x5d:
1352  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v3 + v1;
1353  offset = mixer_offset<5>::value;
1354  break;
1355  case 0x5e:
1356  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2;
1357  offset = mixer_offset<5>::value;
1358  break;
1359  case 0x5f:
1360  Vi = (((Vhp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1361  offset = mixer_offset<6>::value;
1362  break;
1363  case 0x60:
1364  Vi = (((Vhp + Vbp) * f.filterGain) >> 12);
1365  offset = mixer_offset<2>::value;
1366  break;
1367  case 0x61:
1368  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v1;
1369  offset = mixer_offset<3>::value;
1370  break;
1371  case 0x62:
1372  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v2;
1373  offset = mixer_offset<3>::value;
1374  break;
1375  case 0x63:
1376  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v2 + v1;
1377  offset = mixer_offset<4>::value;
1378  break;
1379  case 0x64:
1380  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v3;
1381  offset = mixer_offset<3>::value;
1382  break;
1383  case 0x65:
1384  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v3 + v1;
1385  offset = mixer_offset<4>::value;
1386  break;
1387  case 0x66:
1388  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v3 + v2;
1389  offset = mixer_offset<4>::value;
1390  break;
1391  case 0x67:
1392  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + v3 + v2 + v1;
1393  offset = mixer_offset<5>::value;
1394  break;
1395  case 0x68:
1396  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve;
1397  offset = mixer_offset<3>::value;
1398  break;
1399  case 0x69:
1400  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v1;
1401  offset = mixer_offset<4>::value;
1402  break;
1403  case 0x6a:
1404  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v2;
1405  offset = mixer_offset<4>::value;
1406  break;
1407  case 0x6b:
1408  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v2 + v1;
1409  offset = mixer_offset<5>::value;
1410  break;
1411  case 0x6c:
1412  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v3;
1413  offset = mixer_offset<4>::value;
1414  break;
1415  case 0x6d:
1416  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v3 + v1;
1417  offset = mixer_offset<5>::value;
1418  break;
1419  case 0x6e:
1420  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v3 + v2;
1421  offset = mixer_offset<5>::value;
1422  break;
1423  case 0x6f:
1424  Vi = (((Vhp + Vbp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1425  offset = mixer_offset<6>::value;
1426  break;
1427  case 0x70:
1428  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12);
1429  offset = mixer_offset<3>::value;
1430  break;
1431  case 0x71:
1432  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v1;
1433  offset = mixer_offset<4>::value;
1434  break;
1435  case 0x72:
1436  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v2;
1437  offset = mixer_offset<4>::value;
1438  break;
1439  case 0x73:
1440  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v2 + v1;
1441  offset = mixer_offset<5>::value;
1442  break;
1443  case 0x74:
1444  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v3;
1445  offset = mixer_offset<4>::value;
1446  break;
1447  case 0x75:
1448  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v3 + v1;
1449  offset = mixer_offset<5>::value;
1450  break;
1451  case 0x76:
1452  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v3 + v2;
1453  offset = mixer_offset<5>::value;
1454  break;
1455  case 0x77:
1456  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + v3 + v2 + v1;
1457  offset = mixer_offset<6>::value;
1458  break;
1459  case 0x78:
1460  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve;
1461  offset = mixer_offset<4>::value;
1462  break;
1463  case 0x79:
1464  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v1;
1465  offset = mixer_offset<5>::value;
1466  break;
1467  case 0x7a:
1468  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v2;
1469  offset = mixer_offset<5>::value;
1470  break;
1471  case 0x7b:
1472  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v2 + v1;
1473  offset = mixer_offset<6>::value;
1474  break;
1475  case 0x7c:
1476  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v3;
1477  offset = mixer_offset<5>::value;
1478  break;
1479  case 0x7d:
1480  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v1;
1481  offset = mixer_offset<6>::value;
1482  break;
1483  case 0x7e:
1484  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2;
1485  offset = mixer_offset<6>::value;
1486  break;
1487  case 0x7f:
1488  Vi = (((Vhp + Vbp + Vlp) * f.filterGain) >> 12) + ve + v3 + v2 + v1;
1489  offset = mixer_offset<7>::value;
1490  break;
1491  }
1492 
1493  // Sum the inputs in the mixer and run the mixer output through the gain.
1494  const int idx1 = offset + Vi;
1495  assert((idx1 >= 0) && (idx1 < mixer_offset<8>::value));
1496  const int idx2 = f.mixer[idx1];
1497  assert((idx2 >= 0) && (idx2 < (1 << 16)));
1498  return (short)(f.gain[vol][idx2] - (1 << 15));
1499 }
1500 
1501 
1502 /*
1503 Find output voltage in inverting gain and inverting summer SID op-amp
1504 circuits, using a combination of Newton-Raphson and bisection.
1505 
1506  ---R2--
1507  | |
1508  vi ---R1-----[A>----- vo
1509  vx
1510 
1511 From Kirchoff's current law it follows that
1512 
1513  IR1f + IR2r = 0
1514 
1515 Substituting the triode mode transistor model K*W/L*(Vgst^2 - Vgdt^2)
1516 for the currents, we get:
1517 
1518  n*((Vddt - vx)^2 - (Vddt - vi)^2) + (Vddt - vx)^2 - (Vddt - vo)^2 = 0
1519 
1520 Our root function f can thus be written as:
1521 
1522  f = (n + 1)*(Vddt - vx)^2 - n*(Vddt - vi)^2 - (Vddt - vo)^2 = 0
1523 
1524 We are using the mapping function x = vo - vx -> vx. We thus substitute
1525 for vo = vx + x and get:
1526 
1527  f(vx) = (n + 1)*(Vddt - vx)^2 - n*(Vddt - vi)^2 - (Vddt - (vx + x))^2 = 0
1528 
1529 Using substitution constants
1530 
1531  a = n + 1
1532  b = Vddt
1533  c = n*(Vddt - vi)^2
1534 
1535 the equations for the root function can be written and expanded as:
1536 
1537  f(vx) = a*(b - vx)^2 - c - (b - (vx + x))^2
1538  = a*(b^2 + vx^2 - 2*b*vx) - c - (b^2 + (vx + x)^2 - 2*b*(vx + x))
1539  = a*b^2 + a*vx^2 - 2*a*b*vx - c - b^2 - (vx + x)^2 + 2*b*(vx + x)
1540  = a*b^2 + a*vx^2 - 2*a*b*vx - c - b^2 - vx^2 - x^2 - 2*x*vx + 2*b*vx + 2*b*x
1541 
1542 Then we calculate the derivative:
1543 
1544  f'(vx) = 2*a*vx - 2*a*b - 2*vx - 2*x + 2*b
1545  = 2*(a*vx - a*b - vx - x + b)
1546  = 2*(a*(vx - b) + b - (vx + x))
1547  = 2*(b - (vx + x) - a*(b - vx))
1548  = 2*(b - vo - a*(b - vx))
1549 
1550 Given f'(x) = df/dx, we have the resulting
1551 
1552  df = 2*((b - (vx + x)) - a*(b - vx))*dvx
1553 */
1554 #if 0
1555 RESID_INLINE
1556 int Filter::solve_gain(opamp_t* opamp, int n, int vi, int& x, model_filter_t& mf)
1557 {
1558  // Note that all variables are translated and scaled in order to fit
1559  // in 16 bits. It is not necessary to explicitly translate the variables here,
1560  // since they are all used in subtractions which cancel out the translation:
1561  // (a - t) - (b - t) = a - b
1562 
1563  // Start off with an estimate of x and a root bracket [ak, bk].
1564  // f is increasing, so that f(ak) < 0 and f(bk) > 0.
1565  int ak = mf.ak, bk = mf.bk;
1566 
1567  int a = n + (1 << 7); // Scaled by 2^7
1568  int b = mf.kVddt; // Scaled by m*2^16
1569  int b_vi = b - vi; // Scaled by m*2^16
1570  if (b_vi < 0) b_vi = 0;
1571  int c = n*int(unsigned(b_vi)*unsigned(b_vi) >> 12); // Scaled by m^2*2^27
1572 
1573  for (;;) {
1574  int xk = x;
1575 
1576  // Calculate f and df.
1577  int vx = opamp[x].vx; // Scaled by m*2^16
1578  int dvx = opamp[x].dvx; // Scaled by 2^11
1579 
1580  // f = a*(b - vx)^2 - c - (b - vo)^2
1581  // df = 2*((b - vo)*(dvx + 1) - a*(b - vx)*dvx)
1582  //
1583  int vo = vx + (x << 1) - (1 << 16);
1584  if (vo >= (1 << 16)) {
1585  vo = (1 << 16) - 1;
1586  }
1587  else if (vo < 0) {
1588  vo = 0;
1589  }
1590  int b_vx = b - vx;
1591  if (b_vx < 0) b_vx = 0;
1592  int b_vo = b - vo;
1593  if (b_vo < 0) b_vo = 0;
1594  // The dividend is scaled by m^2*2^27.
1595  int f = a*int(unsigned(b_vx)*unsigned(b_vx) >> 12) - c - int(unsigned(b_vo)*unsigned(b_vo) >> 5);
1596  // The divisor is scaled by m*2^11.
1597  int df = ((b_vo*(dvx + (1 << 11)) >> 1) - (a*(b_vx*dvx >> 8))) >> 14;
1598  // The resulting quotient is thus scaled by m*2^16.
1599 
1600  // Newton-Raphson step: xk1 = xk - f(xk)/f'(xk)
1601  // If f(xk) or f'(xk) are zero then we can't improve further.
1602  if (df) {
1603  x -= f/df;
1604  }
1605  if (unlikely(x == xk)) {
1606  // No further root improvement possible.
1607  return vo;
1608  }
1609 
1610  // Narrow down root bracket.
1611  if (f < 0) {
1612  // f(xk) < 0
1613  ak = xk;
1614  }
1615  else {
1616  // f(xk) > 0
1617  bk = xk;
1618  }
1619 
1620  if (unlikely(x <= ak) || unlikely(x >= bk)) {
1621  // Bisection step (ala Dekker's method).
1622  x = (ak + bk) >> 1;
1623  if (unlikely(x == ak)) {
1624  // No further bisection possible.
1625  return vo;
1626  }
1627  }
1628  }
1629 }
1630 #endif
1631 RESID_INLINE
1632 int Filter::solve_gain_d(opamp_t* opamp, double n, int vi, int& x, model_filter_t& mf)
1633 {
1634  // Note that all variables are translated and scaled in order to fit
1635  // in 16 bits. It is not necessary to explicitly translate the variables here,
1636  // since they are all used in subtractions which cancel out the translation:
1637  // (a - t) - (b - t) = a - b
1638 
1639  // Start off with an estimate of x and a root bracket [ak, bk].
1640  // f is increasing, so that f(ak) < 0 and f(bk) > 0.
1641  int ak = mf.ak, bk = mf.bk;
1642 
1643  double a = n + 1.;
1644  int b = mf.kVddt; // Scaled by m*2^16
1645  double b_vi = b > vi ? double(b - vi) : 0.; // Scaled by m*2^16
1646  double c = n*(b_vi*b_vi); // Scaled by m^2*2^32
1647 
1648  for (;;) {
1649  int xk = x;
1650 
1651  // Calculate f and df.
1652  int vx = opamp[x].vx; // Scaled by m*2^16
1653  int dvx = opamp[x].dvx; // Scaled by m*2^11
1654 
1655  // f = a*(b - vx)^2 - c - (b - vo)^2
1656  // df = 2*((b - vo) - a*(b - vx))*dvx
1657  //
1658  int vo = vx + (x << 1) - (1 << 16);
1659  if (vo > (1 << 16) - 1) {
1660  vo = (1 << 16) - 1;
1661  }
1662  else if (vo < 0) {
1663  vo = 0;
1664  }
1665  double b_vx = b > vx ? double(b - vx) : 0.;
1666  double b_vo = b > vo ? double(b - vo) : 0.;
1667  // The dividend is scaled by m^2*2^32.
1668  double f = a*(b_vx*b_vx) - c - (b_vo*b_vo);
1669  // The divisor is scaled by m*2^27.
1670  double df = 2.*(b_vo - a*b_vx)*double(dvx);
1671  // The resulting quotient is thus scaled by m*2^5.
1672 
1673  // Newton-Raphson step: xk1 = xk - f(xk)/f'(xk)
1674  // If f(xk) or f'(xk) are zero then we can't improve further.
1675  if (df) {
1676  // Multiply by 2^11 so it's scaled by m*2^16.
1677  x -= int(double(1<<11)*f/df);
1678  }
1679  if (unlikely(x == xk)) {
1680  // No further root improvement possible.
1681  return vo;
1682  }
1683 
1684  // Narrow down root bracket.
1685  if (f < 0) {
1686  // f(xk) < 0
1687  ak = xk;
1688  }
1689  else {
1690  // f(xk) > 0
1691  bk = xk;
1692  }
1693 
1694  if (unlikely(x <= ak) || unlikely(x >= bk)) {
1695  // Bisection step (ala Dekker's method).
1696  x = (ak + bk) >> 1;
1697  if (unlikely(x == ak)) {
1698  // No further bisection possible.
1699  return vo;
1700  }
1701  }
1702  }
1703 }
1704 
1705 
1706 /*
1707 Find output voltage in inverting integrator SID op-amp circuits, using a
1708 single fixpoint iteration step.
1709 
1710 A circuit diagram of a MOS 6581 integrator is shown below.
1711 
1712  ---C---
1713  | |
1714  vi -----Rw-------[A>----- vo
1715  | | vx
1716  --Rs--
1717 
1718 From Kirchoff's current law it follows that
1719 
1720  IRw + IRs + ICr = 0
1721 
1722 Using the formula for current through a capacitor, i = C*dv/dt, we get
1723 
1724  IRw + IRs + C*(vc - vc0)/dt = 0
1725  dt/C*(IRw + IRs) + vc - vc0 = 0
1726  vc = vc0 - n*(IRw(vi,vx) + IRs(vi,vx))
1727 
1728 which may be rewritten as the following iterative fixpoint function:
1729 
1730  vc = vc0 - n*(IRw(vi,g(vc)) + IRs(vi,g(vc)))
1731 
1732 To accurately calculate the currents through Rs and Rw, we need to use
1733 transistor models. Rs has a gate voltage of Vdd = 12V, and can be
1734 assumed to always be in triode mode. For Rw, the situation is rather
1735 more complex, as it turns out that this transistor will operate in
1736 both subthreshold, triode, and saturation modes.
1737 
1738 The Shichman-Hodges transistor model routinely used in textbooks may
1739 be written as follows:
1740 
1741  Ids = 0 , Vgst < 0 (subthreshold mode)
1742  Ids = K/2*W/L*(2*Vgst - Vds)*Vds , Vgst >= 0, Vds < Vgst (triode mode)
1743  Ids = K/2*W/L*Vgst^2 , Vgst >= 0, Vds >= Vgst (saturation mode)
1744 
1745  where
1746  K = u*Cox (conductance)
1747  W/L = ratio between substrate width and length
1748  Vgst = Vg - Vs - Vt (overdrive voltage)
1749 
1750 This transistor model is also called the quadratic model.
1751 
1752 Note that the equation for the triode mode can be reformulated as
1753 independent terms depending on Vgs and Vgd, respectively, by the
1754 following substitution:
1755 
1756  Vds = Vgst - (Vgst - Vds) = Vgst - Vgdt
1757 
1758  Ids = K/2*W/L*(2*Vgst - Vds)*Vds
1759  = K/2*W/L*(2*Vgst - (Vgst - Vgdt)*(Vgst - Vgdt)
1760  = K/2*W/L*(Vgst + Vgdt)*(Vgst - Vgdt)
1761  = K/2*W/L*(Vgst^2 - Vgdt^2)
1762 
1763 This turns out to be a general equation which covers both the triode
1764 and saturation modes (where the second term is 0 in saturation mode).
1765 The equation is also symmetrical, i.e. it can calculate negative
1766 currents without any change of parameters (since the terms for drain
1767 and source are identical except for the sign).
1768 
1769 FIXME: Subthreshold as function of Vgs, Vgd.
1770  Ids = I0*e^(Vgst/(n*VT)) , Vgst < 0 (subthreshold mode)
1771 
1772 The remaining problem with the textbook model is that the transition
1773 from subthreshold the triode/saturation is not continuous.
1774 
1775 Realizing that the subthreshold and triode/saturation modes may both
1776 be defined by independent (and equal) terms of Vgs and Vds,
1777 respectively, the corresponding terms can be blended into (equal)
1778 continuous functions suitable for table lookup.
1779 
1780 The EKV model (Enz, Krummenacher and Vittoz) essentially performs this
1781 blending using an elegant mathematical formulation:
1782 
1783  Ids = Is*(if - ir)
1784  Is = ((2*u*Cox*Ut^2)/k)*W/L
1785  if = ln^2(1 + e^((k*(Vg - Vt) - Vs)/(2*Ut))
1786  ir = ln^2(1 + e^((k*(Vg - Vt) - Vd)/(2*Ut))
1787 
1788 For our purposes, the EKV model preserves two important properties
1789 discussed above:
1790 
1791 - It consists of two independent terms, which can be represented by
1792  the same lookup table.
1793 - It is symmetrical, i.e. it calculates current in both directions,
1794  facilitating a branch-free implementation.
1795 
1796 Rw in the circuit diagram above is a VCR (voltage controlled resistor),
1797 as shown in the circuit diagram below.
1798 
1799  Vw
1800 
1801  |
1802  Vdd |
1803  |---|
1804  _|_ |
1805  -- --| Vg
1806  | __|__
1807  | ----- Rw
1808  | | |
1809  vi ------------ -------- vo
1810 
1811 
1812 In order to calculalate the current through the VCR, its gate voltage
1813 must be determined.
1814 
1815 Assuming triode mode and applying Kirchoff's current law, we get the
1816 following equation for Vg:
1817 
1818 u*Cox/2*W/L*((Vddt - Vg)^2 - (Vddt - vi)^2 + (Vddt - Vg)^2 - (Vddt - Vw)^2) = 0
1819 2*(Vddt - Vg)^2 - (Vddt - vi)^2 - (Vddt - Vw)^2 = 0
1820 (Vddt - Vg) = sqrt(((Vddt - vi)^2 + (Vddt - Vw)^2)/2)
1821 
1822 Vg = Vddt - sqrt(((Vddt - vi)^2 + (Vddt - Vw)^2)/2)
1823 
1824 */
1825 RESID_INLINE
1826 int Filter::solve_integrate_6581(int dt, int vi, int& vx, int& vc, model_filter_t& mf)
1827 {
1828  // Note that all variables are translated and scaled in order to fit
1829  // in 16 bits. It is not necessary to explicitly translate the variables here,
1830  // since they are all used in subtractions which cancel out the translation:
1831  // (a - t) - (b - t) = a - b
1832 
1833  int kVddt = mf.kVddt; // Scaled by m*2^16
1834 
1835  // "Snake" voltages for triode mode calculation.
1836  unsigned int Vgst = kVddt - vx;
1837  unsigned int Vgdt = kVddt - vi;
1838  unsigned int Vgdt_2 = Vgdt*Vgdt;
1839 
1840  // "Snake" current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30
1841  int n_I_snake = n_snake*(int(Vgst*Vgst - Vgdt_2) >> 15);
1842 
1843  // VCR gate voltage. // Scaled by m*2^16
1844  // Vg = Vddt - sqrt(((Vddt - Vw)^2 + Vgdt^2)/2)
1845  int kVg = vcr_kVg[(Vddt_Vw_2 + (Vgdt_2 >> 1)) >> 16];
1846 
1847  // VCR voltages for EKV model table lookup.
1848  int Vgs = kVg - vx + (1 << 15);
1849  int Vgd = kVg - vi + (1 << 15);
1850 
1851  // VCR current, scaled by m*2^15*2^15 = m*2^30
1852  int n_I_vcr = int(unsigned(vcr_n_Ids_term[Vgs] - vcr_n_Ids_term[Vgd]) << 15);
1853 
1854  // Change in capacitor charge.
1855  vc -= (n_I_snake + n_I_vcr)*dt;
1856 
1857 /*
1858  // FIXME: Determine whether this check is necessary.
1859  if (vc < mf.vc_min) {
1860  vc = mf.vc_min;
1861  }
1862  else if (vc > mf.vc_max) {
1863  vc = mf.vc_max;
1864  }
1865 */
1866 
1867  // vx = g(vc)
1868  const int idx = (vc >> 15) + (1 << 15);
1869  assert((idx >= 0) && (idx < (1 << 16)));
1870  vx = mf.opamp_rev[idx];
1871 
1872  // Return vo.
1873  return vx + (vc >> 14);
1874 }
1875 
1876 /*
1877 The 8580 integrator is similar to those found in 6581
1878 but the resistance is formed by multiple NMOS transistors
1879 in parallel controlled by the fc bits where the gate voltage
1880 is driven by a temperature dependent voltage divider.
1881 
1882  ---C---
1883  | |
1884  vi -----Rfc------[A>----- vo
1885  vx
1886 
1887  IRfc + ICr = 0
1888  IRfc + C*(vc - vc0)/dt = 0
1889  dt/C*(IRfc) + vc - vc0 = 0
1890  vc = vc0 - n*(IRfc(vi,vx))
1891  vc = vc0 - n*(IRfc(vi,g(vc)))
1892 
1893 IRfc = K/2*W/L*(Vgst^2 - Vgdt^2) = n*((Vgt - vx)^2 - (Vgt - vi)^2)
1894 */
1895 RESID_INLINE
1896 int Filter::solve_integrate_8580(int dt, int vi, int& vx, int& vc, model_filter_t& mf)
1897 {
1898  // Note that all variables are translated and scaled in order to fit
1899  // in 16 bits. It is not necessary to explicitly translate the variables here,
1900  // since they are all used in subtractions which cancel out the translation:
1901  // (a - t) - (b - t) = a - b
1902 
1903  // Dac voltages.
1904  unsigned int Vgst = nVgt - vx;
1905  unsigned int Vgdt = (vi < nVgt) ? nVgt - vi : 0; // triode/saturation mode
1906 
1907  // Dac current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30
1908  int n_I_rfc = (n_dac*(int(Vgst*Vgst - Vgdt*Vgdt) >> 15)) >> 4;
1909 
1910  // Change in capacitor charge.
1911  vc -= n_I_rfc*dt;
1912 
1913  // vx = g(vc)
1914  const int idx = (vc >> 15) + (1 << 15);
1915  assert((idx >= 0) && (idx < (1 << 16)));
1916  vx = mf.opamp_rev[idx];
1917 
1918  // Return vo.
1919  return vx + (vc >> 14);
1920 }
1921 
1922 #endif // RESID_INLINING || defined(RESID_FILTER_CC)
1923 
1924 } // namespace reSID
1925 
1926 #endif // not RESID_FILTER_H