home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / resid-fp / envelope.cpp < prev    next >
C/C++ Source or Header  |  2009-01-03  |  10KB  |  255 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 __ENVELOPE_CC__
  21. #include "envelope.h"
  22.  
  23. // ----------------------------------------------------------------------------
  24. // Constructor.
  25. // ----------------------------------------------------------------------------
  26. EnvelopeGeneratorFP::EnvelopeGeneratorFP()
  27. {
  28.   reset();
  29. }
  30.  
  31. // ----------------------------------------------------------------------------
  32. // SID reset.
  33. // ----------------------------------------------------------------------------
  34. void EnvelopeGeneratorFP::reset()
  35. {
  36.   envelope_counter = 0;
  37.  
  38.   attack = 0;
  39.   decay = 0;
  40.   sustain = 0;
  41.   release = 0;
  42.  
  43.   gate = 0;
  44.  
  45.   rate_counter = 0;
  46.   exponential_counter = 0;
  47.   exponential_counter_period = 1;
  48.  
  49.   state = RELEASE;
  50.   rate_period = rate_counter_period[release];
  51.   hold_zero = true;
  52. }
  53.  
  54.  
  55. // Rate counter periods are calculated from the Envelope Rates table in
  56. // the Programmer's Reference Guide. The rate counter period is the number of
  57. // cycles between each increment of the envelope counter.
  58. // The rates have been verified by sampling ENV3. 
  59. //
  60. // The rate counter is a 16 bit register which is incremented each cycle.
  61. // When the counter reaches a specific comparison value, the envelope counter
  62. // is incremented (attack) or decremented (decay/release) and the
  63. // counter is zeroed.
  64. //
  65. // NB! Sampling ENV3 shows that the calculated values are not exact.
  66. // It may seem like most calculated values have been rounded (.5 is rounded
  67. // down) and 1 has beed added to the result. A possible explanation for this
  68. // is that the SID designers have used the calculated values directly
  69. // as rate counter comparison values, not considering a one cycle delay to
  70. // zero the counter. This would yield an actual period of comparison value + 1.
  71. //
  72. // The time of the first envelope count can not be exactly controlled, except
  73. // possibly by resetting the chip. Because of this we cannot do cycle exact
  74. // sampling and must devise another method to calculate the rate counter
  75. // periods.
  76. //
  77. // The exact rate counter periods can be determined e.g. by counting the number
  78. // of cycles from envelope level 1 to envelope level 129, and dividing the
  79. // number of cycles by 128. CIA1 timer A and B in linked mode can perform
  80. // the cycle count. This is the method used to find the rates below.
  81. //
  82. // To avoid the ADSR delay bug, sampling of ENV3 should be done using
  83. // sustain = release = 0. This ensures that the attack state will not lower
  84. // the current rate counter period.
  85. //
  86. // The ENV3 sampling code below yields a maximum timing error of 14 cycles.
  87. //     lda #$01
  88. // l1: cmp $d41c
  89. //     bne l1
  90. //     ...
  91. //     lda #$ff
  92. // l2: cmp $d41c
  93. //     bne l2
  94. //
  95. // This yields a maximum error for the calculated rate period of 14/128 cycles.
  96. // The described method is thus sufficient for exact calculation of the rate
  97. // periods.
  98. //
  99. reg16 EnvelopeGeneratorFP::rate_counter_period[] = {
  100.       9,  //   2ms*1.0MHz/256 =     7.81
  101.      32,  //   8ms*1.0MHz/256 =    31.25
  102.      63,  //  16ms*1.0MHz/256 =    62.50
  103.      95,  //  24ms*1.0MHz/256 =    93.75
  104.     149,  //  38ms*1.0MHz/256 =   148.44
  105.     220,  //  56ms*1.0MHz/256 =   218.75
  106.     267,  //  68ms*1.0MHz/256 =   265.63
  107.     313,  //  80ms*1.0MHz/256 =   312.50
  108.     392,  // 100ms*1.0MHz/256 =   390.63
  109.     977,  // 250ms*1.0MHz/256 =   976.56
  110.    1954,  // 500ms*1.0MHz/256 =  1953.13
  111.    3126,  // 800ms*1.0MHz/256 =  3125.00
  112.    3907,  //   1 s*1.0MHz/256 =  3906.25
  113.   11720,  //   3 s*1.0MHz/256 = 11718.75
  114.   19532,  //   5 s*1.0MHz/256 = 19531.25
  115.   31251   //   8 s*1.0MHz/256 = 31250.00
  116. };
  117.  
  118.  
  119. // For decay and release, the clock to the envelope counter is sequentially
  120. // divided by 1, 2, 4, 8, 16, 30, 1 to create a piece-wise linear approximation
  121. // of an exponential. The exponential counter period is loaded at the envelope
  122. // counter values 255, 93, 54, 26, 14, 6, 0. The period can be different for the
  123. // same envelope counter value, depending on whether the envelope has been
  124. // rising (attack -> release) or sinking (decay/release).
  125. //
  126. // Since it is not possible to reset the rate counter (the test bit has no
  127. // influence on the envelope generator whatsoever) a method must be devised to
  128. // do cycle exact sampling of ENV3 to do the investigation. This is possible
  129. // with knowledge of the rate period for A=0, found above.
  130. //
  131. // The CPU can be synchronized with ENV3 by first synchronizing with the rate
  132. // counter by setting A=0 and wait in a carefully timed loop for the envelope
  133. // counter _not_ to change for 9 cycles. We can then wait for a specific value
  134. // of ENV3 with another timed loop to fully synchronize with ENV3.
  135. //
  136. // At the first period when an exponential counter period larger than one
  137. // is used (decay or relase), one extra cycle is spent before the envelope is
  138. // decremented. The envelope output is then delayed one cycle until the state
  139. // is changed to attack. Now one cycle less will be spent before the envelope
  140. // is incremented, and the situation is normalized.
  141. // The delay is probably caused by the comparison with the exponential counter,
  142. // and does not seem to affect the rate counter. This has been verified by
  143. // timing 256 consecutive complete envelopes with A = D = R = 1, S = 0, using
  144. // CIA1 timer A and B in linked mode. If the rate counter is not affected the
  145. // period of each complete envelope is
  146. // (255 + 162*1 + 39*2 + 28*4 + 12*8 + 8*16 + 6*30)*32 = 756*32 = 32352
  147. // which corresponds exactly to the timed value divided by the number of
  148. // complete envelopes.
  149. // NB! This one cycle delay is not modeled.
  150.  
  151.  
  152. // From the sustain levels it follows that both the low and high 4 bits of the
  153. // envelope counter are compared to the 4-bit sustain value.
  154. // This has been verified by sampling ENV3.
  155. //
  156. reg8 EnvelopeGeneratorFP::sustain_level[] = {
  157.   0x00,
  158.   0x11,
  159.   0x22,
  160.   0x33,
  161.   0x44,
  162.   0x55,
  163.   0x66,
  164.   0x77,
  165.   0x88,
  166.   0x99,
  167.   0xaa,
  168.   0xbb,
  169.   0xcc,
  170.   0xdd,
  171.   0xee,
  172.   0xff,
  173. };
  174.  
  175.  
  176. // ----------------------------------------------------------------------------
  177. // Register functions.
  178. // ----------------------------------------------------------------------------
  179. void EnvelopeGeneratorFP::writeCONTROL_REG(reg8 control)
  180. {
  181.   reg8 gate_next = control & 0x01;
  182.  
  183.   // The rate counter is never reset, thus there will be a delay before the
  184.   // envelope counter starts counting up (attack) or down (release).
  185.  
  186.   // Gate bit on: Start attack, decay, sustain.
  187.   if (!gate && gate_next) {
  188.     state = ATTACK;
  189.     update_rate_period(rate_counter_period[attack]);
  190.  
  191.     // Switching to attack state unlocks the zero freeze.
  192.     hold_zero = false;
  193.   }
  194.   // Gate bit off: Start release.
  195.   else if (gate && !gate_next) {
  196.     state = RELEASE;
  197.     update_rate_period(rate_counter_period[release]);
  198.   }
  199.  
  200.   gate = gate_next;
  201. }
  202.  
  203. void EnvelopeGeneratorFP::writeATTACK_DECAY(reg8 attack_decay)
  204. {
  205.   attack = (attack_decay >> 4) & 0x0f;
  206.   decay = attack_decay & 0x0f;
  207.   if (state == ATTACK) {
  208.     update_rate_period(rate_counter_period[attack]);
  209.   }
  210.   else if (state == DECAY_SUSTAIN) {
  211.     update_rate_period(rate_counter_period[decay]);
  212.   }
  213. }
  214.  
  215. void EnvelopeGeneratorFP::writeSUSTAIN_RELEASE(reg8 sustain_release)
  216. {
  217.   sustain = (sustain_release >> 4) & 0x0f;
  218.   release = sustain_release & 0x0f;
  219.   if (state == RELEASE) {
  220.     update_rate_period(rate_counter_period[release]);
  221.   }
  222. }
  223.  
  224. reg8 EnvelopeGeneratorFP::readENV()
  225. {
  226.   return output();
  227. }
  228.  
  229. void EnvelopeGeneratorFP::update_rate_period(reg16 newperiod)
  230. {
  231.     rate_period = newperiod;
  232.  
  233.    /* The ADSR counter is XOR shift register with 0x7fff unique values.
  234.     * If the rate_period is adjusted to a value already seen in this cycle,
  235.     * the register will wrap around. This is known as the ADSR delay bug.
  236.     *
  237.     * To simplify the hot path calculation, we simulate this through observing
  238.     * that we add the 0x7fff cycle delay by changing the rate_counter variable
  239.     * directly. This takes care of the 99 % common case. However, playroutine
  240.     * could make multiple consequtive rate_period adjustments, in which case we
  241.     * need to cancel the previous adjustment. */
  242.  
  243.     /* if the new period exeecds 0x7fff, we need to wrap */
  244.     if (rate_period - rate_counter > 0x7fff)
  245.         rate_counter += 0x7fff;
  246.  
  247.     /* simulate 0x7fff wraparound, if the period-to-be-written
  248.      * is less than the current value. */
  249.     if (rate_period <= rate_counter)
  250.         rate_counter -= 0x7fff;
  251.  
  252.     /* at this point it should be impossible for
  253.      * rate_counter >= rate_period. If it is, there is a bug... */
  254. }
  255.