DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/hardware/reSID/wave.h
00001 //  ---------------------------------------------------------------------------
00002 //  This file is part of reSID, a MOS6581 SID emulator engine.
00003 //  Copyright (C) 2004  Dag Lem <resid@nimrod.no>
00004 //
00005 //  This program is free software; you can redistribute it and/or modify
00006 //  it under the terms of the GNU General Public License as published by
00007 //  the Free Software Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //
00010 //  This program is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License
00016 //  along with this program; if not, write to the Free Software
00017 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //  ---------------------------------------------------------------------------
00019 
00020 #ifndef __WAVE_H__
00021 #define __WAVE_H__
00022 
00023 #include "siddefs.h"
00024 #include <sstream>
00025 
00026 // ----------------------------------------------------------------------------
00027 // A 24 bit accumulator is the basis for waveform generation. FREQ is added to
00028 // the lower 16 bits of the accumulator each cycle.
00029 // The accumulator is set to zero when TEST is set, and starts counting
00030 // when TEST is cleared.
00031 // The noise waveform is taken from intermediate bits of a 23 bit shift
00032 // register. This register is clocked by bit 19 of the accumulator.
00033 // ----------------------------------------------------------------------------
00034 class WaveformGenerator
00035 {
00036 public:
00037   WaveformGenerator();
00038 
00039   void set_sync_source(WaveformGenerator*);
00040   void set_chip_model(chip_model model);
00041 
00042   RESID_INLINE void clock();
00043   RESID_INLINE void clock(cycle_count delta_t);
00044   RESID_INLINE void synchronize();
00045   void reset();
00046 
00047   void writeFREQ_LO(reg8);
00048   void writeFREQ_HI(reg8);
00049   void writePW_LO(reg8);
00050   void writePW_HI(reg8);
00051   void writeCONTROL_REG(reg8);
00052   reg8 readOSC();
00053 
00054   // 12-bit waveform output.
00055   RESID_INLINE reg12 output();
00056 
00057         void SaveState( std::ostream& stream );
00058         void LoadState( std::istream& stream );
00059 
00060 protected:
00061   const WaveformGenerator* sync_source;
00062   WaveformGenerator* sync_dest;
00063 
00064   // Tell whether the accumulator MSB was set high on this cycle.
00065   bool msb_rising;
00066 
00067   reg24 accumulator;
00068   reg24 shift_register;
00069 
00070   // Fout  = (Fn*Fclk/16777216)Hz
00071   reg16 freq;
00072   // PWout = (PWn/40.95)%
00073   reg12 pw;
00074 
00075   // The control register right-shifted 4 bits; used for output function
00076   // table lookup.
00077   reg8 waveform;
00078 
00079   // The remaining control register bits.
00080   reg8 test;
00081   reg8 ring_mod;
00082   reg8 sync;
00083   // The gate bit is handled by the EnvelopeGenerator.
00084 
00085   // 16 possible combinations of waveforms.
00086   RESID_INLINE reg12 output____();
00087   RESID_INLINE reg12 output___T();
00088   RESID_INLINE reg12 output__S_();
00089   RESID_INLINE reg12 output__ST();
00090   RESID_INLINE reg12 output_P__();
00091   RESID_INLINE reg12 output_P_T();
00092   RESID_INLINE reg12 output_PS_();
00093   RESID_INLINE reg12 output_PST();
00094   RESID_INLINE reg12 outputN___();
00095   RESID_INLINE reg12 outputN__T();
00096   RESID_INLINE reg12 outputN_S_();
00097   RESID_INLINE reg12 outputN_ST();
00098   RESID_INLINE reg12 outputNP__();
00099   RESID_INLINE reg12 outputNP_T();
00100   RESID_INLINE reg12 outputNPS_();
00101   RESID_INLINE reg12 outputNPST();
00102 
00103   // Sample data for combinations of waveforms.
00104   static reg8 wave6581__ST[];
00105   static reg8 wave6581_P_T[];
00106   static reg8 wave6581_PS_[];
00107   static reg8 wave6581_PST[];
00108 
00109   static reg8 wave8580__ST[];
00110   static reg8 wave8580_P_T[];
00111   static reg8 wave8580_PS_[];
00112   static reg8 wave8580_PST[];
00113 
00114   reg8* wave__ST;
00115   reg8* wave_P_T;
00116   reg8* wave_PS_;
00117   reg8* wave_PST;
00118 
00119 friend class Voice;
00120 friend class SID2;
00121 };
00122 
00123 
00124 // ----------------------------------------------------------------------------
00125 // Inline functions.
00126 // The following functions are defined inline because they are called every
00127 // time a sample is calculated.
00128 // ----------------------------------------------------------------------------
00129 
00130 #if RESID_INLINING || defined(__WAVE_CC__)
00131 
00132 // ----------------------------------------------------------------------------
00133 // SID clocking - 1 cycle.
00134 // ----------------------------------------------------------------------------
00135 RESID_INLINE
00136 void WaveformGenerator::clock()
00137 {
00138   // No operation if test bit is set.
00139   if (test) {
00140     return;
00141   }
00142 
00143   reg24 accumulator_prev = accumulator;
00144 
00145   // Calculate new accumulator value;
00146   accumulator += freq;
00147   accumulator &= 0xffffff;
00148 
00149   // Check whether the MSB is set high. This is used for synchronization.
00150   msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000);
00151 
00152   // Shift noise register once for each time accumulator bit 19 is set high.
00153   if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) {
00154     reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
00155     shift_register <<= 1;
00156     shift_register &= 0x7fffff;
00157     shift_register |= bit0;
00158   }
00159 }
00160 
00161 // ----------------------------------------------------------------------------
00162 // SID clocking - delta_t cycles.
00163 // ----------------------------------------------------------------------------
00164 RESID_INLINE
00165 void WaveformGenerator::clock(cycle_count delta_t)
00166 {
00167   // No operation if test bit is set.
00168   if (test) {
00169     return;
00170   }
00171 
00172   reg24 accumulator_prev = accumulator;
00173 
00174   // Calculate new accumulator value;
00175   reg24 delta_accumulator = (unsigned int)(delta_t * (cycle_count)freq);
00176   accumulator += delta_accumulator;
00177   accumulator &= 0xffffff;
00178 
00179   // Check whether the MSB is set high. This is used for synchronization.
00180   msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000);
00181 
00182   // Shift noise register once for each time accumulator bit 19 is set high.
00183   // Bit 19 is set high each time 2^20 (0x100000) is added to the accumulator.
00184   reg24 shift_period = 0x100000;
00185 
00186   while (delta_accumulator) {
00187     if (delta_accumulator < shift_period) {
00188       shift_period = delta_accumulator;
00189       // Determine whether bit 19 is set on the last period.
00190       // NB! Requires two's complement integer.
00191       if (shift_period <= 0x080000) {
00192         // Check for flip from 0 to 1.
00193         if (((accumulator - shift_period) & 0x080000) || !(accumulator & 0x080000))
00194         {
00195           break;
00196         }
00197       }
00198       else {
00199         // Check for flip from 0 (to 1 or via 1 to 0) or from 1 via 0 to 1.
00200         if (((accumulator - shift_period) & 0x080000) && !(accumulator & 0x080000))
00201         {
00202           break;
00203         }
00204       }
00205     }
00206 
00207     // Shift the noise/random register.
00208     // NB! The shift is actually delayed 2 cycles, this is not modeled.
00209     reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
00210     shift_register <<= 1;
00211     shift_register &= 0x7fffff;
00212     shift_register |= bit0;
00213 
00214     delta_accumulator -= shift_period;
00215   }
00216 }
00217 
00218 
00219 // ----------------------------------------------------------------------------
00220 // Synchronize oscillators.
00221 // This must be done after all the oscillators have been clock()'ed since the
00222 // oscillators operate in parallel.
00223 // Note that the oscillators must be clocked exactly on the cycle when the
00224 // MSB is set high for hard sync to operate correctly. See SID2::clock().
00225 // ----------------------------------------------------------------------------
00226 RESID_INLINE
00227 void WaveformGenerator::synchronize()
00228 {
00229   // A special case occurs when a sync source is synced itself on the same
00230   // cycle as when its MSB is set high. In this case the destination will
00231   // not be synced. This has been verified by sampling OSC3.
00232   if (msb_rising && sync_dest->sync && !(sync && sync_source->msb_rising)) {
00233     sync_dest->accumulator = 0;
00234   }
00235 }
00236 
00237 
00238 // ----------------------------------------------------------------------------
00239 // Output functions.
00240 // NB! The output from SID 8580 is delayed one cycle compared to SID 6581,
00241 // this is not modeled.
00242 // ----------------------------------------------------------------------------
00243 
00244 // No waveform:
00245 // Zero output.
00246 //
00247 RESID_INLINE
00248 reg12 WaveformGenerator::output____()
00249 {
00250   return 0x000;
00251 }
00252 
00253 // Triangle:
00254 // The upper 12 bits of the accumulator are used.
00255 // The MSB is used to create the falling edge of the triangle by inverting
00256 // the lower 11 bits. The MSB is thrown away and the lower 11 bits are
00257 // left-shifted (half the resolution, full amplitude).
00258 // Ring modulation substitutes the MSB with MSB EOR sync_source MSB.
00259 //
00260 RESID_INLINE
00261 reg12 WaveformGenerator::output___T()
00262 {
00263   reg24 msb = (ring_mod ? accumulator ^ sync_source->accumulator : accumulator)
00264     & 0x800000;
00265   return ((msb ? ~accumulator : accumulator) >> 11) & 0xfff;
00266 }
00267 
00268 // Sawtooth:
00269 // The output is identical to the upper 12 bits of the accumulator.
00270 //
00271 RESID_INLINE
00272 reg12 WaveformGenerator::output__S_()
00273 {
00274   return accumulator >> 12;
00275 }
00276 
00277 // Pulse:
00278 // The upper 12 bits of the accumulator are used.
00279 // These bits are compared to the pulse width register by a 12 bit digital
00280 // comparator; output is either all one or all zero bits.
00281 // NB! The output is actually delayed one cycle after the compare.
00282 // This is not modeled.
00283 //
00284 // The test bit, when set to one, holds the pulse waveform output at 0xfff
00285 // regardless of the pulse width setting.
00286 //
00287 RESID_INLINE
00288 reg12 WaveformGenerator::output_P__()
00289 {
00290   return (test || (accumulator >> 12) >= pw) ? 0xfff : 0x000;
00291 }
00292 
00293 // Noise:
00294 // The noise output is taken from intermediate bits of a 23-bit shift register
00295 // which is clocked by bit 19 of the accumulator.
00296 // NB! The output is actually delayed 2 cycles after bit 19 is set high.
00297 // This is not modeled.
00298 //
00299 // Operation: Calculate EOR result, shift register, set bit 0 = result.
00300 //
00301 //                        ----------------------->---------------------
00302 //                        |                                            |
00303 //                   ----EOR----                                       |
00304 //                   |         |                                       |
00305 //                   2 2 2 1 1 1 1 1 1 1 1 1 1                         |
00306 // 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 <---
00307 //                   |   |       |     |   |       |     |   |
00308 // OSC3 bits  :      7   6       5     4   3       2     1   0
00309 //
00310 // Since waveform output is 12 bits the output is left-shifted 4 times.
00311 //
00312 RESID_INLINE
00313 reg12 WaveformGenerator::outputN___()
00314 {
00315   return
00316     ((shift_register & 0x400000) >> 11) |
00317     ((shift_register & 0x100000) >> 10) |
00318     ((shift_register & 0x010000) >> 7) |
00319     ((shift_register & 0x002000) >> 5) |
00320     ((shift_register & 0x000800) >> 4) |
00321     ((shift_register & 0x000080) >> 1) |
00322     ((shift_register & 0x000010) << 1) |
00323     ((shift_register & 0x000004) << 2);
00324 }
00325 
00326 // Combined waveforms:
00327 // By combining waveforms, the bits of each waveform are effectively short
00328 // circuited. A zero bit in one waveform will result in a zero output bit
00329 // (thus the infamous claim that the waveforms are AND'ed).
00330 // However, a zero bit in one waveform will also affect the neighboring bits
00331 // in the output. The reason for this has not been determined.
00332 //
00333 // Example:
00334 // 
00335 //             1 1
00336 // Bit #       1 0 9 8 7 6 5 4 3 2 1 0
00337 //             -----------------------
00338 // Sawtooth    0 0 0 1 1 1 1 1 1 0 0 0
00339 //
00340 // Triangle    0 0 1 1 1 1 1 1 0 0 0 0
00341 //
00342 // AND         0 0 0 1 1 1 1 1 0 0 0 0
00343 //
00344 // Output      0 0 0 0 1 1 1 0 0 0 0 0
00345 //
00346 //
00347 // This behavior would be quite difficult to model exactly, since the SID
00348 // in this case does not act as a digital state machine. Tests show that minor
00349 // (1 bit)  differences can actually occur in the output from otherwise
00350 // identical samples from OSC3 when waveforms are combined. To further
00351 // complicate the situation the output changes slightly with time (more
00352 // neighboring bits are successively set) when the 12-bit waveform
00353 // registers are kept unchanged.
00354 //
00355 // It is probably possible to come up with a valid model for the
00356 // behavior, however this would be far too slow for practical use since it
00357 // would have to be based on the mutual influence of individual bits.
00358 //
00359 // The output is instead approximated by using the upper bits of the
00360 // accumulator as an index to look up the combined output in a table
00361 // containing actual combined waveform samples from OSC3.
00362 // These samples are 8 bit, so 4 bits of waveform resolution is lost.
00363 // All OSC3 samples are taken with FREQ=0x1000, adding a 1 to the upper 12
00364 // bits of the accumulator each cycle for a sample period of 4096 cycles.
00365 //
00366 // Sawtooth+Triangle:
00367 // The sawtooth output is used to look up an OSC3 sample.
00368 // 
00369 // Pulse+Triangle:
00370 // The triangle output is right-shifted and used to look up an OSC3 sample.
00371 // The sample is output if the pulse output is on.
00372 // The reason for using the triangle output as the index is to handle ring
00373 // modulation. Only the first half of the sample is used, which should be OK
00374 // since the triangle waveform has half the resolution of the accumulator.
00375 // 
00376 // Pulse+Sawtooth:
00377 // The sawtooth output is used to look up an OSC3 sample.
00378 // The sample is output if the pulse output is on.
00379 //
00380 // Pulse+Sawtooth+Triangle:
00381 // The sawtooth output is used to look up an OSC3 sample.
00382 // The sample is output if the pulse output is on.
00383 // 
00384 RESID_INLINE
00385 reg12 WaveformGenerator::output__ST()
00386 {
00387   return wave__ST[output__S_()] << 4;
00388 }
00389 
00390 RESID_INLINE
00391 reg12 WaveformGenerator::output_P_T()
00392 {
00393   return (wave_P_T[output___T() >> 1] << 4) & output_P__();
00394 }
00395 
00396 RESID_INLINE
00397 reg12 WaveformGenerator::output_PS_()
00398 {
00399   return (wave_PS_[output__S_()] << 4) & output_P__();
00400 }
00401 
00402 RESID_INLINE
00403 reg12 WaveformGenerator::output_PST()
00404 {
00405   return (wave_PST[output__S_()] << 4) & output_P__();
00406 }
00407 
00408 // Combined waveforms including noise:
00409 // All waveform combinations including noise output zero after a few cycles.
00410 // NB! The effects of such combinations are not fully explored. It is claimed
00411 // that the shift register may be filled with zeroes and locked up, which
00412 // seems to be true.
00413 // We have not attempted to model this behavior, suffice to say that
00414 // there is very little audible output from waveform combinations including
00415 // noise. We hope that nobody is actually using it.
00416 //
00417 RESID_INLINE
00418 reg12 WaveformGenerator::outputN__T()
00419 {
00420   return 0;
00421 }
00422 
00423 RESID_INLINE
00424 reg12 WaveformGenerator::outputN_S_()
00425 {
00426   return 0;
00427 }
00428 
00429 RESID_INLINE
00430 reg12 WaveformGenerator::outputN_ST()
00431 {
00432   return 0;
00433 }
00434 
00435 RESID_INLINE
00436 reg12 WaveformGenerator::outputNP__()
00437 {
00438   return 0;
00439 }
00440 
00441 RESID_INLINE
00442 reg12 WaveformGenerator::outputNP_T()
00443 {
00444   return 0;
00445 }
00446 
00447 RESID_INLINE
00448 reg12 WaveformGenerator::outputNPS_()
00449 {
00450   return 0;
00451 }
00452 
00453 RESID_INLINE
00454 reg12 WaveformGenerator::outputNPST()
00455 {
00456   return 0;
00457 }
00458 
00459 // ----------------------------------------------------------------------------
00460 // Select one of 16 possible combinations of waveforms.
00461 // ----------------------------------------------------------------------------
00462 RESID_INLINE
00463 reg12 WaveformGenerator::output()
00464 {
00465   // It may seem cleaner to use an array of member functions to return
00466   // waveform output; however a switch with inline functions is faster.
00467 
00468   switch (waveform) {
00469   default:
00470   case 0x0:
00471     return output____();
00472   case 0x1:
00473     return output___T();
00474   case 0x2:
00475     return output__S_();
00476   case 0x3:
00477     return output__ST();
00478   case 0x4:
00479     return output_P__();
00480   case 0x5:
00481     return output_P_T();
00482   case 0x6:
00483     return output_PS_();
00484   case 0x7:
00485     return output_PST();
00486   case 0x8:
00487     return outputN___();
00488   case 0x9:
00489     return outputN__T();
00490   case 0xa:
00491     return outputN_S_();
00492   case 0xb:
00493     return outputN_ST();
00494   case 0xc:
00495     return outputNP__();
00496   case 0xd:
00497     return outputNP_T();
00498   case 0xe:
00499     return outputNPS_();
00500   case 0xf:
00501     return outputNPST();
00502   }
00503 }
00504 
00505 #endif // RESID_INLINING || defined(__WAVE_CC__)
00506 
00507 #endif // not __WAVE_H__