DOSBox-X
|
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