00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef WAVEFORMGENERATOR_H
00024 #define WAVEFORMGENERATOR_H
00025
00026 #include "siddefs-fp.h"
00027 #include "array.h"
00028
00029 namespace reSIDfp
00030 {
00031
00046 class WaveformGenerator
00047 {
00048 private:
00049 array<short>* model_wave;
00050
00051
00052 int pw;
00053
00054 int shift_register;
00055
00059 int shift_register_reset;
00060
00064 int shift_pipeline;
00065
00066 int ring_msb_mask;
00067 int no_noise;
00068 int noise_output;
00069 int no_noise_or_noise_output;
00070 int no_pulse;
00071 int pulse_output;
00072
00076 int waveform;
00077
00078 int floating_output_ttl;
00079
00080 short* wave;
00081
00082 int waveform_output;
00083
00085 int accumulator;
00086
00087
00088 int freq;
00089
00093 bool test;
00094 bool sync;
00095
00099 bool msb_rising;
00100
00101 short dac[4096];
00102
00103 private:
00104 void clock_shift_register();
00105
00106 void write_shift_register();
00107
00108 void reset_shift_register();
00109
00110 void set_noise_output();
00111
00112 public:
00113 void setWaveformModels(array<short>* models);
00114
00122 void setChipModel(ChipModel chipModel);
00123
00127 void clock();
00128
00137 void synchronize(WaveformGenerator* syncDest, const WaveformGenerator* syncSource) const;
00138
00142 WaveformGenerator() :
00143 model_wave(0),
00144 pw(0),
00145 shift_register(0),
00146 shift_register_reset(0),
00147 shift_pipeline(0),
00148 ring_msb_mask(0),
00149 no_noise(0),
00150 noise_output(0),
00151 no_noise_or_noise_output(no_noise | noise_output),
00152 no_pulse(0),
00153 pulse_output(0),
00154 waveform(0),
00155 floating_output_ttl(0),
00156 wave(0),
00157 waveform_output(0),
00158 accumulator(0),
00159 freq(0),
00160 test(false),
00161 sync(false),
00162 msb_rising(false) {}
00163
00169 void writeFREQ_LO(unsigned char freq_lo) { freq = (freq & 0xff00) | (freq_lo & 0xff); }
00170
00176 void writeFREQ_HI(unsigned char freq_hi) { freq = (freq_hi << 8 & 0xff00) | (freq & 0xff); }
00177
00186 void writePW_LO(unsigned char pw_lo) { pw = (pw & 0xf00) | (pw_lo & 0x0ff); }
00187
00193 void writePW_HI(unsigned char pw_hi) { pw = (pw_hi << 8 & 0xf00) | (pw & 0x0ff); }
00194
00200 void writeCONTROL_REG(unsigned char control);
00201
00205 void reset();
00206
00213 short output(const WaveformGenerator* ringModulator);
00214
00220 unsigned char readOSC() const { return (unsigned char)(waveform_output >> 4); }
00221
00225 int readAccumulator() const { return accumulator; }
00226
00230 int readFreq() const { return freq; }
00231
00235 bool readTest() const { return test; }
00236
00240 bool readSync() const { return sync; }
00241 };
00242
00243 }
00244
00245 #if RESID_INLINING || defined(WAVEFORMGENERATOR_CPP)
00246
00247 namespace reSIDfp
00248 {
00249
00250 RESID_INLINE
00251 void WaveformGenerator::clock()
00252 {
00253 if (test)
00254 {
00255 if (shift_register_reset != 0 && -- shift_register_reset == 0)
00256 {
00257 reset_shift_register();
00258 }
00259
00260
00261 pulse_output = 0xfff;
00262 }
00263 else
00264 {
00265
00266 const int accumulator_next = (accumulator + freq) & 0xffffff;
00267 const int accumulator_bits_set = ~accumulator & accumulator_next;
00268 accumulator = accumulator_next;
00269
00270
00271 msb_rising = (accumulator_bits_set & 0x800000) != 0;
00272
00273
00274
00275 if ((accumulator_bits_set & 0x080000) != 0)
00276 {
00277
00278 shift_pipeline = 2;
00279 }
00280 else if (shift_pipeline != 0 && -- shift_pipeline == 0)
00281 {
00282 clock_shift_register();
00283 }
00284 }
00285 }
00286
00287 RESID_INLINE
00288 short WaveformGenerator::output(const WaveformGenerator* ringModulator)
00289 {
00290
00291 if (waveform != 0)
00292 {
00293
00294
00295 const int ix = (accumulator ^ (ringModulator->accumulator & ring_msb_mask)) >> 12;
00296 waveform_output = wave[ix] & (no_pulse | pulse_output) & no_noise_or_noise_output;
00297
00298 if (waveform > 0x8)
00299 {
00300
00301 write_shift_register();
00302 }
00303 }
00304 else
00305 {
00306
00307 if (floating_output_ttl != 0 && -- floating_output_ttl == 0)
00308 {
00309 waveform_output = 0;
00310 }
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 pulse_output = ((accumulator >> 12) >= pw) ? 0xfff : 0x000;
00326
00327
00328
00329 return dac[waveform_output];
00330 }
00331
00332 }
00333
00334 #endif
00335
00336 #endif