DOSBox-X
|
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 along 00016 // with this program; if not, write to the Free Software Foundation, Inc., 00017 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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__