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