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 #ifndef __WAVE_H__
21 #define __WAVE_H__
22
23 #include "siddefs.h"
24
25 // ----------------------------------------------------------------------------
26 // A 24 bit accumulator is the basis for waveform generation. FREQ is added to
27 // the lower 16 bits of the accumulator each cycle.
28 // The accumulator is set to zero when TEST is set, and starts counting
29 // when TEST is cleared.
30 // The noise waveform is taken from intermediate bits of a 23 bit shift
31 // register. This register is clocked by bit 19 of the accumulator.
32 // ----------------------------------------------------------------------------
33 class WaveformGenerator
34 {
35 public:
36 WaveformGenerator();
37
38 void set_sync_source(WaveformGenerator*);
39 void set_chip_model(chip_model model);
40
41 RESID_INLINE void clock();
42 RESID_INLINE void clock(cycle_count delta_t);
43 RESID_INLINE void synchronize();
44 void reset();
45
46 void writeFREQ_LO(reg8);
47 void writeFREQ_HI(reg8);
48 void writePW_LO(reg8);
49 void writePW_HI(reg8);
50 void writeCONTROL_REG(reg8);
51 reg8 readOSC();
52
53 // 12-bit waveform output.
54 RESID_INLINE reg12 output();
55
56 protected:
57 const WaveformGenerator* sync_source;
58 WaveformGenerator* sync_dest;
59
60 // Tell whether the accumulator MSB was set high on this cycle.
61 bool msb_rising;
62
63 reg24 accumulator;
64 reg24 shift_register;
65
66 // Fout = (Fn*Fclk/16777216)Hz
67 reg16 freq;
68 // PWout = (PWn/40.95)%
69 reg12 pw;
70
71 // The control register right-shifted 4 bits; used for output function
72 // table lookup.
73 reg8 waveform;
74
75 // The remaining control register bits.
76 reg8 test;
77 reg8 ring_mod;
78 reg8 sync;
79 // The gate bit is handled by the EnvelopeGenerator.
80
81 // 16 possible combinations of waveforms.
82 RESID_INLINE reg12 output____();
83 RESID_INLINE reg12 output___T();
84 RESID_INLINE reg12 output__S_();
85 RESID_INLINE reg12 output__ST();
86 RESID_INLINE reg12 output_P__();
87 RESID_INLINE reg12 output_P_T();
88 RESID_INLINE reg12 output_PS_();
89 RESID_INLINE reg12 output_PST();
90 RESID_INLINE reg12 outputN___();
91 RESID_INLINE reg12 outputN__T();
92 RESID_INLINE reg12 outputN_S_();
93 RESID_INLINE reg12 outputN_ST();
94 RESID_INLINE reg12 outputNP__();
95 RESID_INLINE reg12 outputNP_T();
96 RESID_INLINE reg12 outputNPS_();
97 RESID_INLINE reg12 outputNPST();
98
99 // Sample data for combinations of waveforms.
100 static reg8 wave6581__ST[];
101 static reg8 wave6581_P_T[];
102 static reg8 wave6581_PS_[];
103 static reg8 wave6581_PST[];
104
105 static reg8 wave8580__ST[];
106 static reg8 wave8580_P_T[];
107 static reg8 wave8580_PS_[];
108 static reg8 wave8580_PST[];
109
110 reg8* wave__ST;
111 reg8* wave_P_T;
112 reg8* wave_PS_;
113 reg8* wave_PST;
114
115 friend class Voice;
116 friend class SID;
117 };
118
119
120 // ----------------------------------------------------------------------------
121 // Inline functions.
122 // The following functions are defined inline because they are called every
123 // time a sample is calculated.
124 // ----------------------------------------------------------------------------
125
126 #if RESID_INLINING || defined(__WAVE_CC__)
127
128 // ----------------------------------------------------------------------------
129 // SID clocking - 1 cycle.
130 // ----------------------------------------------------------------------------
131 RESID_INLINE
clock()132 void WaveformGenerator::clock()
133 {
134 // No operation if test bit is set.
135 if (test) {
136 return;
137 }
138
139 reg24 accumulator_prev = accumulator;
140
141 // Calculate new accumulator value;
142 accumulator += freq;
143 accumulator &= 0xffffff;
144
145 // Check whether the MSB is set high. This is used for synchronization.
146 msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000);
147
148 // Shift noise register once for each time accumulator bit 19 is set high.
149 if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) {
150 reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
151 shift_register <<= 1;
152 shift_register &= 0x7fffff;
153 shift_register |= bit0;
154 }
155 }
156
157 // ----------------------------------------------------------------------------
158 // SID clocking - delta_t cycles.
159 // ----------------------------------------------------------------------------
160 RESID_INLINE
clock(cycle_count delta_t)161 void WaveformGenerator::clock(cycle_count delta_t)
162 {
163 // No operation if test bit is set.
164 if (test) {
165 return;
166 }
167
168 reg24 accumulator_prev = accumulator;
169
170 // Calculate new accumulator value;
171 reg24 delta_accumulator = delta_t*freq;
172 accumulator += delta_accumulator;
173 accumulator &= 0xffffff;
174
175 // Check whether the MSB is set high. This is used for synchronization.
176 msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000);
177
178 // Shift noise register once for each time accumulator bit 19 is set high.
179 // Bit 19 is set high each time 2^20 (0x100000) is added to the accumulator.
180 reg24 shift_period = 0x100000;
181
182 while (delta_accumulator) {
183 if (delta_accumulator < shift_period) {
184 shift_period = delta_accumulator;
185 // Determine whether bit 19 is set on the last period.
186 // NB! Requires two's complement integer.
187 if (shift_period <= 0x080000) {
188 // Check for flip from 0 to 1.
189 if (((accumulator - shift_period) & 0x080000) || !(accumulator & 0x080000))
190 {
191 break;
192 }
193 }
194 else {
195 // Check for flip from 0 (to 1 or via 1 to 0) or from 1 via 0 to 1.
196 if (((accumulator - shift_period) & 0x080000) && !(accumulator & 0x080000))
197 {
198 break;
199 }
200 }
201 }
202
203 // Shift the noise/random register.
204 // NB! The shift is actually delayed 2 cycles, this is not modeled.
205 reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
206 shift_register <<= 1;
207 shift_register &= 0x7fffff;
208 shift_register |= bit0;
209
210 delta_accumulator -= shift_period;
211 }
212 }
213
214
215 // ----------------------------------------------------------------------------
216 // Synchronize oscillators.
217 // This must be done after all the oscillators have been clock()'ed since the
218 // oscillators operate in parallel.
219 // Note that the oscillators must be clocked exactly on the cycle when the
220 // MSB is set high for hard sync to operate correctly. See SID::clock().
221 // ----------------------------------------------------------------------------
222 RESID_INLINE
synchronize()223 void WaveformGenerator::synchronize()
224 {
225 // A special case occurs when a sync source is synced itself on the same
226 // cycle as when its MSB is set high. In this case the destination will
227 // not be synced. This has been verified by sampling OSC3.
228 if (msb_rising && sync_dest->sync && !(sync && sync_source->msb_rising)) {
229 sync_dest->accumulator = 0;
230 }
231 }
232
233
234 // ----------------------------------------------------------------------------
235 // Output functions.
236 // NB! The output from SID 8580 is delayed one cycle compared to SID 6581,
237 // this is not modeled.
238 // ----------------------------------------------------------------------------
239
240 // No waveform:
241 // Zero output.
242 //
243 RESID_INLINE
output____()244 reg12 WaveformGenerator::output____()
245 {
246 return 0x000;
247 }
248
249 // Triangle:
250 // The upper 12 bits of the accumulator are used.
251 // The MSB is used to create the falling edge of the triangle by inverting
252 // the lower 11 bits. The MSB is thrown away and the lower 11 bits are
253 // left-shifted (half the resolution, full amplitude).
254 // Ring modulation substitutes the MSB with MSB EOR sync_source MSB.
255 //
256 RESID_INLINE
output___T()257 reg12 WaveformGenerator::output___T()
258 {
259 reg24 msb = (ring_mod ? accumulator ^ sync_source->accumulator : accumulator)
260 & 0x800000;
261 return ((msb ? ~accumulator : accumulator) >> 11) & 0xfff;
262 }
263
264 // Sawtooth:
265 // The output is identical to the upper 12 bits of the accumulator.
266 //
267 RESID_INLINE
output__S_()268 reg12 WaveformGenerator::output__S_()
269 {
270 return accumulator >> 12;
271 }
272
273 // Pulse:
274 // The upper 12 bits of the accumulator are used.
275 // These bits are compared to the pulse width register by a 12 bit digital
276 // comparator; output is either all one or all zero bits.
277 // NB! The output is actually delayed one cycle after the compare.
278 // This is not modeled.
279 //
280 // The test bit, when set to one, holds the pulse waveform output at 0xfff
281 // regardless of the pulse width setting.
282 //
283 RESID_INLINE
output_P__()284 reg12 WaveformGenerator::output_P__()
285 {
286 return (test || (accumulator >> 12) >= pw) ? 0xfff : 0x000;
287 }
288
289 // Noise:
290 // The noise output is taken from intermediate bits of a 23-bit shift register
291 // which is clocked by bit 19 of the accumulator.
292 // NB! The output is actually delayed 2 cycles after bit 19 is set high.
293 // This is not modeled.
294 //
295 // Operation: Calculate EOR result, shift register, set bit 0 = result.
296 //
297 // ----------------------->---------------------
298 // | |
299 // ----EOR---- |
300 // | | |
301 // 2 2 2 1 1 1 1 1 1 1 1 1 1 |
302 // Register bits: 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 <---
303 // | | | | | | | |
304 // OSC3 bits : 7 6 5 4 3 2 1 0
305 //
306 // Since waveform output is 12 bits the output is left-shifted 4 times.
307 //
308 RESID_INLINE
outputN___()309 reg12 WaveformGenerator::outputN___()
310 {
311 return
312 ((shift_register & 0x400000) >> 11) |
313 ((shift_register & 0x100000) >> 10) |
314 ((shift_register & 0x010000) >> 7) |
315 ((shift_register & 0x002000) >> 5) |
316 ((shift_register & 0x000800) >> 4) |
317 ((shift_register & 0x000080) >> 1) |
318 ((shift_register & 0x000010) << 1) |
319 ((shift_register & 0x000004) << 2);
320 }
321
322 // Combined waveforms:
323 // By combining waveforms, the bits of each waveform are effectively short
324 // circuited. A zero bit in one waveform will result in a zero output bit
325 // (thus the infamous claim that the waveforms are AND'ed).
326 // However, a zero bit in one waveform will also affect the neighboring bits
327 // in the output. The reason for this has not been determined.
328 //
329 // Example:
330 //
331 // 1 1
332 // Bit # 1 0 9 8 7 6 5 4 3 2 1 0
333 // -----------------------
334 // Sawtooth 0 0 0 1 1 1 1 1 1 0 0 0
335 //
336 // Triangle 0 0 1 1 1 1 1 1 0 0 0 0
337 //
338 // AND 0 0 0 1 1 1 1 1 0 0 0 0
339 //
340 // Output 0 0 0 0 1 1 1 0 0 0 0 0
341 //
342 //
343 // This behavior would be quite difficult to model exactly, since the SID
344 // in this case does not act as a digital state machine. Tests show that minor
345 // (1 bit) differences can actually occur in the output from otherwise
346 // identical samples from OSC3 when waveforms are combined. To further
347 // complicate the situation the output changes slightly with time (more
348 // neighboring bits are successively set) when the 12-bit waveform
349 // registers are kept unchanged.
350 //
351 // It is probably possible to come up with a valid model for the
352 // behavior, however this would be far too slow for practical use since it
353 // would have to be based on the mutual influence of individual bits.
354 //
355 // The output is instead approximated by using the upper bits of the
356 // accumulator as an index to look up the combined output in a table
357 // containing actual combined waveform samples from OSC3.
358 // These samples are 8 bit, so 4 bits of waveform resolution is lost.
359 // All OSC3 samples are taken with FREQ=0x1000, adding a 1 to the upper 12
360 // bits of the accumulator each cycle for a sample period of 4096 cycles.
361 //
362 // Sawtooth+Triangle:
363 // The sawtooth output is used to look up an OSC3 sample.
364 //
365 // Pulse+Triangle:
366 // The triangle output is right-shifted and used to look up an OSC3 sample.
367 // The sample is output if the pulse output is on.
368 // The reason for using the triangle output as the index is to handle ring
369 // modulation. Only the first half of the sample is used, which should be OK
370 // since the triangle waveform has half the resolution of the accumulator.
371 //
372 // Pulse+Sawtooth:
373 // The sawtooth output is used to look up an OSC3 sample.
374 // The sample is output if the pulse output is on.
375 //
376 // Pulse+Sawtooth+Triangle:
377 // The sawtooth output is used to look up an OSC3 sample.
378 // The sample is output if the pulse output is on.
379 //
380 RESID_INLINE
output__ST()381 reg12 WaveformGenerator::output__ST()
382 {
383 return wave__ST[output__S_()] << 4;
384 }
385
386 RESID_INLINE
output_P_T()387 reg12 WaveformGenerator::output_P_T()
388 {
389 return (wave_P_T[output___T() >> 1] << 4) & output_P__();
390 }
391
392 RESID_INLINE
output_PS_()393 reg12 WaveformGenerator::output_PS_()
394 {
395 return (wave_PS_[output__S_()] << 4) & output_P__();
396 }
397
398 RESID_INLINE
output_PST()399 reg12 WaveformGenerator::output_PST()
400 {
401 return (wave_PST[output__S_()] << 4) & output_P__();
402 }
403
404 // Combined waveforms including noise:
405 // All waveform combinations including noise output zero after a few cycles.
406 // NB! The effects of such combinations are not fully explored. It is claimed
407 // that the shift register may be filled with zeroes and locked up, which
408 // seems to be true.
409 // We have not attempted to model this behavior, suffice to say that
410 // there is very little audible output from waveform combinations including
411 // noise. We hope that nobody is actually using it.
412 //
413 RESID_INLINE
outputN__T()414 reg12 WaveformGenerator::outputN__T()
415 {
416 return 0;
417 }
418
419 RESID_INLINE
outputN_S_()420 reg12 WaveformGenerator::outputN_S_()
421 {
422 return 0;
423 }
424
425 RESID_INLINE
outputN_ST()426 reg12 WaveformGenerator::outputN_ST()
427 {
428 return 0;
429 }
430
431 RESID_INLINE
outputNP__()432 reg12 WaveformGenerator::outputNP__()
433 {
434 return 0;
435 }
436
437 RESID_INLINE
outputNP_T()438 reg12 WaveformGenerator::outputNP_T()
439 {
440 return 0;
441 }
442
443 RESID_INLINE
outputNPS_()444 reg12 WaveformGenerator::outputNPS_()
445 {
446 return 0;
447 }
448
449 RESID_INLINE
outputNPST()450 reg12 WaveformGenerator::outputNPST()
451 {
452 return 0;
453 }
454
455 // ----------------------------------------------------------------------------
456 // Select one of 16 possible combinations of waveforms.
457 // ----------------------------------------------------------------------------
458 RESID_INLINE
output()459 reg12 WaveformGenerator::output()
460 {
461 // It may seem cleaner to use an array of member functions to return
462 // waveform output; however a switch with inline functions is faster.
463
464 switch (waveform) {
465 default:
466 case 0x0:
467 return output____();
468 case 0x1:
469 return output___T();
470 case 0x2:
471 return output__S_();
472 case 0x3:
473 return output__ST();
474 case 0x4:
475 return output_P__();
476 case 0x5:
477 return output_P_T();
478 case 0x6:
479 return output_PS_();
480 case 0x7:
481 return output_PST();
482 case 0x8:
483 return outputN___();
484 case 0x9:
485 return outputN__T();
486 case 0xa:
487 return outputN_S_();
488 case 0xb:
489 return outputN_ST();
490 case 0xc:
491 return outputNP__();
492 case 0xd:
493 return outputNP_T();
494 case 0xe:
495 return outputNPS_();
496 case 0xf:
497 return outputNPST();
498 }
499 }
500
501 #endif // RESID_INLINING || defined(__WAVE_CC__)
502
503 #endif // not __WAVE_H__
504