libsidplayfp 2.6.0
WaveformGenerator.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2011-2023 Leandro Nini <drfiemost@users.sourceforge.net>
5 * Copyright 2007-2010 Antti Lankila
6 * Copyright 2004,2010 Dag Lem <resid@nimrod.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef WAVEFORMGENERATOR_H
24#define WAVEFORMGENERATOR_H
25
26#include "siddefs-fp.h"
27#include "array.h"
28
29#include "sidcxx11.h"
30
31// print SR debugging info
32//#define TRACE 1
33
34#ifdef TRACE
35# include <iostream>
36#endif
37
38namespace reSIDfp
39{
40
94{
95private:
96 matrix_t* model_wave;
97 matrix_t* model_pulldown;
98
99 short* wave;
100 short* pulldown;
101
102 // PWout = (PWn/40.95)%
103 unsigned int pw;
104
105 unsigned int shift_register;
106
108 unsigned int shift_latch;
109
111 int shift_pipeline;
112
113 unsigned int ring_msb_mask;
114 unsigned int no_noise;
115 unsigned int noise_output;
116 unsigned int no_noise_or_noise_output;
117 unsigned int no_pulse;
118 unsigned int pulse_output;
119
121 unsigned int waveform;
122
123 unsigned int waveform_output;
124
126 unsigned int accumulator;
127
128 // Fout = (Fn*Fclk/16777216)Hz
129 unsigned int freq;
130
132 unsigned int tri_saw_pipeline;
133
135 unsigned int osc3;
136
138 unsigned int shift_register_reset;
139
140 // The wave signal TTL when no waveform is selected.
141 unsigned int floating_output_ttl;
142
144
145 bool test;
146 bool sync;
148
150 bool test_or_reset;
151
153 bool msb_rising;
154
155 bool is6581; //-V730_NOINIT this is initialized in the SID constructor
156
157private:
158 void shift_phase2(unsigned int waveform_old, unsigned int waveform_new);
159
160 void write_shift_register();
161
162 void set_noise_output();
163
164 void set_no_noise_or_noise_output();
165
166 void waveBitfade();
167
168 void shiftregBitfade();
169
170public:
171 void setWaveformModels(matrix_t* models);
172 void setPulldownModels(matrix_t* models);
173
180 void setModel(bool is6581) { this->is6581 = is6581; }
181
185 void clock();
186
195 void synchronize(WaveformGenerator* syncDest, const WaveformGenerator* syncSource) const;
196
201 model_wave(nullptr),
202 model_pulldown(nullptr),
203 wave(nullptr),
204 pulldown(nullptr),
205 pw(0),
206 shift_register(0),
207 shift_pipeline(0),
208 ring_msb_mask(0),
209 no_noise(0),
210 noise_output(0),
211 no_noise_or_noise_output(0),
212 no_pulse(0),
213 pulse_output(0),
214 waveform(0),
215 waveform_output(0),
216 accumulator(0x555555), // Accumulator's even bits are high on powerup
217 freq(0),
218 tri_saw_pipeline(0x555),
219 osc3(0),
220 shift_register_reset(0),
221 floating_output_ttl(0),
222 test(false),
223 sync(false),
224 msb_rising(false) {}
225
231 void writeFREQ_LO(unsigned char freq_lo) { freq = (freq & 0xff00) | (freq_lo & 0xff); }
232
238 void writeFREQ_HI(unsigned char freq_hi) { freq = (freq_hi << 8 & 0xff00) | (freq & 0xff); }
239
245 void writePW_LO(unsigned char pw_lo) { pw = (pw & 0xf00) | (pw_lo & 0x0ff); }
246
252 void writePW_HI(unsigned char pw_hi) { pw = (pw_hi << 8 & 0xf00) | (pw & 0x0ff); }
253
259 void writeCONTROL_REG(unsigned char control);
260
264 void reset();
265
272 unsigned int output(const WaveformGenerator* ringModulator);
273
277 unsigned char readOSC() const { return static_cast<unsigned char>(osc3 >> 4); }
278
282 unsigned int readAccumulator() const { return accumulator; }
283
287 unsigned int readFreq() const { return freq; }
288
292 bool readTest() const { return test; }
293
297 bool readSync() const { return sync; }
298};
299
300} // namespace reSIDfp
301
302#if RESID_INLINING || defined(WAVEFORMGENERATOR_CPP)
303
304namespace reSIDfp
305{
306
307RESID_INLINE
309{
310 if (unlikely(test))
311 {
312 if (unlikely(shift_register_reset != 0) && unlikely(--shift_register_reset == 0))
313 {
314#ifdef TRACE
315 std::cout << "shiftregBitfade" << std::endl;
316#endif
317 shiftregBitfade();
318 shift_latch = shift_register;
319
320 // New noise waveform output.
321 set_noise_output();
322 }
323
324 // Latch the test bit value for shift phase 2.
325 test_or_reset = true;
326
327 // The test bit sets pulse high.
328 pulse_output = 0xfff;
329 }
330 else
331 {
332 // Calculate new accumulator value;
333 const unsigned int accumulator_old = accumulator;
334 accumulator = (accumulator + freq) & 0xffffff;
335
336 // Check which bit have changed from low to high
337 const unsigned int accumulator_bits_set = ~accumulator_old & accumulator;
338
339 // Check whether the MSB is set high. This is used for synchronization.
340 msb_rising = (accumulator_bits_set & 0x800000) != 0;
341
342 // Shift noise register once for each time accumulator bit 19 is set high.
343 // The shift is delayed 2 cycles.
344 if (unlikely((accumulator_bits_set & 0x080000) != 0))
345 {
346 // Pipeline: Detect rising bit, shift phase 1, shift phase 2.
347 shift_pipeline = 2;
348 }
349 else if (unlikely(shift_pipeline != 0))
350 {
351 switch (--shift_pipeline)
352 {
353 case 0:
354#ifdef TRACE
355 std::cout << "shift phase 2" << std::endl;
356#endif
357 shift_phase2(waveform, waveform);
358 break;
359 case 1:
360#ifdef TRACE
361 std::cout << "shift phase 1" << std::endl;
362#endif
363 // Start shift phase 1.
364 test_or_reset = false;
365 shift_latch = shift_register;
366 break;
367 }
368 }
369 }
370}
371
372RESID_INLINE
373unsigned int WaveformGenerator::output(const WaveformGenerator* ringModulator)
374{
375 // Set output value.
376 if (likely(waveform != 0))
377 {
378 const unsigned int ix = (accumulator ^ (~ringModulator->accumulator & ring_msb_mask)) >> 12;
379
380 // The bit masks no_pulse and no_noise are used to achieve branch-free
381 // calculation of the output value.
382 waveform_output = wave[ix] & (no_pulse | pulse_output) & no_noise_or_noise_output;
383 if (pulldown != nullptr)
384 waveform_output = pulldown[waveform_output];
385
386 // Triangle/Sawtooth output is delayed half cycle on 8580.
387 // This will appear as a one cycle delay on OSC3 as it is latched
388 // in the first phase of the clock.
389 if ((waveform & 3) && !is6581)
390 {
391 osc3 = tri_saw_pipeline & (no_pulse | pulse_output) & no_noise_or_noise_output;
392 if (pulldown != nullptr)
393 osc3 = pulldown[osc3];
394 tri_saw_pipeline = wave[ix];
395 }
396 else
397 {
398 osc3 = waveform_output;
399 }
400
401 // In the 6581 the top bit of the accumulator may be driven low by combined waveforms
402 // when the sawtooth is selected
403 if (is6581
404 && (waveform & 0x2)
405 && ((waveform_output & 0x800) == 0))
406 accumulator &= 0x7fffff;
407
408 write_shift_register();
409 }
410 else
411 {
412 // Age floating DAC input.
413 if (likely(floating_output_ttl != 0) && unlikely(--floating_output_ttl == 0))
414 {
415 waveBitfade();
416 }
417 }
418
419 // The pulse level is defined as (accumulator >> 12) >= pw ? 0xfff : 0x000.
420 // The expression -((accumulator >> 12) >= pw) & 0xfff yields the same
421 // results without any branching (and thus without any pipeline stalls).
422 // NB! This expression relies on that the result of a boolean expression
423 // is either 0 or 1, and furthermore requires two's complement integer.
424 // A few more cycles may be saved by storing the pulse width left shifted
425 // 12 bits, and dropping the and with 0xfff (this is valid since pulse is
426 // used as a bit mask on 12 bit values), yielding the expression
427 // -(accumulator >= pw24). However this only results in negligible savings.
428
429 // The result of the pulse width compare is delayed one cycle.
430 // Push next pulse level into pulse level pipeline.
431 pulse_output = ((accumulator >> 12) >= pw) ? 0xfff : 0x000;
432
433 return waveform_output;
434}
435
436} // namespace reSIDfp
437
438#endif
439
440#endif
Definition WaveformGenerator.h:94
void synchronize(WaveformGenerator *syncDest, const WaveformGenerator *syncSource) const
Definition WaveformGenerator.cpp:338
bool readTest() const
Definition WaveformGenerator.h:292
unsigned int output(const WaveformGenerator *ringModulator)
Definition WaveformGenerator.h:373
void clock()
Definition WaveformGenerator.h:308
unsigned int readFreq() const
Definition WaveformGenerator.h:287
void writePW_HI(unsigned char pw_hi)
Definition WaveformGenerator.h:252
void writeFREQ_HI(unsigned char freq_hi)
Definition WaveformGenerator.h:238
void writePW_LO(unsigned char pw_lo)
Definition WaveformGenerator.h:245
unsigned char readOSC() const
Definition WaveformGenerator.h:277
void writeFREQ_LO(unsigned char freq_lo)
Definition WaveformGenerator.h:231
void writeCONTROL_REG(unsigned char control)
Definition WaveformGenerator.cpp:354
WaveformGenerator()
Definition WaveformGenerator.h:200
unsigned int readAccumulator() const
Definition WaveformGenerator.h:282
bool readSync() const
Definition WaveformGenerator.h:297
void setModel(bool is6581)
Definition WaveformGenerator.h:180
void reset()
Definition WaveformGenerator.cpp:453