home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / resid-fp / wave.h < prev    next >
C/C++ Source or Header  |  2009-01-03  |  15KB  |  458 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_FP_H__
  21. #define __WAVE_FP_H__
  22.  
  23. #include "siddefs-fp.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 WaveformGeneratorFP
  34. {
  35. public:
  36.   WaveformGeneratorFP();
  37.  
  38.   void set_sync_source(WaveformGeneratorFP*);
  39.   void set_chip_model(chip_model model);
  40.  
  41.   RESID_INLINE void clock();
  42.   RESID_INLINE void synchronize();
  43.   void reset();
  44.  
  45.   void writeFREQ_LO(reg8);
  46.   void writeFREQ_HI(reg8);
  47.   void writePW_LO(reg8);
  48.   void writePW_HI(reg8);
  49.   void writeCONTROL_REG(reg8);
  50.   reg8 readOSC();
  51.  
  52.   // 12-bit waveform output.
  53.   RESID_INLINE reg12 output();
  54.  
  55. protected:
  56.   const WaveformGeneratorFP* sync_source;
  57.   WaveformGeneratorFP* sync_dest;
  58.  
  59.   // Tell whether the accumulator MSB was set high on this cycle.
  60.   bool msb_rising;
  61.  
  62.   reg24 accumulator;
  63.   reg24 shift_register;
  64.   reg12 previous, noise_output_cached;
  65.   int noise_overwrite_delay;
  66.  
  67.   // Fout  = (Fn*Fclk/16777216)Hz
  68.   reg16 freq;
  69.   // PWout = (PWn/40.95)%, also the same << 12 for direct comparison against acc
  70.   reg12 pw; reg24 pw_acc_scale;
  71.  
  72.   // The control register right-shifted 4 bits; used for output function
  73.   // table lookup.
  74.   reg8 waveform;
  75.  
  76.   // The remaining control register bits.
  77.   reg8 test;
  78.   reg8 ring_mod;
  79.   reg8 sync;
  80.   // The gate bit is handled by the EnvelopeGenerator.
  81.  
  82.   // 16 possible combinations of waveforms.
  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 VoiceFP;
  116. friend class SIDFP;
  117. };
  118.  
  119. // ----------------------------------------------------------------------------
  120. // SID clocking - 1 cycle.
  121. // ----------------------------------------------------------------------------
  122. RESID_INLINE
  123. void WaveformGeneratorFP::clock()
  124. {
  125.   /* no digital operation if test bit is set. Only emulate analog fade. */
  126.   if (test) {
  127.     if (noise_overwrite_delay != 0) {
  128.         if (-- noise_overwrite_delay == 0) {
  129.             shift_register |= 0x7ffffc;
  130.             noise_output_cached = outputN___();
  131.         }
  132.     }
  133.     return;
  134.   }
  135.  
  136.   reg24 accumulator_prev = accumulator;
  137.  
  138.   // Calculate new accumulator value;
  139.   accumulator += freq;
  140.   accumulator &= 0xffffff;
  141.  
  142.   // Check whether the MSB became set high. This is used for synchronization.
  143.   msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000);
  144.  
  145.   // Shift noise register once for each time accumulator bit 19 is set high.
  146.   if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) {
  147.     reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
  148.     shift_register <<= 1;
  149.     // optimization: fall into the bit bucket
  150.     //shift_register &= 0x7fffff;
  151.     shift_register |= bit0;
  152.  
  153.     /* since noise changes relatively infrequently, we'll avoid the relatively
  154.      * expensive bit shuffling at output time. */
  155.     noise_output_cached = outputN___();
  156.   }
  157.  
  158.   // clear output bits of shift register if noise and other waveforms
  159.   // are selected simultaneously
  160.   if (waveform > 8) {
  161.     shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2);
  162.     noise_output_cached = outputN___();
  163.   }
  164. }
  165.  
  166. // ----------------------------------------------------------------------------
  167. // Synchronize oscillators.
  168. // This must be done after all the oscillators have been clock()'ed since the
  169. // oscillators operate in parallel.
  170. // Note that the oscillators must be clocked exactly on the cycle when the
  171. // MSB is set high for hard sync to operate correctly. See SID::clock().
  172. // ----------------------------------------------------------------------------
  173. RESID_INLINE
  174. void WaveformGeneratorFP::synchronize()
  175. {
  176.   // A special case occurs when a sync source is synced itself on the same
  177.   // cycle as when its MSB is set high. In this case the destination will
  178.   // not be synced. This has been verified by sampling OSC3.
  179.   if (msb_rising && sync_dest->sync && !(sync && sync_source->msb_rising)) {
  180.     sync_dest->accumulator = 0;
  181.   }
  182. }
  183.  
  184.  
  185. // ----------------------------------------------------------------------------
  186. // Output functions.
  187. // NB! The output from SID 8580 is delayed one cycle compared to SID 6581,
  188. // this is not modeled.
  189. // ----------------------------------------------------------------------------
  190.  
  191. // Triangle:
  192. // The upper 12 bits of the accumulator are used.
  193. // The MSB is used to create the falling edge of the triangle by inverting
  194. // the lower 11 bits. The MSB is thrown away and the lower 11 bits are
  195. // left-shifted (half the resolution, full amplitude).
  196. // Ring modulation substitutes the MSB with MSB EOR sync_source MSB.
  197. //
  198. RESID_INLINE
  199. reg12 WaveformGeneratorFP::output___T()
  200. {
  201.   reg24 msb = (ring_mod ? accumulator ^ sync_source->accumulator : accumulator)
  202.     & 0x800000;
  203.   return ((msb ? ~accumulator : accumulator) >> 11) & 0xfff;
  204. }
  205.  
  206. // Sawtooth:
  207. // The output is identical to the upper 12 bits of the accumulator.
  208. //
  209. RESID_INLINE
  210. reg12 WaveformGeneratorFP::output__S_()
  211. {
  212.   return accumulator >> 12;
  213. }
  214.  
  215. // Pulse:
  216. // The upper 12 bits of the accumulator are used.
  217. // These bits are compared to the pulse width register by a 12 bit digital
  218. // comparator; output is either all one or all zero bits.
  219. // NB! The output is actually delayed one cycle after the compare.
  220. // This is not modeled.
  221. //
  222. // The test bit, when set to one, holds the pulse waveform output at 0xfff
  223. // regardless of the pulse width setting.
  224. //
  225. RESID_INLINE
  226. reg12 WaveformGeneratorFP::output_P__()
  227. {
  228.   return (test || accumulator >= pw_acc_scale) ? 0xfff : 0x000;
  229. }
  230.  
  231. // Noise:
  232. // The noise output is taken from intermediate bits of a 23-bit shift register
  233. // which is clocked by bit 19 of the accumulator.
  234. // NB! The output is actually delayed 2 cycles after bit 19 is set high.
  235. // This is not modeled.
  236. //
  237. // Operation: Calculate EOR result, shift register, set bit 0 = result.
  238. //
  239. //                        ----------------------->---------------------
  240. //                        |                                            |
  241. //                   ----EOR----                                       |
  242. //                   |         |                                       |
  243. //                   2 2 2 1 1 1 1 1 1 1 1 1 1                         |
  244. // 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 <---
  245. //                   |   |       |     |   |       |     |   |
  246. // OSC3 bits  :      7   6       5     4   3       2     1   0
  247. //
  248. // Since waveform output is 12 bits the output is left-shifted 4 times.
  249. //
  250. RESID_INLINE
  251. reg12 WaveformGeneratorFP::outputN___()
  252. {
  253.   return
  254.     ((shift_register & 0x400000) >> 11) |
  255.     ((shift_register & 0x100000) >> 10) |
  256.     ((shift_register & 0x010000) >> 7) |
  257.     ((shift_register & 0x002000) >> 5) |
  258.     ((shift_register & 0x000800) >> 4) |
  259.     ((shift_register & 0x000080) >> 1) |
  260.     ((shift_register & 0x000010) << 1) |
  261.     ((shift_register & 0x000004) << 2);
  262. }
  263.  
  264. // Combined waveforms:
  265. // By combining waveforms, the bits of each waveform are effectively short
  266. // circuited. A zero bit in one waveform will result in a zero output bit
  267. // (thus the infamous claim that the waveforms are AND'ed).
  268. // However, a zero bit in one waveform will also affect the neighboring bits
  269. // in the output. The reason for this has not been determined.
  270. //
  271. // Example:
  272. // 
  273. //             1 1
  274. // Bit #       1 0 9 8 7 6 5 4 3 2 1 0
  275. //             -----------------------
  276. // Sawtooth    0 0 0 1 1 1 1 1 1 0 0 0
  277. //
  278. // Triangle    0 0 1 1 1 1 1 1 0 0 0 0
  279. //
  280. // AND         0 0 0 1 1 1 1 1 0 0 0 0
  281. //
  282. // Output      0 0 0 0 1 1 1 0 0 0 0 0
  283. //
  284. //
  285. // This behavior would be quite difficult to model exactly, since the SID
  286. // in this case does not act as a digital state machine. Tests show that minor
  287. // (1 bit)  differences can actually occur in the output from otherwise
  288. // identical samples from OSC3 when waveforms are combined. To further
  289. // complicate the situation the output changes slightly with time (more
  290. // neighboring bits are successively set) when the 12-bit waveform
  291. // registers are kept unchanged.
  292. //
  293. // It is probably possible to come up with a valid model for the
  294. // behavior, however this would be far too slow for practical use since it
  295. // would have to be based on the mutual influence of individual bits.
  296. //
  297. // The output is instead approximated by using the upper bits of the
  298. // accumulator as an index to look up the combined output in a table
  299. // containing actual combined waveform samples from OSC3.
  300. // These samples are 8 bit, so 4 bits of waveform resolution is lost.
  301. // All OSC3 samples are taken with FREQ=0x1000, adding a 1 to the upper 12
  302. // bits of the accumulator each cycle for a sample period of 4096 cycles.
  303. //
  304. // Sawtooth+Triangle:
  305. // The sawtooth output is used to look up an OSC3 sample.
  306. // 
  307. // Pulse+Triangle:
  308. // The triangle output is right-shifted and used to look up an OSC3 sample.
  309. // The sample is output if the pulse output is on.
  310. // The reason for using the triangle output as the index is to handle ring
  311. // modulation. Only the first half of the sample is used, which should be OK
  312. // since the triangle waveform has half the resolution of the accumulator.
  313. // 
  314. // Pulse+Sawtooth:
  315. // The sawtooth output is used to look up an OSC3 sample.
  316. // The sample is output if the pulse output is on.
  317. //
  318. // Pulse+Sawtooth+Triangle:
  319. // The sawtooth output is used to look up an OSC3 sample.
  320. // The sample is output if the pulse output is on.
  321. // 
  322. RESID_INLINE
  323. reg12 WaveformGeneratorFP::output__ST()
  324. {
  325.   return wave__ST[output__S_()] << 4;
  326. }
  327.  
  328. RESID_INLINE
  329. reg12 WaveformGeneratorFP::output_P_T()
  330. {
  331.   /* ring modulation does something odd with this waveform. But I don't know
  332.    * how to emulate it. */
  333.   return (wave_P_T[output___T() >> 1] << 4) & output_P__();
  334. }
  335.  
  336. RESID_INLINE
  337. reg12 WaveformGeneratorFP::output_PS_()
  338. {
  339.   return (wave_PS_[output__S_()] << 4) & output_P__();
  340. }
  341.  
  342. RESID_INLINE
  343. reg12 WaveformGeneratorFP::output_PST()
  344. {
  345.   return (wave_PST[output__S_()] << 4) & output_P__();
  346. }
  347.  
  348. // Combined waveforms including noise:
  349. // All waveform combinations including noise output zero after a few cycles.
  350. // NB! The effects of such combinations are not fully explored. It is claimed
  351. // that the shift register may be filled with zeroes and locked up, which
  352. // seems to be true.
  353. // We have not attempted to model this behavior, suffice to say that
  354. // there is very little audible output from waveform combinations including
  355. // noise. We hope that nobody is actually using it.
  356. //
  357. RESID_INLINE
  358. reg12 WaveformGeneratorFP::outputN__T()
  359. {
  360.   return 0;
  361. }
  362.  
  363. RESID_INLINE
  364. reg12 WaveformGeneratorFP::outputN_S_()
  365. {
  366.   return 0;
  367. }
  368.  
  369. RESID_INLINE
  370. reg12 WaveformGeneratorFP::outputN_ST()
  371. {
  372.   return 0;
  373. }
  374.  
  375. RESID_INLINE
  376. reg12 WaveformGeneratorFP::outputNP__()
  377. {
  378.   return 0;
  379. }
  380.  
  381. RESID_INLINE
  382. reg12 WaveformGeneratorFP::outputNP_T()
  383. {
  384.   return 0;
  385. }
  386.  
  387. RESID_INLINE
  388. reg12 WaveformGeneratorFP::outputNPS_()
  389. {
  390.   return 0;
  391. }
  392.  
  393. RESID_INLINE
  394. reg12 WaveformGeneratorFP::outputNPST()
  395. {
  396.   return 0;
  397. }
  398.  
  399. // ----------------------------------------------------------------------------
  400. // Select one of 16 possible combinations of waveforms.
  401. // ----------------------------------------------------------------------------
  402. RESID_INLINE
  403. reg12 WaveformGeneratorFP::output()
  404. {
  405.   switch (waveform) {
  406.   case 0x1:
  407.     previous = output___T();
  408.     break;
  409.   case 0x2:
  410.     previous = output__S_();
  411.     break;
  412.   case 0x3:
  413.     previous = output__ST();
  414.     break;
  415.   case 0x4:
  416.     previous = output_P__();
  417.     break;
  418.   case 0x5:
  419.     previous = output_P_T();
  420.     break;
  421.   case 0x6:
  422.     previous = output_PS_();
  423.     break;
  424.   case 0x7:
  425.     previous = output_PST();
  426.     break;
  427.   case 0x8:
  428.     previous = noise_output_cached;
  429.     break;
  430.   case 0x9:
  431.     previous = outputN__T();
  432.     break;
  433.   case 0xa:
  434.     previous = outputN_S_();
  435.     break;
  436.   case 0xb:
  437.     previous = outputN_ST();
  438.     break;
  439.   case 0xc:
  440.     previous = outputNP__();
  441.     break;
  442.   case 0xd:
  443.     previous = outputNP_T();
  444.     break;
  445.   case 0xe:
  446.     previous = outputNPS_();
  447.     break;
  448.   case 0xf:
  449.     previous = outputNPST();
  450.     break;
  451.   default:
  452.     break;
  453.   }
  454.   return previous;
  455. }
  456.  
  457. #endif // not __WAVE_FP_H__
  458.