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