1 //  ---------------------------------------------------------------------------
2 //  This file is part of reSID, a MOS6581 SID emulator engine.
3 //  Copyright (C) 2004  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 #include "wavefp.h"
21 #include "sidfp.h"
22 
23 typedef struct {
24     float bias;
25     float pulsestrength;
26     float topbit;
27     float distance;
28     float stmix;
29 } waveformconfig_t;
30 
31 const float sharpness = 512.f;
32 const waveformconfig_t wfconfig[2][5] = { {
33     /* kevtris chip G (6581) */
34     { 0.880815f, 0.f, 0.f, 0.3279614f, 0.5999545f }, // error 1795
35     { 0.8924618f, 2.014781f, 1.003332f, 0.02992322f, 0.0f }, // error 11610
36     { 0.8646501f, 1.712586f, 1.137704f, 0.02845423f, 0.f }, // error 21307
37     { 0.9527834f, 1.794777f, 0.f, 0.09806272f, 0.7752482f }, // error 196
38     { 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, },
39 }, {
40     /* kevtris chip V (8580) */
41     { 0.9781665f, 0.f, 0.9899469f, 8.087667f, 0.8226412f }, // error 5546
42     { 0.9097769f, 2.039997f, 0.9584096f, 0.1765447f, 0.f }, // error 18763
43     { 0.9231212f, 2.084788f, 0.9493895f, 0.1712518f, 0.f }, // error 17103
44     { 0.9845552f, 1.415612f, 0.9703883f, 3.68829f, 0.8265008f }, // error 3319
45     { 0.5f, 0.0f, 1.0f, 0.0f, 0.0f },
46     }
47 };
48 
49 /* render output from bitstate */
make_sample(float * o)50 static float make_sample(float *o) {
51   float out = 0;
52   for (int i = 0; i < 12; i ++) {
53     out += o[i] * dac[i];
54   }
55   return out;
56 }
57 
58 /* generate tables for waveforms 1 .. 7 */
rebuild_wftable()59 void WaveformGeneratorFP::rebuild_wftable() {
60     float o[12];
61     reg8 oldwf = waveform;
62     reg32 oldacc = accumulator;
63     reg12 oldpw = pw;
64 
65     for (waveform = 1; waveform < 8; waveform ++) {
66         for (accumulator = 0; accumulator < (1<<24); accumulator += (1<<12)) {
67             /* generate pulse-low variants. Also,
68              * when waveform < 4, pw doesn't matter. */
69             pw = 0x1000; /* pulse always low */
70             calculate_waveform_sample(o);
71             wftable[waveform - 1][accumulator >> 12] = make_sample(o) + wave_zero;
72             /* Add pulse-high variants after pulse-low state variants */
73             if (waveform >= 4) {
74                 pw = 0x000; /* pulse always high */
75                 calculate_waveform_sample(o);
76                 wftable[waveform + 3][accumulator >> 12] = make_sample(o) + wave_zero;
77             }
78         }
79     }
80 
81     waveform = oldwf;
82     accumulator = oldacc;
83     pw = oldpw;
84 }
85 
86 /* explode reg12 to a floating point bit array */
populate(reg12 v,float o[12])87 static void populate(reg12 v, float o[12])
88 {
89     int j = 1;
90     for (int i = 0; i < 12; i ++) {
91         o[i] = v & j ? 1.f : 0.f;
92         j <<= 1;
93     }
94 }
95 
96 /* waveform values valid are 1 .. 7 */
calculate_waveform_sample(float o[12])97 void WaveformGeneratorFP::calculate_waveform_sample(float o[12])
98 {
99   int i;
100 
101   /* P */
102   if (waveform == 4) {
103     populate((accumulator >> 12) >= pw ? 0xfff : 0x000, o);
104     return;
105   }
106 
107   const waveformconfig_t config = wfconfig[
108     model == MOS6581 ? 0 : 1
109   ][
110     waveform == 3 ? 0 :
111     waveform == 5 ? 1 :
112     waveform == 6 ? 2 :
113     waveform == 7 ? 3 :
114                     4
115   ];
116 
117   /* S with strong top bit for 6581 */
118   populate(accumulator >> 12, o);
119 
120   /* convert to T */
121   if ((waveform & 3) == 1) {
122     bool top = (accumulator & 0x800000) != 0;
123     for (i = 11; i > 0; i --) {
124       if (top) {
125         o[i] = 1.0f - o[i-1];
126       } else {
127         o[i] = o[i-1];
128       }
129     }
130     o[0] = 0;
131   }
132 
133   /* convert to ST */
134   if ((waveform & 3) == 3) {
135     /* bottom bit is grounded via T waveform selector */
136     o[0] *= config.stmix;
137     for (i = 1; i < 12; i ++) {
138       o[i] = o[i - 1] * (1.f - config.stmix) + o[i] * config.stmix;
139     }
140   }
141   o[11] *= config.topbit;
142 
143   /* ST, P* waveform? */
144   if (waveform == 3 || waveform > 4) {
145     float distancetable[12 * 2 + 1];
146     for (i = 0; i <= 12; i ++) {
147         distancetable[12+i] = distancetable[12-i] = 1.f / (1.f + i * i * config.distance);
148     }
149 
150     float pulse = (accumulator >> 12) >= pw ? 1.f : -1.f;
151     pulse *= config.pulsestrength;
152 
153     float tmp[12];
154     for (i = 0; i < 12; i ++) {
155         float avg = 0;
156         float n = 0;
157         for (int j = 0; j < 12; j ++) {
158             float weight = distancetable[i - j + 12];
159             avg += o[j] * weight;
160             n += weight;
161         }
162         /* pulse control bit */
163         if (waveform > 4) {
164             float weight = distancetable[i - 12 + 12];
165             avg += pulse * weight;
166             n += weight;
167         }
168 
169         tmp[i] = (o[i] + avg / n) * 0.5f;
170     }
171 
172     for (i = 0; i < 12; i ++) {
173         o[i] = tmp[i];
174     }
175   }
176 
177   /* use the environment around bias value to set/clear dac bit. The
178    * relationship is nonlinear because that seems to sound a bit better. */
179   for (i = 0; i < 12; i ++) {
180     o[i] = (o[i] - config.bias) * sharpness;
181 
182     o[i] += 0.5f;
183     if (o[i] > 1.f) {
184        o[i] = 1.f;
185     }
186     if (o[i] < 0.f) {
187         o[i] = 0.;
188     }
189   }
190 }
191 
set_nonlinearity(float nl)192 void WaveformGeneratorFP::set_nonlinearity(float nl)
193 {
194   for (int i = 0; i < 12; i ++) {
195     dac[i] = SIDFP::kinked_dac((1 << i), nl, 12);
196   }
197 }
198 
199 // ----------------------------------------------------------------------------
200 // Constructor.
201 // ----------------------------------------------------------------------------
WaveformGeneratorFP()202 WaveformGeneratorFP::WaveformGeneratorFP()
203 {
204   set_chip_model(MOS6581);
205   reset();
206 }
207 
208 // ----------------------------------------------------------------------------
209 // Set chip model.
210 // ----------------------------------------------------------------------------
set_chip_model(chip_model model)211 void WaveformGeneratorFP::set_chip_model(chip_model model)
212 {
213   this->model = model;
214   wave_zero = static_cast<float>(model == MOS6581 ? -0x380 : -0x800);
215 }
216 
217 
218 // ----------------------------------------------------------------------------
219 // Register functions.
220 // ----------------------------------------------------------------------------
writeFREQ_LO(reg8 freq_lo)221 void WaveformGeneratorFP::writeFREQ_LO(reg8 freq_lo)
222 {
223   freq = (freq & 0xff00) | (freq_lo & 0xff);
224 }
225 
writeFREQ_HI(reg8 freq_hi)226 void WaveformGeneratorFP::writeFREQ_HI(reg8 freq_hi)
227 {
228   freq = ((freq_hi << 8) & 0xff00) | (freq & 0xff);
229 }
230 
writePW_LO(reg8 pw_lo)231 void WaveformGeneratorFP::writePW_LO(reg8 pw_lo)
232 {
233   pw = (pw & 0xf00) | (pw_lo & 0x0ff);
234 }
235 
writePW_HI(reg8 pw_hi)236 void WaveformGeneratorFP::writePW_HI(reg8 pw_hi)
237 {
238   pw = ((pw_hi << 8) & 0xf00) | (pw & 0x0ff);
239 }
240 
writeCONTROL_REG(WaveformGeneratorFP & source,reg8 control)241 void WaveformGeneratorFP::writeCONTROL_REG(WaveformGeneratorFP& source, reg8 control)
242 {
243   /* when selecting the 0 waveform, the previous output is held for
244    * a time in the DAC MOSFET gates. We keep on holding forever, though... */
245   reg4 waveform_next = (control >> 4) & 0x0f;
246   if (waveform_next == 0 && waveform >= 1 && waveform <= 7) {
247     previous = readOSC(source);
248     previous_dac = output(source);
249   }
250 
251   waveform = waveform_next;
252   ring_mod = (control & 0x04) != 0;
253   sync = (control & 0x02) != 0;
254   bool test_next = (control & 0x08) != 0;
255 
256   // Test bit rising? Invert bit 19 and write it to bit 1.
257   if (test_next && !test) {
258     accumulator = 0;
259     reg24 bit19 = (shift_register >> 18) & 2;
260     shift_register = (shift_register & 0x7ffffd) | (bit19^2);
261     noise_overwrite_delay = 200000; /* 200 ms, probably too generous? */
262   } else {
263     if (! test_next) {
264       // Test bit falling? clock noise once,
265       // otherwise just emulate noise's combined waveforms.
266       clock_noise(test);
267     }
268   }
269 
270   test = test_next;
271 }
272 
readOSC(WaveformGeneratorFP & source)273 reg8 WaveformGeneratorFP::readOSC(WaveformGeneratorFP& source)
274 {
275   float o[12];
276 
277   if (waveform == 0 || waveform > 7) {
278     return previous;
279   }
280 
281   /* Include effects of the test bit & ring mod */
282   reg12 oldpw = pw;
283   if (test) {
284     pw = 0;
285   }
286   reg24 oldaccumulator = accumulator;
287   accumulator ^= (waveform & 3) == 1 && ring_mod && (source.accumulator & 0x800000) ? 0x800000 : 0;
288   calculate_waveform_sample(o);
289   pw = oldpw;
290   accumulator = oldaccumulator;
291 
292   reg8 out = 0;
293   reg8 bit = 1;
294   for (int i = 4; i < 12; i ++) {
295     if (o[i] > 0.5f) {
296         out |= bit;
297     }
298     bit <<= 1;
299   }
300   return out;
301 }
302 
clock_noise(const bool clock)303 void WaveformGeneratorFP::clock_noise(const bool clock)
304 {
305   if (clock) {
306     reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
307     shift_register <<= 1;
308     shift_register |= bit0;
309   }
310 
311   // clear output bits of shift register if noise and other waveforms
312   // are selected simultaneously
313   if (waveform > 8) {
314     shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2);
315   }
316 
317   if (waveform >= 8) {
318     previous = outputN___() >> 4;
319     previous_dac = wave_zero;
320     for (int i = 0; i < 8; i ++) {
321       if (previous & (1 << i)) {
322         previous_dac += dac[i+4];
323       }
324     }
325   }
326 }
327 
outputN___()328 reg12 WaveformGeneratorFP::outputN___()
329 {
330   return
331     ((shift_register & 0x400000) >> 11) |
332     ((shift_register & 0x100000) >> 10) |
333     ((shift_register & 0x010000) >> 7) |
334     ((shift_register & 0x002000) >> 5) |
335     ((shift_register & 0x000800) >> 4) |
336     ((shift_register & 0x000080) >> 1) |
337     ((shift_register & 0x000010) << 1) |
338     ((shift_register & 0x000004) << 2);
339 }
340 
341 // ----------------------------------------------------------------------------
342 // SID reset.
343 // ----------------------------------------------------------------------------
reset()344 void WaveformGeneratorFP::reset()
345 {
346   accumulator = 0;
347   previous = 0;
348   previous_dac = 0;
349   shift_register = 0x7ffffc;
350   freq = 0;
351   pw = 0;
352   test = 0;
353   waveform = 0;
354   writeCONTROL_REG(*this, 0);
355   msb_rising = false;
356 }
357