home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / resid-fp / wave.cpp < prev    next >
C/C++ Source or Header  |  2009-01-03  |  5KB  |  152 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. #define __WAVE_CC__
  21. #include "wave.h"
  22.  
  23. // ----------------------------------------------------------------------------
  24. // Constructor.
  25. // ----------------------------------------------------------------------------
  26. WaveformGeneratorFP::WaveformGeneratorFP()
  27. {
  28.   sync_source = this;
  29.  
  30.   set_chip_model(MOS6581FP);
  31.  
  32.   reset();
  33. }
  34.  
  35.  
  36. // ----------------------------------------------------------------------------
  37. // Set sync source.
  38. // ----------------------------------------------------------------------------
  39. void WaveformGeneratorFP::set_sync_source(WaveformGeneratorFP* source)
  40. {
  41.   sync_source = source;
  42.   source->sync_dest = this;
  43. }
  44.  
  45.  
  46. // ----------------------------------------------------------------------------
  47. // Set chip model.
  48. // ----------------------------------------------------------------------------
  49. void WaveformGeneratorFP::set_chip_model(chip_model model)
  50. {
  51.   if (model == MOS6581FP) {
  52.     wave__ST = wave6581__ST;
  53.     wave_P_T = wave6581_P_T;
  54.     wave_PS_ = wave6581_PS_;
  55.     wave_PST = wave6581_PST;
  56.   }
  57.   else {
  58.     wave__ST = wave8580__ST;
  59.     wave_P_T = wave8580_P_T;
  60.     wave_PS_ = wave8580_PS_;
  61.     wave_PST = wave8580_PST;
  62.   }
  63. }
  64.  
  65.  
  66. // ----------------------------------------------------------------------------
  67. // Register functions.
  68. // ----------------------------------------------------------------------------
  69. void WaveformGeneratorFP::writeFREQ_LO(reg8 freq_lo)
  70. {
  71.   freq = (freq & 0xff00) | (freq_lo & 0x00ff);
  72. }
  73.  
  74. void WaveformGeneratorFP::writeFREQ_HI(reg8 freq_hi)
  75. {
  76.   freq = ((freq_hi << 8) & 0xff00) | (freq & 0x00ff);
  77. }
  78.  
  79. /* The original form was (acc >> 12) >= pw, where truth value is not affected
  80.  * by the contents of the low 12 bits. Therefore the lowest bits must be zero
  81.  * in the new formulation acc >= (pw << 12). */
  82. void WaveformGeneratorFP::writePW_LO(reg8 pw_lo)
  83. {
  84.   pw = (pw & 0xf00) | (pw_lo & 0x0ff);
  85.   pw_acc_scale = pw << 12;
  86. }
  87.  
  88. void WaveformGeneratorFP::writePW_HI(reg8 pw_hi)
  89. {
  90.   pw = ((pw_hi << 8) & 0xf00) | (pw & 0x0ff);
  91.   pw_acc_scale = pw << 12;
  92. }
  93.  
  94. void WaveformGeneratorFP::writeCONTROL_REG(reg8 control)
  95. {
  96.   waveform = (control >> 4) & 0x0f;
  97.   ring_mod = control & 0x04;
  98.   sync = control & 0x02;
  99.  
  100.   reg8 test_next = control & 0x08;
  101.  
  102.   /* SounDemoN found out that test bit can be used to control the noise
  103.    * register. Hear the result in Bojojoing.sid. */
  104.  
  105.   // testbit set. invert bit 19 and write it to bit 1
  106.   if (test_next && !test) {
  107.     accumulator = 0;
  108.     reg24 bit19 = (shift_register >> 19) & 1;
  109.     shift_register = (shift_register & 0x7ffffd) | ((bit19^1) << 1);
  110.     noise_overwrite_delay = 200000; /* 200 ms, probably too generous? */
  111.   }
  112.   // Test bit cleared.
  113.   // The accumulator starts counting, and the shift register is reset to
  114.   // the value 0x7ffff8.
  115.   else if (!test_next && test) {
  116.     reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1;
  117.     shift_register <<= 1;
  118.     shift_register |= bit0;
  119.   }
  120.   // clear output bits of shift register if noise and other waveforms
  121.   // are selected simultaneously
  122.   if (waveform > 8) {
  123.     shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2);
  124.   }
  125.  
  126.   test = test_next;
  127.   
  128.   /* update noise anyway, just in case the above paths triggered */
  129.   noise_output_cached = outputN___();
  130. }
  131.  
  132. reg8 WaveformGeneratorFP::readOSC()
  133. {
  134.   return output() >> 4;
  135. }
  136.  
  137. // ----------------------------------------------------------------------------
  138. // SID reset.
  139. // ----------------------------------------------------------------------------
  140. void WaveformGeneratorFP::reset()
  141. {
  142.   accumulator = 0;
  143.   previous = 0;
  144.   shift_register = 0x7ffffc;
  145.   freq = 0;
  146.   pw = 0;
  147.   pw_acc_scale = 0;
  148.   test = 0;
  149.   writeCONTROL_REG(0);
  150.   msb_rising = false;
  151. }
  152.