DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/reSID/envelope.cpp
00001 //  ---------------------------------------------------------------------------
00002 //  This file is part of reSID, a MOS6581 SID emulator engine.
00003 //  Copyright (C) 2004  Dag Lem <resid@nimrod.no>
00004 //
00005 //  This program is free software; you can redistribute it and/or modify
00006 //  it under the terms of the GNU General Public License as published by
00007 //  the Free Software Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //
00010 //  This program is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License along
00016 //  with this program; if not, write to the Free Software Foundation, Inc.,
00017 //  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 //  ---------------------------------------------------------------------------
00019 
00020 #define __ENVELOPE_CC__
00021 
00022 #include "envelope.h"
00023 
00024 // ----------------------------------------------------------------------------
00025 // Constructor.
00026 // ----------------------------------------------------------------------------
00027 EnvelopeGenerator::EnvelopeGenerator()
00028 {
00029   reset();
00030 }
00031 
00032 // ----------------------------------------------------------------------------
00033 // SID reset.
00034 // ----------------------------------------------------------------------------
00035 void EnvelopeGenerator::reset()
00036 {
00037   envelope_counter = 0;
00038 
00039   attack = 0;
00040   decay = 0;
00041   sustain = 0;
00042   release = 0;
00043 
00044   gate = 0;
00045 
00046   rate_counter = 0;
00047   exponential_counter = 0;
00048   exponential_counter_period = 1;
00049 
00050   state = RELEASE;
00051   rate_period = rate_counter_period[release];
00052   hold_zero = true;
00053 }
00054 
00055 
00056 // Rate counter periods are calculated from the Envelope Rates table in
00057 // the Programmer's Reference Guide. The rate counter period is the number of
00058 // cycles between each increment of the envelope counter.
00059 // The rates have been verified by sampling ENV3. 
00060 //
00061 // The rate counter is a 16 bit register which is incremented each cycle.
00062 // When the counter reaches a specific comparison value, the envelope counter
00063 // is incremented (attack) or decremented (decay/release) and the
00064 // counter is zeroed.
00065 //
00066 // NB! Sampling ENV3 shows that the calculated values are not exact.
00067 // It may seem like most calculated values have been rounded (.5 is rounded
00068 // down) and 1 has beed added to the result. A possible explanation for this
00069 // is that the SID designers have used the calculated values directly
00070 // as rate counter comparison values, not considering a one cycle delay to
00071 // zero the counter. This would yield an actual period of comparison value + 1.
00072 //
00073 // The time of the first envelope count can not be exactly controlled, except
00074 // possibly by resetting the chip. Because of this we cannot do cycle exact
00075 // sampling and must devise another method to calculate the rate counter
00076 // periods.
00077 //
00078 // The exact rate counter periods can be determined e.g. by counting the number
00079 // of cycles from envelope level 1 to envelope level 129, and dividing the
00080 // number of cycles by 128. CIA1 timer A and B in linked mode can perform
00081 // the cycle count. This is the method used to find the rates below.
00082 //
00083 // To avoid the ADSR delay bug, sampling of ENV3 should be done using
00084 // sustain = release = 0. This ensures that the attack state will not lower
00085 // the current rate counter period.
00086 //
00087 // The ENV3 sampling code below yields a maximum timing error of 14 cycles.
00088 //     lda #$01
00089 // l1: cmp $d41c
00090 //     bne l1
00091 //     ...
00092 //     lda #$ff
00093 // l2: cmp $d41c
00094 //     bne l2
00095 //
00096 // This yields a maximum error for the calculated rate period of 14/128 cycles.
00097 // The described method is thus sufficient for exact calculation of the rate
00098 // periods.
00099 //
00100 reg16 EnvelopeGenerator::rate_counter_period[] = {
00101       9,  //   2ms*1.0MHz/256 =     7.81
00102      32,  //   8ms*1.0MHz/256 =    31.25
00103      63,  //  16ms*1.0MHz/256 =    62.50
00104      95,  //  24ms*1.0MHz/256 =    93.75
00105     149,  //  38ms*1.0MHz/256 =   148.44
00106     220,  //  56ms*1.0MHz/256 =   218.75
00107     267,  //  68ms*1.0MHz/256 =   265.63
00108     313,  //  80ms*1.0MHz/256 =   312.50
00109     392,  // 100ms*1.0MHz/256 =   390.63
00110     977,  // 250ms*1.0MHz/256 =   976.56
00111    1954,  // 500ms*1.0MHz/256 =  1953.13
00112    3126,  // 800ms*1.0MHz/256 =  3125.00
00113    3907,  //   1 s*1.0MHz/256 =  3906.25
00114   11720,  //   3 s*1.0MHz/256 = 11718.75
00115   19532,  //   5 s*1.0MHz/256 = 19531.25
00116   31251   //   8 s*1.0MHz/256 = 31250.00
00117 };
00118 
00119 
00120 // For decay and release, the clock to the envelope counter is sequentially
00121 // divided by 1, 2, 4, 8, 16, 30, 1 to create a piece-wise linear approximation
00122 // of an exponential. The exponential counter period is loaded at the envelope
00123 // counter values 255, 93, 54, 26, 14, 6, 0. The period can be different for the
00124 // same envelope counter value, depending on whether the envelope has been
00125 // rising (attack -> release) or sinking (decay/release).
00126 //
00127 // Since it is not possible to reset the rate counter (the test bit has no
00128 // influence on the envelope generator whatsoever) a method must be devised to
00129 // do cycle exact sampling of ENV3 to do the investigation. This is possible
00130 // with knowledge of the rate period for A=0, found above.
00131 //
00132 // The CPU can be synchronized with ENV3 by first synchronizing with the rate
00133 // counter by setting A=0 and wait in a carefully timed loop for the envelope
00134 // counter _not_ to change for 9 cycles. We can then wait for a specific value
00135 // of ENV3 with another timed loop to fully synchronize with ENV3.
00136 //
00137 // At the first period when an exponential counter period larger than one
00138 // is used (decay or relase), one extra cycle is spent before the envelope is
00139 // decremented. The envelope output is then delayed one cycle until the state
00140 // is changed to attack. Now one cycle less will be spent before the envelope
00141 // is incremented, and the situation is normalized.
00142 // The delay is probably caused by the comparison with the exponential counter,
00143 // and does not seem to affect the rate counter. This has been verified by
00144 // timing 256 consecutive complete envelopes with A = D = R = 1, S = 0, using
00145 // CIA1 timer A and B in linked mode. If the rate counter is not affected the
00146 // period of each complete envelope is
00147 // (255 + 162*1 + 39*2 + 28*4 + 12*8 + 8*16 + 6*30)*32 = 756*32 = 32352
00148 // which corresponds exactly to the timed value divided by the number of
00149 // complete envelopes.
00150 // NB! This one cycle delay is not modeled.
00151 
00152 
00153 // From the sustain levels it follows that both the low and high 4 bits of the
00154 // envelope counter are compared to the 4-bit sustain value.
00155 // This has been verified by sampling ENV3.
00156 //
00157 reg8 EnvelopeGenerator::sustain_level[] = {
00158   0x00,
00159   0x11,
00160   0x22,
00161   0x33,
00162   0x44,
00163   0x55,
00164   0x66,
00165   0x77,
00166   0x88,
00167   0x99,
00168   0xaa,
00169   0xbb,
00170   0xcc,
00171   0xdd,
00172   0xee,
00173   0xff,
00174 };
00175 
00176 
00177 // ----------------------------------------------------------------------------
00178 // Register functions.
00179 // ----------------------------------------------------------------------------
00180 void EnvelopeGenerator::writeCONTROL_REG(reg8 control)
00181 {
00182   reg8 gate_next = control & 0x01;
00183 
00184   // The rate counter is never reset, thus there will be a delay before the
00185   // envelope counter starts counting up (attack) or down (release).
00186 
00187   // Gate bit on: Start attack, decay, sustain.
00188   if (!gate && gate_next) {
00189     state = ATTACK;
00190     rate_period = rate_counter_period[attack];
00191 
00192     // Switching to attack state unlocks the zero freeze.
00193     hold_zero = false;
00194   }
00195   // Gate bit off: Start release.
00196   else if (gate && !gate_next) {
00197     state = RELEASE;
00198     rate_period = rate_counter_period[release];
00199   }
00200 
00201   gate = gate_next;
00202 }
00203 
00204 void EnvelopeGenerator::writeATTACK_DECAY(reg8 attack_decay)
00205 {
00206   attack = (attack_decay >> 4) & 0x0f;
00207   decay = attack_decay & 0x0f;
00208   if (state == ATTACK) {
00209     rate_period = rate_counter_period[attack];
00210   }
00211   else if (state == DECAY_SUSTAIN) {
00212     rate_period = rate_counter_period[decay];
00213   }
00214 }
00215 
00216 void EnvelopeGenerator::writeSUSTAIN_RELEASE(reg8 sustain_release)
00217 {
00218   sustain = (sustain_release >> 4) & 0x0f;
00219   release = sustain_release & 0x0f;
00220   if (state == RELEASE) {
00221     rate_period = rate_counter_period[release];
00222   }
00223 }
00224 
00225 reg8 EnvelopeGenerator::readENV()
00226 {
00227   return output();
00228 }
00229