home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.73.zip / src / resid / wave.h < prev    next >
Encoding:
C/C++ Source or Header  |  2014-07-23  |  15.6 KB  |  504 lines

  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
  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
  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
  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
  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
  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
  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
  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
  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
  381. reg12 WaveformGenerator::output__ST()
  382. {
  383.   return wave__ST[output__S_()] << 4;
  384. }
  385.  
  386. RESID_INLINE
  387. reg12 WaveformGenerator::output_P_T()
  388. {
  389.   return (wave_P_T[output___T() >> 1] << 4) & output_P__();
  390. }
  391.  
  392. RESID_INLINE
  393. reg12 WaveformGenerator::output_PS_()
  394. {
  395.   return (wave_PS_[output__S_()] << 4) & output_P__();
  396. }
  397.  
  398. RESID_INLINE
  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
  414. reg12 WaveformGenerator::outputN__T()
  415. {
  416.   return 0;
  417. }
  418.  
  419. RESID_INLINE
  420. reg12 WaveformGenerator::outputN_S_()
  421. {
  422.   return 0;
  423. }
  424.  
  425. RESID_INLINE
  426. reg12 WaveformGenerator::outputN_ST()
  427. {
  428.   return 0;
  429. }
  430.  
  431. RESID_INLINE
  432. reg12 WaveformGenerator::outputNP__()
  433. {
  434.   return 0;
  435. }
  436.  
  437. RESID_INLINE
  438. reg12 WaveformGenerator::outputNP_T()
  439. {
  440.   return 0;
  441. }
  442.  
  443. RESID_INLINE
  444. reg12 WaveformGenerator::outputNPS_()
  445. {
  446.   return 0;
  447. }
  448.  
  449. RESID_INLINE
  450. reg12 WaveformGenerator::outputNPST()
  451. {
  452.   return 0;
  453. }
  454.  
  455. // ----------------------------------------------------------------------------
  456. // Select one of 16 possible combinations of waveforms.
  457. // ----------------------------------------------------------------------------
  458. RESID_INLINE
  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.