DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/dbopl.cpp
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 /*
00020         DOSBox implementation of a combined Yamaha YMF262 and Yamaha YM3812 emulator.
00021         Enabling the opl3 bit will switch the emulator to stereo opl3 output instead of regular mono opl2
00022         Except for the table generation it's all integer math
00023         Can choose different types of generators, using muls and bigger tables, try different ones for slower platforms
00024         The generation was based on the MAME implementation but tried to have it use less memory and be faster in general
00025         MAME uses much bigger envelope tables and this will be the biggest cause of it sounding different at times
00026 
00027         //TODO Don't delay first operator 1 sample in opl3 mode
00028         //TODO Maybe not use class method pointers but a regular function pointers with operator as first parameter
00029         //TODO Fix panning for the Percussion channels, would any opl3 player use it and actually really change it though?
00030         //TODO Check if having the same accuracy in all frequency multipliers sounds better or not
00031 
00032         //DUNNO Keyon in 4op, switch to 2op without keyoff.
00033 */
00034 
00035 
00036 
00037 #include <math.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include "dosbox.h"
00041 #include "dbopl.h"
00042 
00043 
00044 #ifndef PI
00045 #define PI 3.14159265358979323846
00046 #endif
00047 
00048 namespace DBOPL {
00049 
00050 #define OPLRATE         ((double)(14318180.0 / 288.0))
00051 #define TREMOLO_TABLE 52
00052 
00053 //Try to use most precision for frequencies
00054 //Else try to keep different waves in synch
00055 //#define WAVE_PRECISION        1
00056 #ifndef WAVE_PRECISION
00057 //Wave bits available in the top of the 32bit range
00058 //Original adlib uses 10.10, we use 10.22
00059 #define WAVE_BITS       10
00060 #else
00061 //Need some extra bits at the top to have room for octaves and frequency multiplier
00062 //We support to 8 times lower rate
00063 //128 * 15 * 8 = 15350, 2^13.9, so need 14 bits
00064 #define WAVE_BITS       14
00065 #endif
00066 #define WAVE_SH         ( 32 - WAVE_BITS )
00067 #define WAVE_MASK       ( ( 1 << WAVE_SH ) - 1 )
00068 
00069 //Use the same accuracy as the waves
00070 #define LFO_SH ( WAVE_SH - 10 )
00071 //LFO is controlled by our tremolo 256 sample limit
00072 #define LFO_MAX ( 256 << ( LFO_SH ) )
00073 
00074 
00075 //Maximum amount of attenuation bits
00076 //Envelope goes to 511, 9 bits
00077 #if (DBOPL_WAVE == WAVE_TABLEMUL )
00078 //Uses the value directly
00079 #define ENV_BITS        ( 9 )
00080 #else
00081 //Add 3 bits here for more accuracy and would have to be shifted up either way
00082 #define ENV_BITS        ( 9 )
00083 #endif
00084 //Limits of the envelope with those bits and when the envelope goes silent
00085 #define ENV_MIN         0
00086 #define ENV_EXTRA       ( ENV_BITS - 9 )
00087 #define ENV_MAX         ( 511 << ENV_EXTRA )
00088 #define ENV_LIMIT       ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) )
00089 #define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT )
00090 
00091 //Attack/decay/release rate counter shift
00092 #define RATE_SH         24
00093 #define RATE_MASK       ( ( 1 << RATE_SH ) - 1 )
00094 //Has to fit within 16bit lookuptable
00095 #define MUL_SH          16
00096 
00097 //Check some ranges
00098 #if ENV_EXTRA > 3
00099 #error Too many envelope bits
00100 #endif
00101 
00102 
00103 //How much to substract from the base value for the final attenuation
00104 static const Bit8u KslCreateTable[16] = {
00105         //0 will always be be lower than 7 * 8
00106         64, 32, 24, 19, 
00107         16, 12, 11, 10, 
00108          8,  6,  5,  4,
00109          3,  2,  1,  0,
00110 };
00111 
00112 #define M(_X_) ((Bit8u)( (_X_) * 2))
00113 static const Bit8u FreqCreateTable[16] = {
00114         M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ),
00115         M(8  ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15)
00116 };
00117 #undef M
00118 
00119 //We're not including the highest attack rate, that gets a special value
00120 static const Bit8u AttackSamplesTable[13] = {
00121         69, 55, 46, 40,
00122         35, 29, 23, 20,
00123         19, 15, 11, 10,
00124         9
00125 };
00126 //On a real opl these values take 8 samples to reach and are based upon larger tables
00127 static const Bit8u EnvelopeIncreaseTable[13] = {
00128         4,  5,  6,  7,
00129         8, 10, 12, 14,
00130         16, 20, 24, 28,
00131         32, 
00132 };
00133 
00134 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
00135 static Bit16u ExpTable[ 256 ];
00136 #endif
00137 
00138 #if ( DBOPL_WAVE == WAVE_HANDLER )
00139 //PI table used by WAVEHANDLER
00140 static Bit16u SinTable[ 512 ];
00141 #endif
00142 
00143 #if ( DBOPL_WAVE > WAVE_HANDLER )
00144 //Layout of the waveform table in 512 entry intervals
00145 //With overlapping waves we reduce the table to half it's size
00146 
00147 //      |    |//\\|____|WAV7|//__|/\  |____|/\/\|
00148 //      |\\//|    |    |WAV7|    |  \/|    |    |
00149 //      |06  |0126|17  |7   |3   |4   |4 5 |5   |
00150 
00151 //6 is just 0 shifted and masked
00152 
00153 static Bit16s WaveTable[ 8 * 512 ];
00154 //Distance into WaveTable the wave starts
00155 static const Bit16u WaveBaseTable[8] = {
00156         0x000, 0x200, 0x200, 0x800,
00157         0xa00, 0xc00, 0x100, 0x400,
00158 
00159 };
00160 //Mask the counter with this
00161 static const Bit16u WaveMaskTable[8] = {
00162         1023, 1023, 511, 511,
00163         1023, 1023, 512, 1023,
00164 };
00165 
00166 //Where to start the counter on at keyon
00167 static const Bit16u WaveStartTable[8] = {
00168         512, 0, 0, 0,
00169         0, 512, 512, 256,
00170 };
00171 #endif
00172 
00173 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
00174 static Bit16u MulTable[ 384 ];
00175 #endif
00176 
00177 static Bit8u KslTable[ 8 * 16 ];
00178 static Bit8u TremoloTable[ TREMOLO_TABLE ];
00179 //Start of a channel behind the chip struct start
00180 static Bit16u ChanOffsetTable[32];
00181 //Start of an operator behind the chip struct start
00182 static Bit16u OpOffsetTable[64];
00183 
00184 //The lower bits are the shift of the operator vibrato value
00185 //The highest bit is right shifted to generate -1 or 0 for negation
00186 //So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0
00187 static const Bit8s VibratoTable[ 8 ] = {        
00188         1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, 
00189         1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 
00190 };
00191 
00192 //Shift strength for the ksl value determined by ksl strength
00193 static const Bit8u KslShiftTable[4] = {
00194         31,1,2,0
00195 };
00196 
00197 //Generate a table index and table shift value using input value from a selected rate
00198 static void EnvelopeSelect( Bit8u val, Bit8u& index, Bit8u& shift ) {
00199         if ( val < 13 * 4 ) {                           //Rate 0 - 12
00200                 shift = 12 - ( val >> 2 );
00201                 index = val & 3;
00202         } else if ( val < 15 * 4 ) {            //rate 13 - 14
00203                 shift = 0;
00204                 index = val - 12 * 4;
00205         } else {                                                        //rate 15 and up
00206                 shift = 0;
00207                 index = 12;
00208         }
00209 }
00210 
00211 #if ( DBOPL_WAVE == WAVE_HANDLER )
00212 /*
00213         Generate the different waveforms out of the sine/exponetial table using handlers
00214 */
00215 static /*inline*/ Bits MakeVolume( Bitu wave, Bitu volume ) {
00216         Bitu total = wave + volume;
00217         Bitu index = total & 0xff;
00218         Bitu sig = ExpTable[ index ];
00219         Bitu exp = total >> 8;
00220 #if 0
00221         //Check if we overflow the 31 shift limit
00222         if ( exp >= 32 ) {
00223                 LOG_MSG( "WTF %d %d", total, exp );
00224         }
00225 #endif
00226         return (sig >> exp);
00227 };
00228 
00229 static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) {
00230         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00231         Bitu wave = SinTable[i & 511];
00232         return (MakeVolume( wave, volume ) ^ neg) - neg;
00233 }
00234 static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) {
00235         Bit32u wave = SinTable[i & 511];
00236         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00237         return MakeVolume( wave, volume );
00238 }
00239 static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) {
00240         Bitu wave = SinTable[i & 511];
00241         return MakeVolume( wave, volume );
00242 }
00243 static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) {
00244         Bitu wave = SinTable[i & 255];
00245         wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 );
00246         return MakeVolume( wave, volume );
00247 }
00248 static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) {
00249         //Twice as fast
00250         i <<= 1;
00251         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00252         Bitu wave = SinTable[i & 511];
00253         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00254         return (MakeVolume( wave, volume ) ^ neg) - neg;
00255 }
00256 static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) {
00257         //Twice as fast
00258         i <<= 1;
00259         Bitu wave = SinTable[i & 511];
00260         wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 );
00261         return MakeVolume( wave, volume );
00262 }
00263 static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) {
00264         Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0
00265         return (MakeVolume( 0, volume ) ^ neg) - neg;
00266 }
00267 static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) {
00268         //Negative is reversed here
00269         Bits neg = (( i >> 9) & 1) - 1;
00270         Bitu wave = (i << 3);
00271         //When negative the volume also runs backwards
00272         wave = ((wave ^ neg) - neg) & 4095;
00273         return (MakeVolume( wave, volume ) ^ neg) - neg;
00274 }
00275 
00276 static const WaveHandler WaveHandlerTable[8] = {
00277         WaveForm0, WaveForm1, WaveForm2, WaveForm3,
00278         WaveForm4, WaveForm5, WaveForm6, WaveForm7
00279 };
00280 
00281 #endif
00282 
00283 /*
00284         Operator
00285 */
00286 
00287 //We zero out when rate == 0
00288 /*inline*/ void Operator::UpdateAttack( const Chip* chip ) {
00289         Bit8u rate = reg60 >> 4;
00290         if ( rate ) {
00291                 Bit8u val = (rate << 2) + ksr;
00292                 attackAdd = chip->attackRates[ val ];
00293                 rateZero &= ~(1 << ATTACK);
00294         } else {
00295                 attackAdd = 0;
00296                 rateZero |= (1 << ATTACK);
00297         }
00298 }
00299 /*inline*/ void Operator::UpdateDecay( const Chip* chip ) {
00300         Bit8u rate = reg60 & 0xf;
00301         if ( rate ) {
00302                 Bit8u val = (rate << 2) + ksr;
00303                 decayAdd = chip->linearRates[ val ];
00304                 rateZero &= ~(1 << DECAY);
00305         } else {
00306                 decayAdd = 0;
00307                 rateZero |= (1 << DECAY);
00308         }
00309 }
00310 /*inline*/ void Operator::UpdateRelease( const Chip* chip ) {
00311         Bit8u rate = reg80 & 0xf;
00312         if ( rate ) {
00313                 Bit8u val = (rate << 2) + ksr;
00314                 releaseAdd = chip->linearRates[ val ];
00315                 rateZero &= ~(1 << RELEASE);
00316                 if ( !(reg20 & MASK_SUSTAIN ) ) {
00317                         rateZero &= ~( 1 << SUSTAIN );
00318                 }       
00319         } else {
00320                 rateZero |= (1 << RELEASE);
00321                 releaseAdd = 0;
00322                 if ( !(reg20 & MASK_SUSTAIN ) ) {
00323                         rateZero |= ( 1 << SUSTAIN );
00324                 }       
00325         }
00326 }
00327 
00328 /*inline*/ void Operator::UpdateAttenuation( ) {
00329         Bit8u kslBase = (Bit8u)((chanData >> SHIFT_KSLBASE) & 0xff);
00330         Bit32u tl = reg40 & 0x3f;
00331         Bit8u kslShift = KslShiftTable[ reg40 >> 6 ];
00332         //Make sure the attenuation goes to the right bits
00333         totalLevel = (Bit32s)(tl << ( ENV_BITS - 7 ));  //Total level goes 2 bits below max
00334         totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift;
00335 }
00336 
00337 void Operator::UpdateFrequency(  ) {
00338         Bit32u freq = chanData & (( 1 << 10 ) - 1);
00339         Bit32u block = (chanData >> 10) & 0xff;
00340 #ifdef WAVE_PRECISION
00341         block = 7u - block;
00342         waveAdd = ( freq * freqMul ) >> block;
00343 #else
00344         waveAdd = ( freq << block ) * freqMul;
00345 #endif
00346         if ( reg20 & MASK_VIBRATO ) {
00347                 vibStrength = (Bit8u)(freq >> 7u);
00348 
00349 #ifdef WAVE_PRECISION
00350                 vibrato = ( (Bitu)vibStrength * freqMul ) >> block;
00351 #else
00352                 vibrato = ( (Bitu)vibStrength << block ) * freqMul;
00353 #endif
00354         } else {
00355                 vibStrength = 0;
00356                 vibrato = 0;
00357         }
00358 }
00359 
00360 void Operator::UpdateRates( const Chip* chip ) {
00361         //Mame seems to reverse this where enabling ksr actually lowers
00362         //the rate, but pdf manuals says otherwise?
00363         Bit8u newKsr = (Bit8u)((chanData >> SHIFT_KEYCODE) & 0xff);
00364         if ( !( reg20 & MASK_KSR ) ) {
00365                 newKsr >>= 2;
00366         }
00367         if ( ksr == newKsr )
00368                 return;
00369         ksr = newKsr;
00370         UpdateAttack( chip );
00371         UpdateDecay( chip );
00372         UpdateRelease( chip );
00373 }
00374 
00375 /*INLINE*/ Bit32s Operator::RateForward( Bit32u add ) {
00376         rateIndex += add;
00377         Bit32s ret = (Bit32s)(rateIndex >> RATE_SH);
00378         rateIndex = rateIndex & RATE_MASK;
00379         return ret;
00380 }
00381 
00382 template< Operator::State yes>
00383 Bits Operator::TemplateVolume(  ) {
00384         Bit32s vol = volume;
00385         Bit32s change;
00386         switch ( yes ) {
00387         case OFF:
00388                 return ENV_MAX;
00389         case ATTACK:
00390                 change = RateForward( attackAdd );
00391                 if ( !change )
00392                         return vol;
00393                 vol += ( (~vol) * change ) >> 3;
00394                 if ( vol < ENV_MIN ) {
00395                         volume = ENV_MIN;
00396                         rateIndex = 0;
00397                         SetState( DECAY );
00398                         return ENV_MIN;
00399                 }
00400                 break;
00401         case DECAY:
00402                 vol += RateForward( decayAdd );
00403                 if ( GCC_UNLIKELY(vol >= sustainLevel) ) {
00404                         //Check if we didn't overshoot max attenuation, then just go off
00405                         if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
00406                                 volume = ENV_MAX;
00407                                 SetState( OFF );
00408                                 return ENV_MAX;
00409                         }
00410                         //Continue as sustain
00411                         rateIndex = 0;
00412                         SetState( SUSTAIN );
00413                 }
00414                 break;
00415         case SUSTAIN:
00416                 if ( reg20 & MASK_SUSTAIN ) {
00417                         return vol;
00418                 }
00419                 //In sustain phase, but not sustaining, do regular release
00420         case RELEASE: 
00421                 vol += RateForward( releaseAdd );
00422                 if ( GCC_UNLIKELY(vol >= ENV_MAX) ) {
00423                         volume = ENV_MAX;
00424                         SetState( OFF );
00425                         return ENV_MAX;
00426                 }
00427                 break;
00428         }
00429         volume = vol;
00430         return vol;
00431 }
00432 
00433 static const VolumeHandler VolumeHandlerTable[5] = {
00434         &Operator::TemplateVolume< Operator::OFF >,
00435         &Operator::TemplateVolume< Operator::RELEASE >,
00436         &Operator::TemplateVolume< Operator::SUSTAIN >,
00437         &Operator::TemplateVolume< Operator::DECAY >,
00438         &Operator::TemplateVolume< Operator::ATTACK >
00439 };
00440 
00441 /*INLINE*/ Bitu Operator::ForwardVolume() {
00442         return (Bitu)(currentLevel + (this->*volHandler)());
00443 }
00444 
00445 
00446 /*INLINE*/ Bitu Operator::ForwardWave() {
00447         waveIndex += waveCurrent;       
00448         return waveIndex >> WAVE_SH;
00449 }
00450 
00451 void Operator::Write20( const Chip* chip, Bit8u val ) {
00452         Bit8u change = (reg20 ^ val );
00453         if ( !change ) 
00454                 return;
00455         reg20 = val;
00456         //Shift the tremolo bit over the entire register, saved a branch, YES!
00457         tremoloMask = (Bit8s)(val) >> 7;
00458         tremoloMask &= ~(( 1 << ENV_EXTRA ) -1);
00459         //Update specific features based on changes
00460         if ( change & MASK_KSR ) {
00461                 UpdateRates( chip );
00462         }
00463         //With sustain enable the volume doesn't change
00464         if ( reg20 & MASK_SUSTAIN || ( !releaseAdd ) ) {
00465                 rateZero |= ( 1 << SUSTAIN );
00466         } else {
00467                 rateZero &= ~( 1 << SUSTAIN );
00468         }
00469         //Frequency multiplier or vibrato changed
00470         if ( change & (0xf | MASK_VIBRATO) ) {
00471                 freqMul = chip->freqMul[ val & 0xf ];
00472                 UpdateFrequency();
00473         }
00474 }
00475 
00476 void Operator::Write40( const Chip* /*chip*/, Bit8u val ) {
00477         if (!(reg40 ^ val )) 
00478                 return;
00479         reg40 = val;
00480         UpdateAttenuation( );
00481 }
00482 
00483 void Operator::Write60( const Chip* chip, Bit8u val ) {
00484         Bit8u change = reg60 ^ val;
00485         reg60 = val;
00486         if ( change & 0x0f ) {
00487                 UpdateDecay( chip );
00488         }
00489         if ( change & 0xf0 ) {
00490                 UpdateAttack( chip );
00491         }
00492 }
00493 
00494 void Operator::Write80( const Chip* chip, Bit8u val ) {
00495         Bit8u change = (reg80 ^ val );
00496         if ( !change ) 
00497                 return;
00498         reg80 = val;
00499         Bit8u sustain = val >> 4;
00500         //Turn 0xf into 0x1f
00501         sustain |= ( sustain + 1) & 0x10;
00502         sustainLevel = sustain << ( ENV_BITS - 5 );
00503         if ( change & 0x0f ) {
00504                 UpdateRelease( chip );
00505         }
00506 }
00507 
00508 void Operator::WriteE0( const Chip* chip, Bit8u val ) {
00509         if ( !(regE0 ^ val) ) 
00510                 return;
00511         //in opl3 mode you can always selet 7 waveforms regardless of waveformselect
00512         Bit8u waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) );
00513         regE0 = val;
00514 #if ( DBOPL_WAVE == WAVE_HANDLER )
00515         waveHandler = WaveHandlerTable[ waveForm ];
00516 #else
00517         waveBase = WaveTable + WaveBaseTable[ waveForm ];
00518         waveStart = (Bitu)WaveStartTable[ waveForm ] << WAVE_SH;
00519         waveMask = WaveMaskTable[ waveForm ];
00520 #endif
00521 }
00522 
00523 /*INLINE*/ void Operator::SetState( Bit8u s ) {
00524         state = s;
00525         volHandler = VolumeHandlerTable[ s ];
00526 }
00527 
00528 /*INLINE*/ bool Operator::Silent() const {
00529         if ( !ENV_SILENT( totalLevel + volume ) )
00530                 return false;
00531         if ( !(rateZero & ( 1 << state ) ) )
00532                 return false;
00533         return true;
00534 }
00535 
00536 /*INLINE*/ void Operator::Prepare( const Chip* chip )  {
00537         currentLevel = (Bit32u)(totalLevel + (Bit32s)(chip->tremoloValue & tremoloMask));
00538         waveCurrent = waveAdd;
00539         if ( vibStrength >> chip->vibratoShift ) {
00540                 Bit32s add = (Bit32s)(vibrato >> chip->vibratoShift);
00541                 //Sign extend over the shift value
00542                 Bit32s neg = chip->vibratoSign;
00543                 //Negate the add with -1 or 0
00544                 add = ( add ^ neg ) - neg; 
00545                 waveCurrent += (Bitu)add;
00546         }
00547 }
00548 
00549 void Operator::KeyOn( Bit8u mask ) {
00550         if ( !keyOn ) {
00551                 //Restart the frequency generator
00552 #if ( DBOPL_WAVE > WAVE_HANDLER )
00553                 waveIndex = waveStart;
00554 #else
00555                 waveIndex = 0;
00556 #endif
00557                 rateIndex = 0;
00558                 SetState( ATTACK );
00559         }
00560         keyOn |= mask;
00561 }
00562 
00563 void Operator::KeyOff( Bit8u mask ) {
00564         keyOn &= ~mask;
00565         if ( !keyOn ) {
00566                 if ( state != OFF ) {
00567                         SetState( RELEASE );
00568                 }
00569         }
00570 }
00571 
00572 /*INLINE*/ Bits Operator::GetWave( Bitu index, Bitu vol ) {
00573 #if ( DBOPL_WAVE == WAVE_HANDLER )
00574         return waveHandler( index, vol << ( 3 - ENV_EXTRA ) );
00575 #elif ( DBOPL_WAVE == WAVE_TABLEMUL )
00576         return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH;
00577 #elif ( DBOPL_WAVE == WAVE_TABLELOG )
00578         Bit32s wave = waveBase[ index & waveMask ];
00579         Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA );
00580         Bit32s sig = ExpTable[ total & 0xff ];
00581         Bit32u exp = total >> 8;
00582         Bit32s neg = wave >> 16;
00583         return ((sig ^ neg) - neg) >> exp;
00584 #else
00585 #error "No valid wave routine"
00586 #endif
00587 }
00588 
00589 Bits /*INLINE*/ Operator::GetSample( Bits modulation ) {
00590         Bitu vol = ForwardVolume();
00591         if ( ENV_SILENT( vol ) ) {
00592                 //Simply forward the wave
00593                 waveIndex += waveCurrent;
00594                 return 0;
00595         } else {
00596                 Bitu index = ForwardWave();
00597                 index += (unsigned long)modulation;
00598                 return GetWave( index, vol );
00599         }
00600 }
00601 
00602 Operator::Operator() {
00603         chanData = 0;
00604         freqMul = 0;
00605         waveIndex = 0;
00606         waveAdd = 0;
00607         waveCurrent = 0;
00608         keyOn = 0;
00609         ksr = 0;
00610         reg20 = 0;
00611         reg40 = 0;
00612         reg60 = 0;
00613         reg80 = 0;
00614         regE0 = 0;
00615     waveBase = 0;
00616     waveMask = 0;
00617     waveStart = 0;
00618     vibrato = 0;
00619     attackAdd = 0;
00620     decayAdd = 0;
00621     rateIndex = 0;
00622     tremoloMask = 0;
00623     vibStrength = 0;
00624         SetState( OFF );
00625         rateZero = (1 << OFF);
00626         sustainLevel = ENV_MAX;
00627         currentLevel = ENV_MAX;
00628         totalLevel = ENV_MAX;
00629         volume = ENV_MAX;
00630         releaseAdd = 0;
00631 }
00632 
00633 /*
00634         Channel
00635 */
00636 
00637 Channel::Channel() {
00638         old[0] = old[1] = 0;
00639         chanData = 0;
00640         regB0 = 0;
00641         regC0 = 0;
00642         maskLeft = -1;
00643         maskRight = -1;
00644         feedback = 31;
00645         fourMask = 0;
00646         synthHandler = &Channel::BlockTemplate< sm2FM >;
00647 }
00648 
00649 void Channel::SetChanData( const Chip* chip, Bit32u data ) {
00650         Bit32u change = chanData ^ data;
00651         chanData = data;
00652         Op( 0 )->chanData = data;
00653         Op( 1 )->chanData = data;
00654         //Since a frequency update triggered this, always update frequency
00655         Op( 0 )->UpdateFrequency();
00656         Op( 1 )->UpdateFrequency();
00657         if ( change & ( 0xffu << SHIFT_KSLBASE ) ) {
00658                 Op( 0 )->UpdateAttenuation();
00659                 Op( 1 )->UpdateAttenuation();
00660         }
00661         if ( change & ( 0xffu << SHIFT_KEYCODE ) ) {
00662                 Op( 0 )->UpdateRates( chip );
00663                 Op( 1 )->UpdateRates( chip );
00664         }
00665 }
00666 
00667 void Channel::UpdateFrequency( const Chip* chip, Bit8u fourOp ) {
00668         //Extrace the frequency bits
00669         Bit32u data = chanData & 0xffff;
00670         Bit32u kslBase = KslTable[ data >> 6 ];
00671         Bit32u keyCode = ( data & 0x1c00) >> 9;
00672         if ( chip->reg08 & 0x40 ) {
00673                 keyCode |= ( data & 0x100)>>8;  /* notesel == 1 */
00674         } else {
00675                 keyCode |= ( data & 0x200)>>9;  /* notesel == 0 */
00676         }
00677         //Add the keycode and ksl into the highest bits of chanData
00678         data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE );
00679         ( this + 0 )->SetChanData( chip, data );
00680         if ( fourOp & 0x3f ) {
00681                 ( this + 1 )->SetChanData( chip, data );
00682         }
00683 }
00684 
00685 void Channel::WriteA0( const Chip* chip, Bit8u val ) {
00686         Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
00687         //Don't handle writes to silent fourop channels
00688         if ( fourOp > 0x80 )
00689                 return;
00690         Bit32u change = (chanData ^ val ) & 0xff;
00691         if ( change ) {
00692                 chanData ^= change;
00693                 UpdateFrequency( chip, fourOp );
00694         }
00695 }
00696 
00697 void Channel::WriteB0( const Chip* chip, Bit8u val ) {
00698         Bit8u fourOp = chip->reg104 & chip->opl3Active & fourMask;
00699         //Don't handle writes to silent fourop channels
00700         if ( fourOp > 0x80 )
00701                 return;
00702         Bitu change = (chanData ^ ( (unsigned int)val << 8u ) ) & 0x1f00u;
00703         if ( change ) {
00704                 chanData ^= change;
00705                 UpdateFrequency( chip, fourOp );
00706         }
00707         //Check for a change in the keyon/off state
00708         if ( !(( val ^ regB0) & 0x20))
00709                 return;
00710         regB0 = val;
00711         if ( val & 0x20 ) {
00712                 Op(0)->KeyOn( 0x1 );
00713                 Op(1)->KeyOn( 0x1 );
00714                 if ( fourOp & 0x3f ) {
00715                         ( this + 1 )->Op(0)->KeyOn( 1 );
00716                         ( this + 1 )->Op(1)->KeyOn( 1 );
00717                 }
00718         } else {
00719                 Op(0)->KeyOff( 0x1 );
00720                 Op(1)->KeyOff( 0x1 );
00721                 if ( fourOp & 0x3f ) {
00722                         ( this + 1 )->Op(0)->KeyOff( 1 );
00723                         ( this + 1 )->Op(1)->KeyOff( 1 );
00724                 }
00725         }
00726 }
00727 
00728 void Channel::WriteC0(const Chip* chip, Bit8u val) {
00729         Bit8u change = val ^ regC0;
00730         if (!change)
00731                 return;
00732         regC0 = val;
00733         feedback = (regC0 >> 1) & 7;
00734         if (feedback) {
00735                 //We shift the input to the right 10 bit wave index value
00736                 feedback = 9 - feedback;
00737         }
00738         else {
00739                 feedback = 31;
00740         }
00741         UpdateSynth(chip);
00742 }
00743 
00744 void Channel::UpdateSynth( const Chip* chip ) {
00745         //Select the new synth mode
00746         if ( chip->opl3Active ) {
00747                 //4-op mode enabled for this channel
00748                 if ( (chip->reg104 & fourMask) & 0x3f ) {
00749                         Channel* chan0, *chan1;
00750                         //Check if it's the 2nd channel in a 4-op
00751                         if ( !(fourMask & 0x80 ) ) {
00752                                 chan0 = this;
00753                                 chan1 = this + 1;
00754                         } else {
00755                                 chan0 = this - 1;
00756                                 chan1 = this;
00757                         }
00758 
00759                         Bit8u synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 );
00760                         switch ( synth ) {
00761                         case 0:
00762                                 chan0->synthHandler = &Channel::BlockTemplate< sm3FMFM >;
00763                                 break;
00764                         case 1:
00765                                 chan0->synthHandler = &Channel::BlockTemplate< sm3AMFM >;
00766                                 break;
00767                         case 2:
00768                                 chan0->synthHandler = &Channel::BlockTemplate< sm3FMAM >;
00769                                 break;
00770                         case 3:
00771                                 chan0->synthHandler = &Channel::BlockTemplate< sm3AMAM >;
00772                                 break;
00773                         }
00774                 //Disable updating percussion channels
00775                 } else if ((fourMask & 0x40) && ( chip->regBD & 0x20) ) {
00776 
00777                 //Regular dual op, am or fm
00778                 } else if (regC0 & 1 ) {
00779                         synthHandler = &Channel::BlockTemplate< sm3AM >;
00780                 } else {
00781                         synthHandler = &Channel::BlockTemplate< sm3FM >;
00782                 }
00783                 maskLeft = (regC0 & 0x10 ) ? -1 : 0;
00784                 maskRight = (regC0 & 0x20 ) ? -1 : 0;
00785         //opl2 active
00786         } else { 
00787                 //Disable updating percussion channels
00788                 if ( (fourMask & 0x40) && ( chip->regBD & 0x20 ) ) {
00789 
00790                 //Regular dual op, am or fm
00791                 } else if (regC0 & 1 ) {
00792                         synthHandler = &Channel::BlockTemplate< sm2AM >;
00793                 } else {
00794                         synthHandler = &Channel::BlockTemplate< sm2FM >;
00795                 }
00796         }
00797 }
00798 
00799 template< bool opl3Mode>
00800 /*INLINE*/ void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
00801         Channel* chan = this;
00802 
00803         //BassDrum
00804         Bit32s mod = (Bit32s)((Bit32u)(old[0] + old[1]) >> feedback);
00805         old[0] = old[1];
00806         old[1] = (Bit32s)Op(0)->GetSample( mod );
00807 
00808         //When bassdrum is in AM mode first operator is ignoed
00809         if ( chan->regC0 & 1 ) {
00810                 mod = 0;
00811         } else {
00812                 mod = old[0];
00813         }
00814         Bit32s sample = (Bit32s)Op(1)->GetSample( mod );
00815 
00816 
00817         //Precalculate stuff used by other outputs
00818         Bit32u noiseBit = chip->ForwardNoise() & 0x1;
00819         Bit32u c2 = (Bit32u)Op(2)->ForwardWave();
00820         Bit32u c5 = (Bit32u)Op(5)->ForwardWave();
00821         Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
00822 
00823         //Hi-Hat
00824         Bit32u hhVol = (Bit32u)Op(2)->ForwardVolume();
00825         if ( !ENV_SILENT( hhVol ) ) {
00826                 Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 )));
00827                 sample += (Bit32s)Op(2)->GetWave( hhIndex, hhVol );
00828         }
00829         //Snare Drum
00830         Bit32u sdVol = (Bit32u)Op(3)->ForwardVolume();
00831         if ( !ENV_SILENT( sdVol ) ) {
00832                 Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 );
00833                 sample += (Bit32s)Op(3)->GetWave( sdIndex, sdVol );
00834         }
00835         //Tom-tom
00836         sample += (Bit32s)Op(4)->GetSample( 0 );
00837 
00838         //Top-Cymbal
00839         Bit32u tcVol = (Bit32u)Op(5)->ForwardVolume();
00840         if ( !ENV_SILENT( tcVol ) ) {
00841                 Bit32u tcIndex = (1 + phaseBit) << 8;
00842                 sample += (Bit32s)Op(5)->GetWave( tcIndex, tcVol );
00843         }
00844         sample <<= 1;
00845         if ( opl3Mode ) {
00846                 output[0] += sample;
00847                 output[1] += sample;
00848         } else {
00849                 output[0] += sample;
00850         }
00851 }
00852 
00853 template<SynthMode mode>
00854 Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) {
00855         switch( mode ) {
00856         case sm2AM:
00857         case sm3AM:
00858                 if ( Op(0)->Silent() && Op(1)->Silent() ) {
00859                         old[0] = old[1] = 0;
00860                         return (this + 1);
00861                 }
00862                 break;
00863         case sm2FM:
00864         case sm3FM:
00865                 if ( Op(1)->Silent() ) {
00866                         old[0] = old[1] = 0;
00867                         return (this + 1);
00868                 }
00869                 break;
00870         case sm3FMFM:
00871                 if ( Op(3)->Silent() ) {
00872                         old[0] = old[1] = 0;
00873                         return (this + 2);
00874                 }
00875                 break;
00876         case sm3AMFM:
00877                 if ( Op(0)->Silent() && Op(3)->Silent() ) {
00878                         old[0] = old[1] = 0;
00879                         return (this + 2);
00880                 }
00881                 break;
00882         case sm3FMAM:
00883                 if ( Op(1)->Silent() && Op(3)->Silent() ) {
00884                         old[0] = old[1] = 0;
00885                         return (this + 2);
00886                 }
00887                 break;
00888         case sm3AMAM:
00889                 if ( Op(0)->Silent() && Op(2)->Silent() && Op(3)->Silent() ) {
00890                         old[0] = old[1] = 0;
00891                         return (this + 2);
00892                 }
00893                 break;
00894         default:
00895                 break;
00896         }
00897         //Init the operators with the the current vibrato and tremolo values
00898         Op( 0 )->Prepare( chip );
00899         Op( 1 )->Prepare( chip );
00900         if ( mode > sm4Start ) {
00901                 Op( 2 )->Prepare( chip );
00902                 Op( 3 )->Prepare( chip );
00903         }
00904         if ( mode > sm6Start ) {
00905                 Op( 4 )->Prepare( chip );
00906                 Op( 5 )->Prepare( chip );
00907         }
00908         for ( Bitu i = 0; i < samples; i++ ) {
00909                 //Early out for percussion handlers
00910                 if ( mode == sm2Percussion ) {
00911                         GeneratePercussion<false>( chip, output + i );
00912                         continue;       //Prevent some unitialized value bitching
00913                 } else if ( mode == sm3Percussion ) {
00914                         GeneratePercussion<true>( chip, output + i * 2 );
00915                         continue;       //Prevent some unitialized value bitching
00916                 }
00917 
00918                 //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise
00919                 Bit32s mod = (Bit32s)((Bit32u)((old[0] + old[1])) >> feedback);
00920                 old[0] = old[1];
00921                 old[1] = (Bit32s)Op(0)->GetSample( mod );
00922                 Bit32s sample;
00923                 Bit32s out0 = old[0];
00924                 if ( mode == sm2AM || mode == sm3AM ) {
00925                         sample = (Bit32s)(out0 + Op(1)->GetSample( 0 ));
00926                 } else if ( mode == sm2FM || mode == sm3FM ) {
00927                         sample = (Bit32s)Op(1)->GetSample( out0 );
00928                 } else if ( mode == sm3FMFM ) {
00929                         Bits next = Op(1)->GetSample( out0 ); 
00930                         next = Op(2)->GetSample( next );
00931                         sample = (Bit32s)Op(3)->GetSample( next );
00932                 } else if ( mode == sm3AMFM ) {
00933                         sample = out0;
00934                         Bits next = Op(1)->GetSample( 0 ); 
00935                         next = Op(2)->GetSample( next );
00936                         sample += (Bit32s)Op(3)->GetSample( next );
00937                 } else if ( mode == sm3FMAM ) {
00938                         sample = (Bit32s)Op(1)->GetSample( out0 );
00939                         Bits next = Op(2)->GetSample( 0 );
00940                         sample += (Bit32s)Op(3)->GetSample( next );
00941                 } else if ( mode == sm3AMAM ) {
00942                         sample = out0;
00943                         Bits next = Op(1)->GetSample( 0 ); 
00944                         sample += (Bit32s)Op(2)->GetSample( next );
00945                         sample += (Bit32s)Op(3)->GetSample( 0 );
00946                 }
00947                 switch( mode ) {
00948                 case sm2AM:
00949                 case sm2FM:
00950                         output[ i ] += sample;
00951                         break;
00952                 case sm3AM:
00953                 case sm3FM:
00954                 case sm3FMFM:
00955                 case sm3AMFM:
00956                 case sm3FMAM:
00957                 case sm3AMAM:
00958                         output[ i * 2 + 0 ] += sample & maskLeft;
00959                         output[ i * 2 + 1 ] += sample & maskRight;
00960                         break;
00961                 default:
00962                         break;
00963                 }
00964         }
00965         switch( mode ) {
00966         case sm2AM:
00967         case sm2FM:
00968         case sm3AM:
00969         case sm3FM:
00970                 return ( this + 1 );
00971         case sm3FMFM:
00972         case sm3AMFM:
00973         case sm3FMAM:
00974         case sm3AMAM:
00975                 return( this + 2 );
00976         case sm2Percussion:
00977         case sm3Percussion:
00978                 return( this + 3 );
00979         }
00980         return 0;
00981 }
00982 
00983 /*
00984         Chip
00985 */
00986 
00987 Chip::Chip() {
00988         reg08 = 0;
00989         reg04 = 0;
00990         regBD = 0;
00991         reg104 = 0;
00992         opl3Active = 0;
00993 }
00994 
00995 /*INLINE*/ Bit32u Chip::ForwardNoise() {
00996         noiseCounter += noiseAdd;
00997         Bitu count = noiseCounter >> LFO_SH;
00998         noiseCounter &= WAVE_MASK;
00999         for ( ; count > 0; --count ) {
01000                 //Noise calculation from mame
01001                 noiseValue ^= ( 0x800302 ) & ( 0 - (noiseValue & 1 ) );
01002                 noiseValue >>= 1;
01003         }
01004         return noiseValue;
01005 }
01006 
01007 /*INLINE*/ Bit32u Chip::ForwardLFO( Bit32u samples ) {
01008         //Current vibrato value, runs 4x slower than tremolo
01009         vibratoSign = ( VibratoTable[ vibratoIndex >> 2] ) >> 7;
01010         vibratoShift = ( VibratoTable[ vibratoIndex >> 2] & 7) + vibratoStrength; 
01011         tremoloValue = TremoloTable[ tremoloIndex ] >> tremoloStrength;
01012 
01013         //Check hom many samples there can be done before the value changes
01014         Bit32u todo = LFO_MAX - lfoCounter;
01015         Bit32u count = (todo + lfoAdd - 1) / lfoAdd;
01016         if ( count > samples ) {
01017                 count = samples;
01018                 lfoCounter += count * lfoAdd;
01019         } else {
01020                 lfoCounter += count * lfoAdd;
01021                 lfoCounter &= (LFO_MAX - 1);
01022                 //Maximum of 7 vibrato value * 4
01023                 vibratoIndex = ( vibratoIndex + 1 ) & 31;
01024                 //Clip tremolo to the the table size
01025                 if ( tremoloIndex + 1 < TREMOLO_TABLE  )
01026                         ++tremoloIndex;
01027                 else
01028                         tremoloIndex = 0;
01029         }
01030         return count;
01031 }
01032 
01033 
01034 void Chip::WriteBD( Bit8u val ) {
01035         Bit8u change = regBD ^ val;
01036         if ( !change )
01037                 return;
01038         regBD = val;
01039         //TODO could do this with shift and xor?
01040         vibratoStrength = (val & 0x40) ? 0x00 : 0x01;
01041         tremoloStrength = (val & 0x80) ? 0x00 : 0x02;
01042         if ( val & 0x20 ) {
01043                 //Drum was just enabled, make sure channel 6 has the right synth
01044                 if ( change & 0x20 ) {
01045                         if ( opl3Active ) {
01046                                 chan[6].synthHandler = &Channel::BlockTemplate< sm3Percussion >; 
01047                         } else {
01048                                 chan[6].synthHandler = &Channel::BlockTemplate< sm2Percussion >; 
01049                         }
01050                 }
01051                 //Bass Drum
01052                 if ( val & 0x10 ) {
01053                         chan[6].op[0].KeyOn( 0x2 );
01054                         chan[6].op[1].KeyOn( 0x2 );
01055                 } else {
01056                         chan[6].op[0].KeyOff( 0x2 );
01057                         chan[6].op[1].KeyOff( 0x2 );
01058                 }
01059                 //Hi-Hat
01060                 if ( val & 0x1 ) {
01061                         chan[7].op[0].KeyOn( 0x2 );
01062                 } else {
01063                         chan[7].op[0].KeyOff( 0x2 );
01064                 }
01065                 //Snare
01066                 if ( val & 0x8 ) {
01067                         chan[7].op[1].KeyOn( 0x2 );
01068                 } else {
01069                         chan[7].op[1].KeyOff( 0x2 );
01070                 }
01071                 //Tom-Tom
01072                 if ( val & 0x4 ) {
01073                         chan[8].op[0].KeyOn( 0x2 );
01074                 } else {
01075                         chan[8].op[0].KeyOff( 0x2 );
01076                 }
01077                 //Top Cymbal
01078                 if ( val & 0x2 ) {
01079                         chan[8].op[1].KeyOn( 0x2 );
01080                 } else {
01081                         chan[8].op[1].KeyOff( 0x2 );
01082                 }
01083         //Toggle keyoffs when we turn off the percussion
01084         } else if ( change & 0x20 ) {
01085                 //Trigger a reset to setup the original synth handler
01086                 //This makes it call
01087                 chan[6].UpdateSynth( this );
01088                 chan[6].op[0].KeyOff( 0x2 );
01089                 chan[6].op[1].KeyOff( 0x2 );
01090                 chan[7].op[0].KeyOff( 0x2 );
01091                 chan[7].op[1].KeyOff( 0x2 );
01092                 chan[8].op[0].KeyOff( 0x2 );
01093                 chan[8].op[1].KeyOff( 0x2 );
01094         }
01095 }
01096 
01097 
01098 #define REGOP( _FUNC_ )                                                                                                                 \
01099         index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f );                                                                \
01100         if ( OpOffsetTable[ index ] ) {                                                                                                 \
01101                 Operator* regOp = (Operator*)( ((char *)this ) + OpOffsetTable[ index ] );      \
01102                 regOp->_FUNC_( this, val );                                                                                                     \
01103         }
01104 
01105 #define REGCHAN( _FUNC_ )                                                                                                                               \
01106         index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf );                                                                         \
01107         if ( ChanOffsetTable[ index ] ) {                                                                                                       \
01108                 Channel* regChan = (Channel*)( ((char *)this ) + ChanOffsetTable[ index ] );    \
01109                 regChan->_FUNC_( this, val );                                                                                                   \
01110         }
01111 
01112 //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers
01113 void Chip::UpdateSynths() {
01114         for (int i = 0; i < 18; i++) {
01115                 chan[i].UpdateSynth(this);
01116         }
01117 }
01118 
01119 void Chip::WriteReg( Bit32u reg, Bit8u val ) {
01120         Bitu index;
01121         switch ( (reg & 0xf0) >> 4 ) {
01122         case 0x00 >> 4:
01123                 if ( reg == 0x01 ) {
01124                         waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; 
01125                 } else if ( reg == 0x104 ) {
01126                         //Only detect changes in lowest 6 bits
01127                         if ( !((reg104 ^ val) & 0x3f) )
01128                                 return;
01129                         //Always keep the highest bit enabled, for checking > 0x80
01130                         reg104 = 0x80 | ( val & 0x3f );
01131                         //Switch synths when changing the 4op combinations
01132                         UpdateSynths();
01133                 } else if ( reg == 0x105 ) {
01134                         //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register
01135                         if ( !((opl3Active ^ val) & 1 ) )
01136                                 return;
01137                         opl3Active = ( val & 1 ) ? 0xff : 0;
01138                         //Just update the synths now that opl3 must have been enabled
01139                         //This isn't how the real card handles it but need to switch to stereo generating handlers
01140                         UpdateSynths();
01141                 } else if ( reg == 0x08 ) {
01142                         reg08 = val;
01143                 }
01144         case 0x10 >> 4:
01145                 break;
01146         case 0x20 >> 4:
01147         case 0x30 >> 4:
01148                 REGOP( Write20 );
01149                 break;
01150         case 0x40 >> 4:
01151         case 0x50 >> 4:
01152                 REGOP( Write40 );
01153                 break;
01154         case 0x60 >> 4:
01155         case 0x70 >> 4:
01156                 REGOP( Write60 );
01157                 break;
01158         case 0x80 >> 4:
01159         case 0x90 >> 4:
01160                 REGOP( Write80 );
01161                 break;
01162         case 0xa0 >> 4:
01163                 REGCHAN( WriteA0 );
01164                 break;
01165         case 0xb0 >> 4:
01166                 if ( reg == 0xbd ) {
01167                         WriteBD( val );
01168                 } else {
01169                         REGCHAN( WriteB0 );
01170                 }
01171                 break;
01172         case 0xc0 >> 4:
01173                 REGCHAN( WriteC0 );
01174         case 0xd0 >> 4:
01175                 break;
01176         case 0xe0 >> 4:
01177         case 0xf0 >> 4:
01178                 REGOP( WriteE0 );
01179                 break;
01180         }
01181 }
01182 
01183 
01184 Bit32u Chip::WriteAddr( Bit32u port, Bit8u val ) {
01185         switch ( port & 3 ) {
01186         case 0:
01187                 return val;
01188         case 2:
01189                 if ( opl3Active || (val == 0x05u) )
01190                         return 0x100u | val;
01191                 else 
01192                         return val;
01193         }
01194         return 0u;
01195 }
01196 
01197 void Chip::GenerateBlock2( Bitu total, Bit32s* output ) {
01198         while ( total > 0 ) {
01199                 Bit32u samples = ForwardLFO( (Bit32u)total );
01200                 memset(output, 0, sizeof(Bit32s) * samples);
01201 //              int count = 0;
01202                 for( Channel* ch = chan; ch < chan + 9; ) {
01203 //                      count++;
01204                         ch = (ch->*(ch->synthHandler))( this, samples, output );
01205                 }
01206                 total -= samples;
01207                 output += samples;
01208         }
01209 }
01210 
01211 void Chip::GenerateBlock3( Bitu total, Bit32s* output  ) {
01212         while ( total > 0 ) {
01213                 Bit32u samples = ForwardLFO( (Bit32u)total );
01214                 memset(output, 0, sizeof(Bit32s) * samples *2);
01215 //              int count = 0;
01216                 for( Channel* ch = chan; ch < chan + 18; ) {
01217 //                      count++;
01218                         ch = (ch->*(ch->synthHandler))( this, samples, output );
01219                 }
01220                 total -= samples;
01221                 output += samples * 2;
01222         }
01223 }
01224 
01225 void Chip::Setup( Bit32u rate ) {
01226         double original = OPLRATE;
01227 //      double original = rate;
01228         double scale = original / (double)rate;
01229 
01230         //Noise counter is run at the same precision as general waves
01231         noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
01232         noiseCounter = 0;
01233         noiseValue = 1; //Make sure it triggers the noise xor the first time
01234         //The low frequency oscillation counter
01235         //Every time his overflows vibrato and tremoloindex are increased
01236         lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) );
01237         lfoCounter = 0;
01238         vibratoIndex = 0;
01239         tremoloIndex = 0;
01240 
01241         //With higher octave this gets shifted up
01242         //-1 since the freqCreateTable = *2
01243 #ifdef WAVE_PRECISION
01244         double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10));
01245         for ( int i = 0; i < 16; i++ ) {
01246                 freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] );
01247         }
01248 #else
01249         Bit32u freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10)));
01250         for ( int i = 0; i < 16; i++ ) {
01251                 freqMul[i] = freqScale * FreqCreateTable[ i ];
01252         }
01253 #endif
01254 
01255         //-3 since the real envelope takes 8 steps to reach the single value we supply
01256         for ( Bit8u i = 0; i < 76; i++ ) {
01257                 Bit8u index, shift;
01258                 EnvelopeSelect( i, index, shift );
01259                 linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
01260         }
01261 //      Bit32s attackDiffs[62];
01262         //Generate the best matching attack rate
01263         for ( Bit8u i = 0; i < 62; i++ ) {
01264                 Bit8u index, shift;
01265                 EnvelopeSelect( i, index, shift );
01266                 //Original amount of samples the attack would take
01267                 Bit32s originalAmount = (Bit32s)((Bit32u)( (AttackSamplesTable[ index ] << shift) / scale));
01268                  
01269                 Bit32s guessAdd = (Bit32s)((Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))));
01270                 Bit32s bestAdd = guessAdd;
01271                 Bit32u bestDiff = 1 << 30;
01272                 for( Bit32u passes = 0; passes < 16; passes ++ ) {
01273                         Bit32s volume = ENV_MAX;
01274                         Bit32s samples = 0;
01275                         Bit32u count = 0;
01276                         while ( volume > 0 && samples < originalAmount * 2 ) {
01277                                 count += (Bit32u)guessAdd;
01278                                 Bit32s change = (Bit32s)(count >> RATE_SH);
01279                                 count &= RATE_MASK;
01280                                 if ( GCC_UNLIKELY(change) ) { // less than 1 % 
01281                                         volume += ( ~volume * change ) >> 3;
01282                                 }
01283                                 samples++;
01284 
01285                         }
01286                         Bit32s diff = originalAmount - samples;
01287                         Bit32u lDiff = labs( diff );
01288                         //Init last on first pass
01289                         if ( lDiff < bestDiff ) {
01290                                 bestDiff = lDiff;
01291                                 bestAdd = guessAdd;
01292                                 //We hit an exactly matching sample count
01293                                 if ( !bestDiff )
01294                                         break;
01295                         }
01296                         //Linear correction factor, not exactly perfect but seems to work
01297                         double correct = (originalAmount - diff) / (double)originalAmount;
01298                         guessAdd = (Bit32s)(guessAdd * correct);
01299                         //Below our target
01300                         if ( diff < 0 ) {
01301                                 //Always add one here for rounding, an overshoot will get corrected by another pass decreasing
01302                                 guessAdd++;
01303                         }
01304                 }
01305                 attackRates[i] = (Bit32u)bestAdd;
01306                 //Keep track of the diffs for some debugging
01307 //              attackDiffs[i] = bestDiff;
01308         }
01309         for ( Bit8u i = 62; i < 76; i++ ) {
01310                 //This should provide instant volume maximizing
01311                 attackRates[i] = 8u << RATE_SH;
01312         }
01313         //Setup the channels with the correct four op flags
01314         //Channels are accessed through a table so they appear linear here
01315         chan[ 0].fourMask = 0x00 | ( 1 << 0 );
01316         chan[ 1].fourMask = 0x80 | ( 1 << 0 );
01317         chan[ 2].fourMask = 0x00 | ( 1 << 1 );
01318         chan[ 3].fourMask = 0x80 | ( 1 << 1 );
01319         chan[ 4].fourMask = 0x00 | ( 1 << 2 );
01320         chan[ 5].fourMask = 0x80 | ( 1 << 2 );
01321 
01322         chan[ 9].fourMask = 0x00 | ( 1 << 3 );
01323         chan[10].fourMask = 0x80 | ( 1 << 3 );
01324         chan[11].fourMask = 0x00 | ( 1 << 4 );
01325         chan[12].fourMask = 0x80 | ( 1 << 4 );
01326         chan[13].fourMask = 0x00 | ( 1 << 5 );
01327         chan[14].fourMask = 0x80 | ( 1 << 5 );
01328 
01329         //mark the percussion channels
01330         chan[ 6].fourMask = 0x40;
01331         chan[ 7].fourMask = 0x40;
01332         chan[ 8].fourMask = 0x40;
01333 
01334         //Clear Everything in opl3 mode
01335         WriteReg( 0x105, 0x1 );
01336         for ( unsigned int i = 0; i < 512; i++ ) {
01337                 if ( i == 0x105 )
01338                         continue;
01339                 WriteReg( i, 0xff );
01340                 WriteReg( i, 0x0 );
01341         }
01342         WriteReg( 0x105, 0x0 );
01343         //Clear everything in opl2 mode
01344         for ( unsigned int i = 0; i < 255; i++ ) {
01345                 WriteReg( i, 0xff );
01346                 WriteReg( i, 0x0 );
01347         }
01348 }
01349 
01350 static bool doneTables = false;
01351 void InitTables( void ) {
01352         if ( doneTables )
01353                 return;
01354         doneTables = true;
01355 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
01356         //Exponential volume table, same as the real adlib
01357         for ( int i = 0; i < 256; i++ ) {
01358                 //Save them in reverse
01359                 ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 );
01360                 ExpTable[i] += 1024; //or remove the -1 oh well :)
01361                 //Preshift to the left once so the final volume can shift to the right
01362                 ExpTable[i] *= 2;
01363         }
01364 #endif
01365 #if ( DBOPL_WAVE == WAVE_HANDLER )
01366         //Add 0.5 for the trunc rounding of the integer cast
01367         //Do a PI sinetable instead of the original 0.5 PI
01368         for ( int i = 0; i < 512; i++ ) {
01369                 SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
01370         }
01371 #endif
01372 #if ( DBOPL_WAVE == WAVE_TABLEMUL )
01373         //Multiplication based tables
01374         for ( int i = 0; i < 384; i++ ) {
01375                 int s = i * 8;
01376                 //TODO maybe keep some of the precision errors of the original table?
01377                 double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
01378                 MulTable[i] = (Bit16u)(val);
01379         }
01380 
01381         //Sine Wave Base
01382         for ( int i = 0; i < 512; i++ ) {
01383                 WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084);
01384                 WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ];
01385         }
01386         //Exponential wave
01387         for ( int i = 0; i < 256; i++ ) {
01388                 WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
01389                 WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
01390         }
01391 #endif
01392 #if ( DBOPL_WAVE == WAVE_TABLELOG )
01393         //Sine Wave Base
01394         for ( int i = 0; i < 512; i++ ) {
01395                 WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 );
01396                 WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i];
01397         }
01398         //Exponential wave
01399         for ( int i = 0; i < 256; i++ ) {
01400                 WaveTable[ 0x700 + i ] = i * 8;
01401                 WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8;
01402         } 
01403 #endif
01404 
01405         //      |    |//\\|____|WAV7|//__|/\  |____|/\/\|
01406         //      |\\//|    |    |WAV7|    |  \/|    |    |
01407         //      |06  |0126|27  |7   |3   |4   |4 5 |5   |
01408 
01409 #if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL ))
01410         for ( int i = 0; i < 256; i++ ) {
01411                 //Fill silence gaps
01412                 WaveTable[ 0x400 + i ] = WaveTable[0];
01413                 WaveTable[ 0x500 + i ] = WaveTable[0];
01414                 WaveTable[ 0x900 + i ] = WaveTable[0];
01415                 WaveTable[ 0xc00 + i ] = WaveTable[0];
01416                 WaveTable[ 0xd00 + i ] = WaveTable[0];
01417                 //Replicate sines in other pieces
01418                 WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ];
01419                 //double speed sines
01420                 WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ];
01421                 WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ];
01422                 WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ];
01423                 WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ];
01424         } 
01425 #endif
01426 
01427         //Create the ksl table
01428         for ( int oct = 0; oct < 8; oct++ ) {
01429                 int base = oct * 8;
01430                 for ( int i = 0; i < 16; i++ ) {
01431                         int val = base - KslCreateTable[i];
01432                         if ( val < 0 )
01433                                 val = 0;
01434                         //*4 for the final range to match attenuation range
01435                         KslTable[ oct * 16 + i ] = val * 4;
01436                 }
01437         }
01438         //Create the Tremolo table, just increase and decrease a triangle wave
01439         for ( Bit8u i = 0; i < TREMOLO_TABLE / 2; i++ ) {
01440                 Bit8u val = i << ENV_EXTRA;
01441                 TremoloTable[i] = val;
01442                 TremoloTable[TREMOLO_TABLE - 1 - i] = val;
01443         }
01444         //Create a table with offsets of the channels from the start of the chip
01445         DBOPL::Chip* chip = 0;
01446         for ( Bitu i = 0; i < 32; i++ ) {
01447                 Bitu index = i & 0xf;
01448                 if ( index >= 9 ) {
01449                         ChanOffsetTable[i] = 0;
01450                         continue;
01451                 }
01452                 //Make sure the four op channels follow eachother
01453                 if ( index < 6 ) {
01454                         index = (index % 3) * 2 + ( index / 3 );
01455                 }
01456                 //Add back the bits for highest ones
01457                 if ( i >= 16 )
01458                         index += 9;
01459                 Bitu blah = reinterpret_cast<Bitu>( &(chip->chan[ index ]) );
01460                 ChanOffsetTable[i] = (Bit16u)blah;
01461         }
01462         //Same for operators
01463         for ( Bitu i = 0; i < 64; i++ ) {
01464                 if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) {
01465                         OpOffsetTable[i] = 0;
01466                         continue;
01467                 }
01468                 Bitu chNum = (i / 8) * 3 + (i % 8) % 3;
01469                 //Make sure we use 16 and up for the 2nd range to match the chanoffset gap
01470                 if ( chNum >= 12 )
01471                         chNum += 16 - 12;
01472                 Bitu opNum = ( i % 8 ) / 3;
01473                 DBOPL::Channel* chan = 0;
01474                 Bitu blah = reinterpret_cast<Bitu>( &(chan->op[opNum]) );
01475                 OpOffsetTable[i] = (Bit16u)(ChanOffsetTable[ chNum ] + blah);
01476         }
01477 #if 0
01478         //Stupid checks if table's are correct
01479         for ( Bitu i = 0; i < 18; i++ ) {
01480                 Bit32u find = (Bit16u)( &(chip->chan[ i ]) );
01481                 for ( Bitu c = 0; c < 32; c++ ) {
01482                         if ( ChanOffsetTable[c] == find ) {
01483                                 find = 0;
01484                                 break;
01485                         }
01486                 }
01487                 if ( find ) {
01488                         find = find;
01489                 }
01490         }
01491         for ( Bitu i = 0; i < 36; i++ ) {
01492                 Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) );
01493                 for ( Bitu c = 0; c < 64; c++ ) {
01494                         if ( OpOffsetTable[c] == find ) {
01495                                 find = 0;
01496                                 break;
01497                         }
01498                 }
01499                 if ( find ) {
01500                         find = find;
01501                 }
01502         }
01503 #endif
01504 }
01505 
01506 Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) {
01507         return chip.WriteAddr( port, val );
01508 
01509 }
01510 void Handler::WriteReg( Bit32u addr, Bit8u val ) {
01511         chip.WriteReg( addr, val );
01512 }
01513 
01514 void Handler::Generate( MixerChannel* chan, Bitu samples ) {
01515         Bit32s buffer[ 512 * 2 ];
01516         if ( GCC_UNLIKELY(samples > 512) )
01517                 samples = 512;
01518         if ( !chip.opl3Active ) {
01519                 chip.GenerateBlock2( samples, buffer );
01520                 chan->AddSamples_m32( samples, buffer );
01521         } else {
01522                 chip.GenerateBlock3( samples, buffer );
01523                 chan->AddSamples_s32( samples, buffer );
01524         }
01525 }
01526 
01527 void Handler::Init( Bitu rate ) {
01528         InitTables();
01529         chip.Setup( (Bit32u)rate );
01530 }
01531 
01532 // save state support
01533 void Handler::SaveState( std::ostream& stream )
01534 {
01535         const char pod_name[32] = "DBOPL";
01536 
01537         if( stream.fail() ) return;
01538 
01539 
01540         WRITE_POD( &pod_name, pod_name );
01541 
01542         //************************************************
01543         //************************************************
01544         //************************************************
01545 
01546         Bit8u volhandler_idx[18][2];
01547         Bit32u wavebase_idx[18][2];
01548         Bit8u synthhandler_idx[18];
01549 
01550 
01551         for( int lcv1=0; lcv1<18; lcv1++ ) {
01552                 for( int lcv2=0; lcv2<2; lcv2++ ) {
01553                         volhandler_idx[lcv1][lcv2] = 0xff;
01554 
01555                         for( int lcv3=0; lcv3<5; lcv3++ ) {
01556                                 if( chip.chan[lcv1].op[lcv2].volHandler == VolumeHandlerTable[lcv3] ) {
01557                                         volhandler_idx[lcv1][lcv2] = lcv3;
01558                                         break;
01559                                 }
01560                         }
01561 
01562                         wavebase_idx[lcv1][lcv2] = (Bitu) chip.chan[lcv1].op[lcv2].waveBase - (Bitu) &WaveTable;
01563                 }
01564 
01565 
01566                 synthhandler_idx[lcv1] = 0xff;
01567                 if(0) {}
01568                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMFM > ) synthhandler_idx[lcv1] = 0x00;
01569                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMFM > ) synthhandler_idx[lcv1] = 0x01;
01570                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FMAM > ) synthhandler_idx[lcv1] = 0x02;
01571                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AMAM > ) synthhandler_idx[lcv1] = 0x03;
01572                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3AM > ) synthhandler_idx[lcv1] = 0x04;
01573                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3FM > ) synthhandler_idx[lcv1] = 0x05;
01574                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2AM > ) synthhandler_idx[lcv1] = 0x06;
01575                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2FM > ) synthhandler_idx[lcv1] = 0x07;
01576                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm3Percussion > ) synthhandler_idx[lcv1] = 0x08;
01577                 else if( chip.chan[lcv1].synthHandler == &Channel::BlockTemplate< sm2Percussion > ) synthhandler_idx[lcv1] = 0x09;
01578         }
01579 
01580         //***************************************************
01581         //***************************************************
01582         //***************************************************
01583 
01584         // dbopl.cpp
01585 
01586         // - pure data
01587         WRITE_POD( &WaveTable, WaveTable );
01588         WRITE_POD( &doneTables, doneTables );
01589 
01590         //***************************************************
01591         //***************************************************
01592         //***************************************************
01593 
01594         // dbopl.h
01595 
01596         // - near-pure data
01597         WRITE_POD( &chip, chip );
01598 
01599 
01600 
01601 
01602         // - reloc ptr (!!!)
01603         WRITE_POD( &volhandler_idx, volhandler_idx );
01604         WRITE_POD( &wavebase_idx, wavebase_idx );
01605         WRITE_POD( &synthhandler_idx, synthhandler_idx );
01606 }
01607 
01608 void Handler::LoadState( std::istream& stream )
01609 {
01610         char pod_name[32] = {0};
01611 
01612         if( stream.fail() ) return;
01613 
01614 
01615         // error checking
01616         READ_POD( &pod_name, pod_name );
01617         if( strcmp( pod_name, "DBOPL" ) ) {
01618                 stream.clear( std::istream::failbit | std::istream::badbit );
01619                 return;
01620         }
01621 
01622         //************************************************
01623         //************************************************
01624         //************************************************
01625 
01626         Bit8u volhandler_idx[18][2];
01627         Bit32u wavebase_idx[18][2];
01628         Bit8u synthhandler_idx[18];
01629 
01630         //***************************************************
01631         //***************************************************
01632         //***************************************************
01633 
01634         // dbopl.cpp
01635 
01636         // - pure data
01637         READ_POD( &WaveTable, WaveTable );
01638         READ_POD( &doneTables, doneTables );
01639 
01640         //***************************************************
01641         //***************************************************
01642         //***************************************************
01643 
01644         // dbopl.h
01645 
01646         // - near-pure data
01647         READ_POD( &chip, chip );
01648 
01649 
01650 
01651 
01652         // - reloc ptr (!!!)
01653         READ_POD( &volhandler_idx, volhandler_idx );
01654         READ_POD( &wavebase_idx, wavebase_idx );
01655         READ_POD( &synthhandler_idx, synthhandler_idx );
01656 
01657         //***************************************************
01658         //***************************************************
01659         //***************************************************
01660 
01661         for( int lcv1=0; lcv1<18; lcv1++ ) {
01662                 for( int lcv2=0; lcv2<2; lcv2++ ) {
01663                         chip.chan[lcv1].op[lcv2].volHandler = VolumeHandlerTable[ volhandler_idx[lcv1][lcv2] ];
01664 
01665                         chip.chan[lcv1].op[lcv2].waveBase = (Bit16s *) ((Bitu) wavebase_idx[lcv1][lcv2] + (Bitu) &WaveTable);
01666                 }
01667 
01668 
01669                 switch( synthhandler_idx[lcv1] ) {
01670                         case 0x00: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMFM >; break;
01671                         case 0x01: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMFM >; break;
01672                         case 0x02: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FMAM >; break;
01673                         case 0x03: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AMAM >; break;
01674                         case 0x04: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3AM >; break;
01675                         case 0x05: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3FM >; break;
01676                         case 0x06: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2AM >; break;
01677                         case 0x07: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2FM >; break;
01678                         case 0x08: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm3Percussion >; break;
01679                         case 0x09: chip.chan[lcv1].synthHandler = &Channel::BlockTemplate< sm2Percussion >; break;
01680                 }
01681         }
01682 }
01683  }              //Namespace DBOPL