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