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