00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #if defined(SID_MONITOR) || defined(WB_DEBUG)
00044 #include <iostream.h>
00045 #include <iomanip.h>
00046 #endif
00047
00048 #include "myendian.h"
00049 #include "sidtune.h"
00050 #include "6510_.h"
00051 #include "emucfg.h"
00052 #include "envelope.h"
00053 #include "samples.h"
00054 #include "wave6581.h"
00055 #include "wave8580.h"
00056 #include "6581_.h"
00057 #include "mixing.h"
00058
00059
00060
00061 static const uword apSpeed = 0x4000;
00062 static const udword noiseSeed = 0x7ffff8;
00063
00064 #define lowPassParam filterTable
00065
00066
00067
00068
00069
00070
00071 inline void sidEmu::calcValuesPerCall()
00072 {
00073 udword fastForwardFreq = PCMfreq;
00074 if ( fastForwardFactor != 128 )
00075 {
00076 fastForwardFreq = (PCMfreq * fastForwardFactor) >> 7;
00077 }
00078 #if defined(DIRECT_FIXPOINT)
00079 VALUES.l = ( VALUESorg.l = (((fastForwardFreq<<12)/calls)<<4) );
00080 VALUESadd.l = 0;
00081 #else
00082 VALUES = (VALUESorg = (fastForwardFreq / calls));
00083 VALUEScomma = ((fastForwardFreq % calls) * 65536UL) / calls;
00084 VALUESadd = 0;
00085 #endif
00086 }
00087
00088
00089 void sidEmu::sidEmuChangeReplayingSpeed()
00090 {
00091 calcValuesPerCall();
00092 }
00093
00094
00095
00096
00097
00098
00099
00100 void sidEmu::sidEmuSetClockSpeed(int clockMode)
00101 {
00102 switch (clockMode)
00103 {
00104 case SIDTUNE_CLOCK_NTSC:
00105 {
00106 C64_clockSpeed = 1022727;
00107 C64_fClockSpeed = 1022727.14f;
00108 break;
00109 }
00110 case SIDTUNE_CLOCK_PAL:
00111 default:
00112 {
00113 C64_clockSpeed = 985248;
00114 C64_fClockSpeed = (float)985248.4;
00115 break;
00116 }
00117 }
00118 }
00119
00120
00121 void sidEmu::sidEmuSetReplayingSpeed(int clockMode, uword callsPerSec)
00122 {
00123 switch (clockMode)
00124 {
00125 case SIDTUNE_CLOCK_NTSC:
00126 {
00127 sidtuneClockSpeed = 1022727;
00128 timer = (defaultTimer = 0x4295);
00129 break;
00130 }
00131 case SIDTUNE_CLOCK_PAL:
00132 default:
00133 {
00134 sidtuneClockSpeed = 985248;
00135 timer = (defaultTimer = 0x4025);
00136 break;
00137 }
00138 }
00139 switch (callsPerSec)
00140 {
00141 case SIDTUNE_SPEED_CIA_1A:
00142 {
00143 timer = readLEword(c64mem2+0xdc04);
00144 if (timer < 16)
00145 {
00146 timer = defaultTimer;
00147 }
00148 calls = (uword)(sidtuneClockSpeed / timer);
00149 break;
00150 }
00151 default:
00152 {
00153 calls = callsPerSec;
00154 break;
00155 }
00156 }
00157 calcValuesPerCall();
00158 }
00159
00160
00161 void sidEmu::sidEmuUpdateReplayingSpeed()
00162 {
00163 if ( timer != readLEword(c64mem2+0xdc04) )
00164 {
00165 timer = readLEword(c64mem2+0xdc04);
00166
00167 if ( timer < 16 )
00168 timer = defaultTimer;
00169 calls = (uword)(sidtuneClockSpeed / timer);
00170 calcValuesPerCall();
00171 }
00172 }
00173
00174
00175
00176 inline void waveAdvance(struct sidOperator* pVoice)
00177 {
00178 #if defined(DIRECT_FIXPOINT)
00179 pVoice->waveStep.l += pVoice->waveStepAdd.l;
00180 pVoice->waveStep.w[HI] &= 4095;
00181 #else
00182 pVoice->waveStepPnt += pVoice->waveStepAddPnt;
00183 pVoice->waveStep += ( pVoice->waveStepAdd + ( pVoice->waveStepPnt > 65535 ));
00184 pVoice->waveStepPnt &= 0xFFFF;
00185 pVoice->waveStep &= 4095;
00186 #endif
00187 }
00188
00189 inline void sidEmu::noiseAdvance(struct sidOperator* pVoice)
00190 {
00191 pVoice->noiseStep += pVoice->noiseStepAdd;
00192 if (pVoice->noiseStep >= (1L<<20))
00193 {
00194 pVoice->noiseStep -= (1L<<20);
00195 #if defined(DIRECT_FIXPOINT)
00196 pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
00197 (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
00198 #else
00199 pVoice->noiseReg = (pVoice->noiseReg << 1) |
00200 (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
00201 #endif
00202 #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE)
00203 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]]
00204 |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]);
00205 #elif defined(DIRECT_FIXPOINT)
00206 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]]
00207 |noiseTableMID[pVoice->noiseReg.b[LOHI]]
00208 |noiseTableMSB[pVoice->noiseReg.b[HILO]]);
00209 #else
00210 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff]
00211 |noiseTableMID[pVoice->noiseReg>>8&0xff]
00212 |noiseTableMSB[pVoice->noiseReg>>16&0xff]);
00213 #endif
00214 }
00215 }
00216
00217 inline void sidEmu::noiseAdvanceHp(struct sidOperator* pVoice)
00218 {
00219 udword tmp = pVoice->noiseStepAdd;
00220 while (tmp >= (1L<<20))
00221 {
00222 tmp -= (1L<<20);
00223 #if defined(DIRECT_FIXPOINT)
00224 pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
00225 (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
00226 #else
00227 pVoice->noiseReg = (pVoice->noiseReg << 1) |
00228 (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
00229 #endif
00230 }
00231 pVoice->noiseStep += tmp;
00232 if (pVoice->noiseStep >= (1L<<20))
00233 {
00234 pVoice->noiseStep -= (1L<<20);
00235 #if defined(DIRECT_FIXPOINT)
00236 pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
00237 (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
00238 #else
00239 pVoice->noiseReg = (pVoice->noiseReg << 1) |
00240 (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
00241 #endif
00242 }
00243 #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE)
00244 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]]
00245 |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]);
00246 #elif defined(DIRECT_FIXPOINT)
00247 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]]
00248 |noiseTableMID[pVoice->noiseReg.b[LOHI]]
00249 |noiseTableMSB[pVoice->noiseReg.b[HILO]]);
00250 #else
00251 pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff]
00252 |noiseTableMID[pVoice->noiseReg>>8&0xff]
00253 |noiseTableMSB[pVoice->noiseReg>>16&0xff]);
00254 #endif
00255 }
00256
00257
00258 #if defined(DIRECT_FIXPOINT)
00259 #define triangle triangleTable[pVoice->waveStep.w[HI]]
00260 #define sawtooth sawtoothTable[pVoice->waveStep.w[HI]]
00261 #define square squareTable[pVoice->waveStep.w[HI] + pVoice->pulseIndex]
00262 #define triSaw waveform30_8580[pVoice->waveStep.w[HI]]
00263
00264 #ifdef LESS_CODE_BUT_ABIT_SLOWER // use index 0 -> content 0 if index >= 4096
00265 #define triSquare (waveform50[( ((pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) : 0 )])
00266 #define sawSquare (waveform60_8580[( ((pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) : 0 )])
00267 #define triSawSquare (waveform70_8580[( ((pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth) : 0 )])
00268 #else
00269 #define triSquare waveform50[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
00270 #define sawSquare waveform60_8580[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
00271 #define triSawSquare waveform70_8580[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
00272 #endif
00273
00274 #else
00275 #define triangle triangleTable[pVoice->waveStep]
00276 #define sawtooth sawtoothTable[pVoice->waveStep]
00277 #define square squareTable[pVoice->waveStep + pVoice->pulseIndex]
00278 #define triSaw waveform30_8580[pVoice->waveStep]
00279 #ifdef LESS_CODE_BUT_ABIT_SLOWER
00280 #define triSquare (waveform50[ ((pVoice->waveStep + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep + pVoice->SIDpulseWidth) : 0 ] )
00281 #define sawSquare (waveform60_8580[ ((pVoice->waveStep + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep + pVoice->SIDpulseWidth) : 0 ] )
00282 #define triSawSquare (waveform70_8580[ ((pVoice->waveStep + pVoice->SIDpulseWidth) < 4096) ? (pVoice->waveStep + pVoice->SIDpulseWidth) : 0 ] )
00283 #else
00284 #define sawSquare waveform60_8580[pVoice->waveStep + pVoice->SIDpulseWidth]
00285 #define triSawSquare waveform70_8580[pVoice->waveStep + pVoice->SIDpulseWidth]
00286 #endif
00287
00288 #endif
00289
00290
00291 void sidEmu::sidMode00(struct sidOperator* pVoice) {
00292 pVoice->output = (pVoice->filtIO-0x80);
00293 waveAdvance(pVoice);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 void sidEmu::sidMode10(struct sidOperator* pVoice) {
00304 pVoice->output = triangle;
00305 waveAdvance(pVoice);
00306 }
00307
00308 void sidEmu::sidMode20(struct sidOperator* pVoice) {
00309 pVoice->output = sawtooth;
00310 waveAdvance(pVoice);
00311 }
00312
00313 void sidEmu::sidMode30(struct sidOperator* pVoice) {
00314 #ifdef SIDEMU_OLD_WAVE30
00315 pVoice->output = ( triangle & sawtooth );
00316 #else
00317 pVoice->output = triSaw;
00318 #endif
00319 waveAdvance(pVoice);
00320 }
00321
00322 void sidEmu::sidMode40(struct sidOperator* pVoice) {
00323 pVoice->output = square;
00324 waveAdvance(pVoice);
00325 }
00326
00327 void sidEmu::sidMode50(struct sidOperator* pVoice) {
00328 pVoice->output = triSquare;
00329 waveAdvance(pVoice);
00330 }
00331
00332 void sidEmu::sidMode60(struct sidOperator* pVoice) {
00333 pVoice->output = sawSquare;
00334 waveAdvance(pVoice);
00335 }
00336
00337 void sidEmu::sidMode70(struct sidOperator* pVoice) {
00338 pVoice->output = triSawSquare;
00339 waveAdvance(pVoice);
00340 }
00341
00342 void sidEmu::sidMode80(struct sidOperator* pVoice) {
00343 pVoice->output = pVoice->noiseOutput;
00344 waveAdvance(pVoice);
00345 noiseAdvance(pVoice);
00346 }
00347
00348 void sidEmu::sidMode80hp(struct sidOperator* pVoice) {
00349 pVoice->output = pVoice->noiseOutput;
00350 waveAdvance(pVoice);
00351 noiseAdvanceHp(pVoice);
00352 }
00353
00354 void sidEmu::sidModeLock(struct sidOperator* pVoice)
00355 {
00356 pVoice->noiseIsLocked = true;
00357 pVoice->output = (pVoice->filtIO-0x80);
00358 waveAdvance(pVoice);
00359 }
00360
00361
00362
00363
00364
00365 void sidEmu::sidMode14(struct sidOperator* pVoice)
00366 {
00367 #if defined(DIRECT_FIXPOINT)
00368 if ( pVoice->modulator->waveStep.w[HI] < 2048 )
00369 #else
00370 if ( pVoice->modulator->waveStep < 2048 )
00371 #endif
00372 pVoice->output = triangle;
00373 else
00374 pVoice->output = 0xFF ^ triangle;
00375 waveAdvance(pVoice);
00376 }
00377
00378 void sidEmu::sidMode34(struct sidOperator* pVoice) {
00379 #if defined(DIRECT_FIXPOINT)
00380 if ( pVoice->modulator->waveStep.w[HI] < 2048 )
00381 #else
00382 if ( pVoice->modulator->waveStep < 2048 )
00383 #endif
00384 #ifdef SIDEMU_OLD_WAVE30
00385 pVoice->output = triangle & sawtooth;
00386 else
00387 pVoice->output = (0xFF^triangle) & (0xFF^sawtooth);
00388 #else
00389 pVoice->output = triSaw;
00390 else
00391 pVoice->output = 0xFF ^ triSaw;
00392 #endif
00393 waveAdvance(pVoice);
00394 }
00395
00396 void sidEmu::sidMode54(struct sidOperator* pVoice) {
00397 #if defined(DIRECT_FIXPOINT)
00398 if ( pVoice->modulator->waveStep.w[HI] < 2048 )
00399 #else
00400 if ( pVoice->modulator->waveStep < 2048 )
00401 #endif
00402 pVoice->output = triSquare;
00403 else
00404 pVoice->output = 0xFF ^ triSquare;
00405 waveAdvance(pVoice);
00406 }
00407
00408 void sidEmu::sidMode74(struct sidOperator* pVoice) {
00409 #if defined(DIRECT_FIXPOINT)
00410 if ( pVoice->modulator->waveStep.w[HI] < 2048 )
00411 #else
00412 if ( pVoice->modulator->waveStep < 2048 )
00413 #endif
00414 pVoice->output = triSawSquare;
00415 else
00416 pVoice->output = 0xFF ^ triSawSquare;
00417 waveAdvance(pVoice);
00418 }
00419
00420
00421
00422
00423
00424 inline void waveCalcCycleLen(struct sidOperator* pVoice)
00425 {
00426 #if defined(DIRECT_FIXPOINT)
00427 pVoice->cycleAddLen.w[HI] = 0;
00428 pVoice->cycleAddLen.l += pVoice->cycleLen.l;
00429 pVoice->cycleLenCount = pVoice->cycleAddLen.w[HI];
00430 #else
00431 pVoice->cycleAddLenPnt += pVoice->cycleLenPnt;
00432 pVoice->cycleLenCount = pVoice->cycleLen + ( pVoice->cycleAddLenPnt > 65535 );
00433 pVoice->cycleAddLenPnt &= 0xFFFF;
00434 #endif
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 #if defined(DIRECT_FIXPOINT)
00449 register uword diff = pVoice->cycleLenCount - pVoice->cycleLen.w[HI];
00450 #else
00451 register uword diff = pVoice->cycleLenCount - pVoice->cycleLen;
00452 #endif
00453 if ( pVoice->wavePre[diff].len != pVoice->cycleLenCount )
00454 {
00455 pVoice->wavePre[diff].len = (uword)(pVoice->cycleLenCount);
00456 #if defined(DIRECT_FIXPOINT)
00457 pVoice->wavePre[diff].stp = (pVoice->waveStepAdd.l = (4096UL*65536UL) / pVoice->cycleLenCount);
00458 #else
00459 pVoice->wavePre[diff].stp = (uword)(pVoice->waveStepAdd = 4096UL / pVoice->cycleLenCount);
00460 pVoice->wavePre[diff].pnt = (pVoice->waveStepAddPnt = ((4096UL % pVoice->cycleLenCount) * 65536UL) / pVoice->cycleLenCount);
00461 #endif
00462 }
00463 else
00464 {
00465 #if defined(DIRECT_FIXPOINT)
00466 pVoice->waveStepAdd.l = pVoice->wavePre[diff].stp;
00467 #else
00468 pVoice->waveStepAdd = pVoice->wavePre[diff].stp;
00469 pVoice->waveStepAddPnt = pVoice->wavePre[diff].pnt;
00470 #endif
00471 }
00472
00473 }
00474
00475 inline void sidEmu::waveCalcFilter(struct sidOperator* pVoice)
00476 {
00477 if ( pVoice->filtEnabled )
00478 {
00479 if ( filterType != 0 )
00480 {
00481 if ( filterType == 0x20 )
00482 {
00483 pVoice->filtLow += ( pVoice->filtRef * filterDy );
00484 float tmp = (float)pVoice->filtIO - pVoice->filtLow;
00485 tmp -= pVoice->filtRef * filterResDy;
00486 pVoice->filtRef += ( tmp * (filterDy) );
00487 pVoice->filtIO = (sbyte)(pVoice->filtRef-pVoice->filtLow/4);
00488 }
00489 else if (filterType == 0x40)
00490 {
00491 pVoice->filtLow += (float)( pVoice->filtRef * filterDy * 0.1 );
00492 float tmp = (float)pVoice->filtIO - pVoice->filtLow;
00493 tmp -= pVoice->filtRef * filterResDy;
00494 pVoice->filtRef += ( tmp * (filterDy) );
00495 float tmp2 = pVoice->filtRef - pVoice->filtIO/8;
00496 if (tmp2 < -128)
00497 tmp2 = -128;
00498 if (tmp2 > 127)
00499 tmp2 = 127;
00500 pVoice->filtIO = (sbyte)tmp2;
00501 }
00502 else
00503 {
00504 pVoice->filtLow += ( pVoice->filtRef * filterDy );
00505 float sample = pVoice->filtIO;
00506 float sample2 = sample - pVoice->filtLow;
00507 int tmp = (int)sample2;
00508 sample2 -= pVoice->filtRef * filterResDy;
00509 pVoice->filtRef += ( sample2 * filterDy );
00510
00511 if ( filterType == 0x10 )
00512 {
00513 pVoice->filtIO = (sbyte)pVoice->filtLow;
00514 }
00515 else if ( filterType == 0x30 )
00516 {
00517 pVoice->filtIO = (sbyte)pVoice->filtLow;
00518 }
00519 else if ( filterType == 0x50 )
00520 {
00521 pVoice->filtIO = (sbyte)(sample - (tmp >> 1));
00522 }
00523 else if ( filterType == 0x60 )
00524 {
00525 pVoice->filtIO = (sbyte)tmp;
00526 }
00527 else if ( filterType == 0x70 )
00528 {
00529 pVoice->filtIO = (sbyte)(sample - (tmp >> 1));
00530 }
00531 }
00532 }
00533 else
00534 {
00535 pVoice->filtIO = 0;
00536 }
00537 }
00538 }
00539
00540
00541 sbyte sidEmu::waveCalcMute(struct sidOperator* pVoice)
00542 {
00543
00544
00545 (iTheEnvelope->*pVoice->ADSRproc)(pVoice);
00546 return pVoice->filtIO;
00547 }
00548
00549
00550 sbyte sidEmu::waveCalcNormal(struct sidOperator* pVoice)
00551 {
00552
00553 if ( pVoice->cycleLenCount <= 0 )
00554 {
00555 waveCalcCycleLen(pVoice);
00556 if (( pVoice->SIDctrl & 0x40 ) == 0x40 )
00557 {
00558 pVoice->pulseIndex = pVoice->newPulseIndex;
00559 if ( pVoice->pulseIndex > 2048 )
00560 {
00561 #if defined(DIRECT_FIXPOINT)
00562 pVoice->waveStep.w[HI] = 0;
00563 #else
00564 pVoice->waveStep = 0;
00565 #endif
00566 }
00567 }
00568 }
00569
00570 (this->*pVoice->waveProc)(pVoice);
00571
00572
00573
00574 int index = (iTheEnvelope->*pVoice->ADSRproc)(pVoice);
00575
00576 pVoice->filtIO = iTheEmuEngine->ampMod1x8[index | pVoice->output];
00577
00578 ((sidEmu*)this)->waveCalcFilter(pVoice);
00579
00580 return pVoice->filtIO;
00581 }
00582
00583 sbyte sidEmu::waveCalcRangeCheck(struct sidOperator* pVoice)
00584 {
00585
00586 #if defined(DIRECT_FIXPOINT)
00587 pVoice->waveStepOld = pVoice->waveStep.w[HI];
00588 (this->*pVoice->waveProc)(pVoice);
00589 if (pVoice->waveStep.w[HI] < pVoice->waveStepOld)
00590 #else
00591 pVoice->waveStepOld = pVoice->waveStep;
00592 (this->*pVoice->waveProc)(pVoice);
00593 if (pVoice->waveStep < pVoice->waveStepOld)
00594 #endif
00595 {
00596
00597 pVoice->cycleLenCount = 0;
00598 pVoice->outProc = &sidEmu::waveCalcNormal;
00599 #if defined(DIRECT_FIXPOINT)
00600 pVoice->waveStep.w[HI] = 4095;
00601 #else
00602 pVoice->waveStep = 4095;
00603 #endif
00604 }
00605
00606 int index = (iTheEnvelope->*pVoice->ADSRproc)(pVoice);
00607 pVoice->filtIO = iTheEmuEngine->ampMod1x8[index | pVoice->output];
00608
00609
00610
00611 ((sidEmu*)this)->waveCalcFilter(pVoice);
00612 return pVoice->filtIO;
00613 }
00614
00615
00616
00617 inline void sidEmu::sidEmuSet(struct sidOperator* pVoice, uword sidIndex)
00618 {
00619 pVoice->SIDfreq = readLEword(c64mem2+sidIndex);
00620
00621 pVoice->SIDpulseWidth = (readLEword(c64mem2+sidIndex+2) & 0x0FFF);
00622 pVoice->newPulseIndex = 4096 - pVoice->SIDpulseWidth;
00623 #if defined(DIRECT_FIXPOINT)
00624 if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) >= 0x1000)
00625 && ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) >= 0x1000) )
00626 {
00627 pVoice->pulseIndex = pVoice->newPulseIndex;
00628 }
00629 else if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) < 0x1000)
00630 && ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) < 0x1000) )
00631 {
00632 pVoice->pulseIndex = pVoice->newPulseIndex;
00633 }
00634 #else
00635 if ( ((pVoice->waveStep + pVoice->pulseIndex) >= 0x1000)
00636 && ((pVoice->waveStep + pVoice->newPulseIndex) >= 0x1000) )
00637 {
00638 pVoice->pulseIndex = pVoice->newPulseIndex;
00639 }
00640 else if ( ((pVoice->waveStep + pVoice->pulseIndex) < 0x1000)
00641 && ((pVoice->waveStep + pVoice->newPulseIndex) < 0x1000) )
00642 {
00643 pVoice->pulseIndex = pVoice->newPulseIndex;
00644 }
00645 #endif
00646
00647 ubyte enveTemp, newWave, oldWave;
00648
00649 oldWave = pVoice->SIDctrl;
00650 enveTemp = pVoice->ADSRctrl;
00651 pVoice->SIDctrl = (newWave = c64mem2[sidIndex +4]);
00652
00653 if (( newWave & 1 ) ==0 )
00654 {
00655 if (( oldWave & 1 ) !=0 )
00656 enveTemp = ENVE_STARTRELEASE;
00657
00658
00659
00660
00661 }
00662 else if ( pVoice->gateOffCtrl || ((oldWave&1)==0) )
00663 {
00664 enveTemp = ENVE_STARTATTACK;
00665 if (doAutoPanning && updateAutoPanning)
00666 {
00667
00668 uword tmp = pVoice->gainSource;
00669 pVoice->gainSource = pVoice->gainDest;
00670 pVoice->gainDest = tmp;
00671 if ((pVoice->gainDest^pVoice->gainSource) == 0)
00672 {
00673
00674 pVoice->gainLeft = (pVoice->gainRight = 0x0000+0x80);
00675 }
00676 else
00677 {
00678
00679 pVoice->gainLeft = pVoice->gainLeftCentered;
00680 pVoice->gainRight = pVoice->gainRightCentered;
00681 }
00682
00683
00684
00685 pVoice->gainDirec = (pVoice->gainLeft > pVoice->gainDest);
00686 }
00687 }
00688
00689 if (doAutoPanning && updateAutoPanning && (enveTemp!=ENVE_STARTATTACK))
00690 {
00691 if (pVoice->gainDirec)
00692 {
00693 if (pVoice->gainLeft > pVoice->gainDest)
00694 {
00695 pVoice->gainLeft -= 0x0100;
00696 pVoice->gainRight += 0x0100;
00697 }
00698 else
00699 {
00700
00701 uword tmp = pVoice->gainSource;
00702 pVoice->gainSource = pVoice->gainDest;
00703 pVoice->gainDest = tmp;
00704
00705 pVoice->gainDirec = false;
00706 }
00707 }
00708 else
00709 {
00710 if (pVoice->gainRight > pVoice->gainSource)
00711 {
00712 pVoice->gainLeft += 0x0100;
00713 pVoice->gainRight -= 0x0100;
00714 }
00715 else
00716 {
00717 pVoice->gainDirec = true;
00718
00719 uword tmp = pVoice->gainSource;
00720 pVoice->gainSource = pVoice->gainDest;
00721
00722 pVoice->gainDest = tmp;
00723 }
00724 }
00725 }
00726
00727 if ((( oldWave ^ newWave ) & 0xF0 ) != 0 )
00728 {
00729 pVoice->cycleLenCount = 0;
00730 }
00731
00732 ubyte ADtemp = c64mem2[sidIndex +5];
00733 ubyte SRtemp = c64mem2[sidIndex +6];
00734 if ( pVoice->SIDAD != ADtemp )
00735 {
00736 enveTemp |= ENVE_ALTER;
00737 }
00738 else if ( pVoice->SIDSR != SRtemp )
00739 {
00740 enveTemp |= ENVE_ALTER;
00741 }
00742 pVoice->SIDAD = ADtemp;
00743 pVoice->SIDSR = SRtemp;
00744 extern const ubyte masterVolumeLevels[16];
00745 ubyte tmpSusVol = masterVolumeLevels[SRtemp >> 4];
00746 if (pVoice->ADSRctrl != ENVE_SUSTAIN)
00747 {
00748 pVoice->enveSusVol = tmpSusVol;
00749 }
00750 else
00751 {
00752 if ( pVoice->enveSusVol > pVoice->enveVol )
00753 pVoice->enveSusVol = 0;
00754 else
00755 pVoice->enveSusVol = tmpSusVol;
00756 }
00757
00758 pVoice->ADSRproc = (iTheEnvelope->getEnveModeTable())[enveTemp>>1];
00759 pVoice->ADSRctrl = enveTemp & (255-ENVE_ALTER-1);
00760
00761 if ( filterEnabled )
00762 {
00763 if (( c64mem2[0xd417] & pVoice->filtVoiceMask ) != 0 )
00764 {
00765 pVoice->filtEnabled = true;
00766 }
00767 else
00768 {
00769 pVoice->filtEnabled = false;
00770 }
00771 }
00772 else
00773 {
00774 pVoice->filtEnabled = false;
00775 }
00776 }
00777
00778
00779 #if 0 //TODO
00780
00781 ptr2sidVoidFunc sidEmu::sidModeNormalTable[16] =
00782 {
00783 sidEmu::sidMode00, sidEmu::sidMode10, sidEmu::sidMode20, sidEmu::sidMode30, sidEmu::sidMode40, sidEmu::sidMode50, sidEmu::sidMode60, sidEmu::sidMode70,
00784 sidEmu::sidMode80, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock
00785 };
00786
00787
00788 ptr2sidVoidFunc sidEmu::sidModeRingTable[16] =
00789 {
00790 sidEmu::sidMode00, sidEmu::sidMode14, sidEmu::sidMode00, sidEmu::sidMode34, sidEmu::sidMode00, sidEmu::sidMode54, sidEmu::sidMode00, sidEmu::sidMode74,
00791 sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock, sidEmu::sidModeLock
00792 };
00793 #endif
00794
00795 inline void sidEmu::sidEmuSet2(struct sidOperator* pVoice)
00796 {
00797 pVoice->outProc = &sidEmu::waveCalcNormal;
00798 pVoice->sync = false;
00799
00800 if ( (pVoice->SIDfreq < 16)
00801 || ((pVoice->SIDctrl & 8) != 0) )
00802 {
00803 pVoice->outProc = &sidEmu::waveCalcMute;
00804 if (pVoice->SIDfreq == 0)
00805 {
00806 #if defined(DIRECT_FIXPOINT)
00807 pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0);
00808 pVoice->waveStep.l = 0;
00809 #else
00810 pVoice->cycleLen = (pVoice->cycleLenPnt = 0);
00811 pVoice->cycleAddLenPnt = 0;
00812 pVoice->waveStep = 0;
00813 pVoice->waveStepPnt = 0;
00814 #endif
00815 pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0);
00816 pVoice->noiseStepAdd = 0;
00817 pVoice->cycleLenCount = 0;
00818 }
00819 if ((pVoice->SIDctrl & 8) != 0)
00820 {
00821 if (pVoice->noiseIsLocked)
00822 {
00823 pVoice->noiseIsLocked = false;
00824 #if defined(DIRECT_FIXPOINT)
00825 pVoice->noiseReg.l = noiseSeed;
00826 #else
00827 pVoice->noiseReg = noiseSeed;
00828 #endif
00829 }
00830 }
00831 }
00832 else
00833 {
00834 if ( pVoice->curSIDfreq != pVoice->SIDfreq )
00835 {
00836 pVoice->curSIDfreq = (uword)(pVoice->SIDfreq);
00837
00838
00839 #if defined(DIRECT_FIXPOINT)
00840 pVoice->cycleLen.l = ((PCMsid << 12) / pVoice->SIDfreq) << 4;
00841 if (pVoice->cycleLenCount > 0)
00842 {
00843 waveCalcCycleLen(pVoice);
00844 pVoice->outProc = &sidEmu::waveCalcRangeCheck;
00845 }
00846 #else
00847 pVoice->cycleLen = (uword)(PCMsid / pVoice->SIDfreq);
00848 pVoice->cycleLenPnt = (uword)((( PCMsid % pVoice->SIDfreq ) * 65536UL ) / pVoice->SIDfreq);
00849 if (pVoice->cycleLenCount > 0)
00850 {
00851 waveCalcCycleLen(pVoice);
00852 pVoice->outProc = &sidEmu::waveCalcRangeCheck;
00853 }
00854 #endif
00855 }
00856
00857 if ((( pVoice->SIDctrl & 0x80 ) == 0x80 ) && ( pVoice->curNoiseFreq != pVoice->SIDfreq ))
00858 {
00859 pVoice->curNoiseFreq = (uword)(pVoice->SIDfreq);
00860 pVoice->noiseStepAdd = (PCMsidNoise * pVoice->SIDfreq) >> 8;
00861 if (pVoice->noiseStepAdd >= (1L<<21))
00862 sidModeNormalTable[8] = &sidEmu::sidMode80hp;
00863 else
00864 sidModeNormalTable[8] = &sidEmu::sidMode80;
00865 }
00866
00867 if (( pVoice->SIDctrl & 2 ) != 0 )
00868 {
00869 if ( ( pVoice->modulator->SIDfreq == 0 ) || (( pVoice->modulator->SIDctrl & 8 ) != 0 ) )
00870 {
00871 ;
00872 }
00873 else if ( (( pVoice->carrier->SIDctrl & 2 ) != 0 ) &&
00874 ( pVoice->modulator->SIDfreq >= ( pVoice->SIDfreq << 1 )) )
00875 {
00876 ;
00877 }
00878 else
00879 {
00880 pVoice->sync = true;
00881 }
00882 }
00883
00884 if ((( pVoice->SIDctrl & 0x14 ) == 0x14 ) && ( pVoice->modulator->SIDfreq != 0 ))
00885 pVoice->waveProc = sidModeRingTable[pVoice->SIDctrl >> 4];
00886 else
00887 pVoice->waveProc = sidModeNormalTable[pVoice->SIDctrl >> 4];
00888 }
00889 }
00890
00891
00892
00893 void sidEmu::sidEmuFillBuffer( emuEngine& thisEmu,
00894 sidTune& thistune,
00895 void* buffer, udword bufferLen )
00896 {
00897
00898
00899
00900
00901 if ( thisEmu.isReady && thistune.returnStatus() )
00902 {
00903
00904 if ( thisEmu.config.volumeControl == SIDEMU_HWMIXING )
00905 {
00906 bufferLen >>= 2;
00907 splitBufferLen = bufferLen;
00908 }
00909
00910
00911 bufferLen >>= thisEmu.bufferScale;
00912
00913 #if defined(SIDEMU_TIME_COUNT)
00914 if (prevBufferLen != bufferLen)
00915 {
00916 prevBufferLen = bufferLen;
00917 scaledBufferLen = (bufferLen<<7) / fastForwardFactor;
00918 }
00919 thisEmu.bytesCount += scaledBufferLen;
00920 while (thisEmu.bytesCount >= thisEmu.config.frequency)
00921 {
00922 thisEmu.bytesCount -= thisEmu.config.frequency;
00923 thisEmu.secondsThisSong++;
00924 thisEmu.secondsTotal++;
00925 }
00926 #endif
00927
00928 while ( bufferLen > 0 )
00929 {
00930 if ( toFill > bufferLen )
00931 {
00932 buffer = thisEmu.iTheMixer->fillFunc(buffer, bufferLen);
00933 toFill -= (uword)bufferLen;
00934 bufferLen = 0;
00935 }
00936 else if ( toFill > 0 )
00937 {
00938 buffer = thisEmu.iTheMixer->fillFunc(buffer, toFill);
00939 bufferLen -= toFill;
00940 toFill = 0;
00941 }
00942
00943 if ( toFill == 0 )
00944 {
00945 iThe6510->optr3readWave = optr3.output;
00946 iThe6510->optr3readEnve = optr3.enveVol;
00947
00948 uword replayPC = thistune.returnPlayAddr();
00949
00950 if ( replayPC == 0 )
00951 {
00952 thisEmu.playRamRom = c64mem1[1];
00953 if ((thisEmu.playRamRom & 2) != 0)
00954 replayPC = readLEword(c64mem1+0x0314);
00955 else
00956 replayPC = readLEword(c64mem1+0xfffe);
00957 }
00958
00959 iThe6510->interpreter(replayPC, thisEmu.playRamRom, 0, 0, 0);
00960
00961 if (thistune.returnSongSpeed() == 0)
00962 {
00963 sidEmuUpdateReplayingSpeed();
00964 }
00965
00966 iTheEnvelope->masterVolume = ( c64mem2[0xd418] & 15 );
00967 iTheEnvelope->masterVolumeAmplIndex = iTheEnvelope->masterVolume << 8;
00968
00969 optr1.gateOnCtrl = iThe6510->sidKeysOn[4];
00970 optr1.gateOffCtrl = iThe6510->sidKeysOff[4];
00971 sidEmuSet( &optr1, 0xd400 );
00972 optr2.gateOnCtrl = iThe6510->sidKeysOn[4+7];
00973 optr2.gateOffCtrl = iThe6510->sidKeysOff[4+7];
00974 sidEmuSet( &optr2, 0xd407 );
00975 optr3.gateOnCtrl = iThe6510->sidKeysOn[4+14];
00976 optr3.gateOffCtrl = iThe6510->sidKeysOff[4+14];
00977 sidEmuSet( &optr3, 0xd40e );
00978
00979 filterType = c64mem2[0xd418] & 0x70;
00980 if (filterType != filterCurType)
00981 {
00982 filterCurType = filterType;
00983 optr1.filtLow = (optr1.filtRef = 0);
00984 optr2.filtLow = (optr2.filtRef = 0);
00985 optr3.filtLow = (optr3.filtRef = 0);
00986 }
00987 if ( filterEnabled )
00988 {
00989
00990 filterValue = 0x7ff & ( (c64mem2[0xd415]&7) | ( (uword)c64mem2[0xd416] << 3 ));
00991 if (filterType == 0x20)
00992 filterDy = bandPassParam[filterValue];
00993 else
00994 filterDy = lowPassParam[filterValue];
00995 filterResDy = filterResTable[c64mem2[0xd417] >> 4] - filterDy;
00996 if ( filterResDy < 1.0 )
00997 filterResDy = 1.0;
00998 }
00999
01000 sidEmuSet2( &optr1 );
01001 sidEmuSet2( &optr2 );
01002 sidEmuSet2( &optr3 );
01003
01004 iTheSampler->sampleEmuCheckForInit();
01005
01006 #if defined(DIRECT_FIXPOINT)
01007 VALUESadd.w[HI] = 0;
01008 VALUESadd.l += VALUES.l;
01009 toFill = VALUESadd.w[HI];
01010 #else
01011 udword temp = (VALUESadd + VALUEScomma);
01012 VALUESadd = temp & 0xFFFF;
01013 toFill = VALUES + (temp > 65535);
01014 #endif
01015
01016
01017 if ((apCount += timer) >= apSpeed)
01018 {
01019 apCount -= apSpeed;
01020 updateAutoPanning = true;
01021 }
01022 else
01023 updateAutoPanning = false;
01024
01025 }
01026 }
01027 }
01028 }
01029
01030
01031 bool sidEmu::sidEmuFastForwardReplay( int percent )
01032 {
01033 if (( percent < 1 ) || ( percent > 100 ))
01034 {
01035 return false;
01036 }
01037 else
01038 {
01039 fastForwardFactor = (percent<<7)/100;
01040 #if defined(SIDEMU_TIME_COUNT)
01041 scaledBufferLen = (prevBufferLen<<7)/fastForwardFactor;
01042 #endif
01043 calcValuesPerCall();
01044
01045
01046
01047 #if defined(DIRECT_FIXPOINT)
01048 if (VALUES.w[HI] < 1)
01049 {
01050 VALUES.l = (VALUESorg.l = 0);
01051 VALUES.w[HI] = (VALUESorg.w[HI] = 1);
01052 }
01053 #else
01054 if (VALUES < 1)
01055 {
01056 VALUES = (VALUESorg = 1);
01057 VALUEScomma = 0;
01058 }
01059 #endif
01060 return true;
01061 }
01062 }
01063
01064
01065
01066 void sidEmu::initWaveformTables(bool isNewSID)
01067 {
01068 int i,j;
01069 uword k;
01070
01071 k = 0;
01072 for ( i = 0; i < 256; i++ )
01073 for ( j = 0; j < 8; j++ )
01074 triangleTable[k++] = (ubyte)i;
01075 for ( i = 255; i >= 0; i-- )
01076 for ( j = 0; j < 8; j++ )
01077 triangleTable[k++] = (ubyte)i;
01078
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 k = 0;
01091 for ( i = 0; i < 256; i++ )
01092 for ( j = 0; j < 16; j++ )
01093 sawtoothTable[k++] = (ubyte)i;
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 k = 0;
01108 for ( i = 0; i < 4096; i++ )
01109 squareTable[k++] = 0;
01110 for ( i = 0; i < 4096; i++ )
01111 squareTable[k++] = 255;
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 #ifdef SIDEMU_OLD_WAVE50
01123 ubyte makeSIDsData1[17*8] =
01124 {
01125 0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x7f,
01126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01127 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01128 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
01130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
01132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
01133 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0xbf,
01134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01135 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
01136 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
01137 0x00,0x00,0x00,0xc0,0x00,0xc0,0xc0,0xdf,
01138 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
01139 0x00,0x00,0x00,0xc0,0xe0,0xe0,0xe0,0xef,
01140 0x00,0x00,0x80,0xe0,0x80,0xe0,0xe0,0xf7,
01141 0x80,0xe0,0xf0,0xfb,0xf0,0xfd,0xfe,0xff
01142 };
01143 k = 0;
01144 for ( i = 0; i < 4096; i++ )
01145 {
01146 ubyte tmp = triangleTable[i];
01147 if (tmp < 0x78)
01148 {
01149 tmp = 0;
01150 }
01151 else
01152 {
01153 tmp = makeSIDsData1[tmp-0x78];
01154 }
01155 waveform50[k++] = tmp;
01156 }
01157 #else
01158 if ( isNewSID )
01159 {
01160 for ( i = 0; i < 4096; i++ )
01161 waveform50[i] = waveform50_8580[i];
01162 }
01163 else
01164 {
01165 int dest = 0;
01166 for ( i = 0; i < 512; i++ )
01167 for ( j = 0; j < 8; j++ )
01168 waveform50[dest++] = waveform50_6581[i];
01169 }
01170 #endif
01171
01172 for ( i = 4096; i < 8192; i++ )
01173 {
01174 #ifndef LESS_CODE_BUT_ABIT_SLOWER
01175 waveform50[i] = 0;
01176 waveform60_8580[i] = 0;
01177 waveform70_8580[i] = 0;
01178 #endif
01179
01180 }
01181
01182 if ( isNewSID )
01183 {
01184 sidModeNormalTable[3] = &sidEmu::sidMode30;
01185 sidModeNormalTable[6] = &sidEmu::sidMode60;
01186 sidModeNormalTable[7] = &sidEmu::sidMode70;
01187 sidModeRingTable[7] = &sidEmu::sidMode74;
01188 }
01189 else
01190 {
01191 sidModeNormalTable[3] = &sidEmu::sidMode30;
01192 sidModeNormalTable[6] = &sidEmu::sidMode60;
01193 sidModeNormalTable[7] = &sidEmu::sidMode00;
01194 sidModeRingTable[7] = &sidEmu::sidMode00;
01195 }
01196
01197 #if defined(LARGE_NOISE_TABLE)
01198 udword ni;
01199 for (ni = 0; ni < sizeof(noiseTableLSB); ni++)
01200 {
01201 noiseTableLSB[ni] = (ubyte)
01202 (((ni >> (13-4)) & 0x10) |
01203 ((ni >> (11-3)) & 0x08) |
01204 ((ni >> (7-2)) & 0x04) |
01205 ((ni >> (4-1)) & 0x02) |
01206 ((ni >> (2-0)) & 0x01));
01207 }
01208 for (ni = 0; ni < sizeof(noiseTableMSB); ni++)
01209 {
01210 noiseTableMSB[ni] = (ubyte)
01211 (((ni << (7-(22-16))) & 0x80) |
01212 ((ni << (6-(20-16))) & 0x40) |
01213 ((ni << (5-(16-16))) & 0x20));
01214 }
01215 #else
01216 udword ni;
01217 for (ni = 0; ni < sizeof(noiseTableLSB); ni++)
01218 {
01219 noiseTableLSB[ni] = (ubyte)
01220 (((ni >> (7-2)) & 0x04) |
01221 ((ni >> (4-1)) & 0x02) |
01222 ((ni >> (2-0)) & 0x01));
01223 }
01224 for (ni = 0; ni < sizeof(noiseTableMID); ni++)
01225 {
01226 noiseTableMID[ni] = (ubyte)
01227 (((ni >> (13-8-4)) & 0x10) |
01228 ((ni << (3-(11-8))) & 0x08));
01229 }
01230 for (ni = 0; ni < sizeof(noiseTableMSB); ni++)
01231 {
01232 noiseTableMSB[ni] = (ubyte)
01233 (((ni << (7-(22-16))) & 0x80) |
01234 ((ni << (6-(20-16))) & 0x40) |
01235 ((ni << (5-(16-16))) & 0x20));
01236 }
01237 #endif
01238 }
01239
01240
01241 void sidEmu::sidEmuConfigure(const struct emuConfig& aEmuConfig)
01242 {
01243 sidEmuSetClockSpeed(aEmuConfig.clockSpeed);
01244
01245 PCMfreq = aEmuConfig.frequency;
01246
01247
01248
01249
01250 PCMsid = (udword)(aEmuConfig.frequency * (16777216 / C64_clockSpeed));
01251 PCMsidNoise = (udword)((C64_clockSpeed*256) / aEmuConfig.frequency);
01252
01253 sidEmuChangeReplayingSpeed();
01254 iTheSampler->sampleEmuInit(this);
01255
01256 filterEnabled = aEmuConfig.emulateFilter;
01257 initWaveformTables(aEmuConfig.mos8580);
01258
01259 iTheEnvelope->enveEmuInit(PCMfreq, aEmuConfig.measuredVolume);
01260 }
01261
01262
01263
01264
01265 bool sidEmu::sidEmuReset()
01266 {
01267 clearSidOperator( &optr1 );
01268 iTheEnvelope->enveEmuResetOperator( &optr1 );
01269 clearSidOperator( &optr2 );
01270 iTheEnvelope->enveEmuResetOperator( &optr2 );
01271 clearSidOperator( &optr3 );
01272 iTheEnvelope->enveEmuResetOperator( &optr3 );
01273
01274 optr1.modulator = &optr3;
01275 optr3.carrier = &optr1;
01276 optr1.filtVoiceMask = 1;
01277
01278 optr2.modulator = &optr1;
01279 optr1.carrier = &optr2;
01280 optr2.filtVoiceMask = 2;
01281
01282 optr3.modulator = &optr2;
01283 optr2.carrier = &optr3;
01284 optr3.filtVoiceMask = 4;
01285
01286
01287
01288 iThe6510->sidKeysOff[4] =
01289 (iThe6510->sidKeysOff[4+7] =
01290 (iThe6510->sidKeysOff[4+14] = false));
01291 iThe6510->sidKeysOn[4] =
01292 (iThe6510->sidKeysOn[4+7] =
01293 (iThe6510->sidKeysOn[4+14] = false));
01294
01295 iTheSampler->sampleEmuReset(this);
01296
01297 filterType = (filterCurType = 0);
01298 filterValue = 0;
01299 filterDy = (filterResDy = 0);
01300
01301 toFill = 0;
01302 #if defined(SIDEMU_TIME_COUNT)
01303 prevBufferLen = (scaledBufferLen = 0);
01304 #endif
01305
01306 return true;
01307 }
01308
01309
01310 void sidEmu::clearSidOperator( struct sidOperator* pVoice )
01311 {
01312 pVoice->SIDfreq = 0;
01313 pVoice->SIDctrl = 0;
01314 pVoice->SIDAD = 0;
01315 pVoice->SIDSR = 0;
01316
01317 pVoice->sync = false;
01318
01319 pVoice->pulseIndex = (pVoice->newPulseIndex = (pVoice->SIDpulseWidth = 0));
01320 pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0);
01321
01322 pVoice->output = (pVoice->noiseOutput = 0);
01323 pVoice->filtIO = 0;
01324
01325 pVoice->filtEnabled = false;
01326 pVoice->filtLow = (pVoice->filtRef = 0);
01327
01328 pVoice->cycleLenCount = 0;
01329 #if defined(DIRECT_FIXPOINT)
01330 pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0);
01331 #else
01332 pVoice->cycleLen = (pVoice->cycleLenPnt = 0);
01333 pVoice->cycleAddLenPnt = 0;
01334 #endif
01335
01336 pVoice->outProc = &sidEmu::waveCalcMute;
01337
01338 #if defined(DIRECT_FIXPOINT)
01339 pVoice->waveStepAdd.l = (pVoice->waveStep.l = 0);
01340 pVoice->wavePre[0].len = (uword)(pVoice->wavePre[0].stp = 0);
01341 pVoice->wavePre[1].len = (uword)(pVoice->wavePre[1].stp = 0);
01342 #else
01343 pVoice->waveStep = 0;
01344 pVoice->waveStepAdd = 0;
01345 pVoice->waveStepPnt = 0;
01346 pVoice->waveStepAddPnt = 0;
01347 pVoice->wavePre[0].len = 0;
01348 pVoice->wavePre[0].stp = 0;
01349 pVoice->wavePre[0].pnt = 0;
01350 pVoice->wavePre[1].len = 0;
01351 pVoice->wavePre[1].stp = 0;
01352 pVoice->wavePre[1].pnt = 0;
01353 #endif
01354 pVoice->waveStepOld = 0;
01355
01356 #if defined(DIRECT_FIXPOINT)
01357 pVoice->noiseReg.l = noiseSeed;
01358 #else
01359 pVoice->noiseReg = noiseSeed;
01360 #endif
01361 pVoice->noiseStepAdd = (pVoice->noiseStep = 0);
01362 pVoice->noiseIsLocked = false;
01363 }
01364
01365
01366 void sidEmu::sidEmuResetAutoPanning(int autoPanning)
01367 {
01368 doAutoPanning = (autoPanning!=SIDEMU_NONE);
01369 updateAutoPanning = false;
01370 apCount = 0;
01371
01372 if (doAutoPanning)
01373 {
01374 optr1.gainLeft = (optr1.gainSource = 0xa080);
01375 optr1.gainRight = (optr1.gainDest = 0x2080);
01376 optr1.gainDirec = (optr1.gainLeft > optr1.gainRight);
01377 optr1.gainLeftCentered = 0x8080;
01378 optr1.gainRightCentered = 0x7f80;
01379
01380 optr2.gainLeft = (optr2.gainSource = 0x2080);
01381 optr2.gainRight = (optr2.gainDest = 0xa080);
01382 optr2.gainDirec = (optr2.gainLeft > optr2.gainRight);
01383 optr2.gainLeftCentered = 0x8080;
01384 optr2.gainRightCentered = 0x7f80;
01385
01386 optr3.gainLeft = (optr3.gainSource = 0xa080);
01387 optr3.gainRight = (optr3.gainDest = 0x2080);
01388 optr3.gainDirec = (optr3.gainLeft > optr3.gainRight);
01389 optr3.gainLeftCentered = 0x8080;
01390 optr3.gainRightCentered = 0x7f80;
01391
01392 voice4_gainLeft = 0x8080;
01393 voice4_gainRight = 0x7f80;
01394 }
01395 }
01396
01397
01398 void sidEmu::sidEmuSetVoiceVolume(int voice, uword leftLevel, uword rightLevel, uword total)
01399 {
01400 leftLevel *= total;
01401 leftLevel >>= 8;
01402 rightLevel *= total;
01403 rightLevel >>= 8;
01404 uword centeredLeftLevel = (0x80*total)>>8;
01405 uword centeredRightLevel = (0x7f*total)>>8;
01406
01407
01408
01409 uword leftIndex = 0x0080 + (leftLevel<<8);
01410 uword rightIndex = 0x0080 + (rightLevel<<8);
01411 uword gainLeftCentered = 0x0080 + (centeredLeftLevel<<8);
01412 uword gainRightCentered = 0x0080 + (centeredRightLevel<<8);
01413 switch ( voice )
01414 {
01415 case 1:
01416 {
01417 optr1.gainLeft = leftIndex;
01418 optr1.gainRight = rightIndex;
01419
01420 optr1.gainSource = leftIndex;
01421 optr1.gainDest = rightIndex;
01422 optr1.gainLeftCentered = gainLeftCentered;
01423 optr1.gainRightCentered = gainRightCentered;
01424 optr1.gainDirec = (optr1.gainLeft > optr1.gainDest);
01425 break;
01426 }
01427 case 2:
01428 {
01429 optr2.gainLeft = leftIndex;
01430 optr2.gainRight = rightIndex;
01431
01432 optr2.gainSource = leftIndex;
01433 optr2.gainDest = rightIndex;
01434 optr2.gainLeftCentered = gainLeftCentered;
01435 optr2.gainRightCentered = gainRightCentered;
01436 optr2.gainDirec = (optr2.gainLeft > optr2.gainDest);
01437 break;
01438 }
01439 case 3:
01440 {
01441 optr3.gainLeft = leftIndex;
01442 optr3.gainRight = rightIndex;
01443
01444 optr3.gainSource = leftIndex;
01445 optr3.gainDest = rightIndex;
01446 optr3.gainLeftCentered = gainLeftCentered;
01447 optr3.gainRightCentered = gainRightCentered;
01448 optr3.gainDirec = (optr3.gainLeft > optr3.gainDest);
01449 break;
01450 }
01451 case 4:
01452 {
01453 voice4_gainLeft = leftIndex;
01454 voice4_gainRight = rightIndex;
01455 break;
01456 }
01457 default:
01458 {
01459 break;
01460 }
01461 }
01462 }
01463
01464
01465 uword sidEmu::sidEmuReturnVoiceVolume( int voice )
01466 {
01467 uword left = 0;
01468 uword right = 0;
01469 switch ( voice )
01470 {
01471 case 1:
01472 {
01473 left = optr1.gainLeft;
01474 right = optr1.gainRight;
01475 break;
01476 }
01477 case 2:
01478 {
01479 left = optr2.gainLeft;
01480 right = optr2.gainRight;
01481 break;
01482 }
01483 case 3:
01484 {
01485 left = optr3.gainLeft;
01486 right = optr3.gainRight;
01487 break;
01488 }
01489 case 4:
01490 {
01491 left = voice4_gainLeft;
01492 right = voice4_gainRight;
01493 break;
01494 }
01495 default:
01496 {
01497 break;
01498 }
01499 }
01500 return (uword)(left&0xff00)|(right>>8);
01501 }
01502
01503
01504 sidEmu::sidEmu(emuEngine* aEmuEngine)
01508 :calls(50)
01509 ,fastForwardFactor(128)
01510 ,sidtuneClockSpeed(985248)
01511 ,C64_clockSpeed(985248)
01512 ,filterEnabled(true)
01513 ,filterType(0)
01514 ,filterCurType(0)
01515 ,iTheEmuEngine(aEmuEngine)
01516 {
01517 CTOR(sidEmu);
01518
01519 triangleTable = new ubyte[4096];
01520 sawtoothTable = new ubyte[4096];
01521 squareTable = new ubyte[2*4096];
01522
01523 #ifdef LESS_CODE_BUT_ABIT_SLOWER
01524 waveform50 = new ubyte[1*4096];
01525 #else
01526 waveform50 = new ubyte[2*4096];
01527 #endif
01528
01529 #if defined(LARGE_NOISE_TABLE)
01530 noiseTableMSB = new ubyte[1<<8];
01531 noiseTableLSB = new ubyte[1L<<16];
01532 #else
01533 noiseTableMSB = new ubyte[1<<8];
01534 noiseTableMID = new ubyte[1<<8];
01535 noiseTableLSB = new ubyte[1<<8];
01536 #endif
01537
01538
01539 sidModeNormalTable[0] = &sidEmu::sidMode00;
01540 sidModeNormalTable[1] = &sidEmu::sidMode10;
01541 sidModeNormalTable[2] = &sidEmu::sidMode20;
01542 sidModeNormalTable[3] = &sidEmu::sidMode30;
01543 sidModeNormalTable[4] = &sidEmu::sidMode40;
01544 sidModeNormalTable[5] = &sidEmu::sidMode50;
01545 sidModeNormalTable[6] = &sidEmu::sidMode60;
01546 sidModeNormalTable[7] = &sidEmu::sidMode70;
01547 sidModeNormalTable[8] = &sidEmu::sidMode80;
01548 sidModeNormalTable[9] = &sidEmu::sidModeLock;
01549 sidModeNormalTable[10] = &sidEmu::sidModeLock;
01550 sidModeNormalTable[11] = &sidEmu::sidModeLock;
01551 sidModeNormalTable[12] = &sidEmu::sidModeLock;
01552 sidModeNormalTable[13] = &sidEmu::sidModeLock;
01553 sidModeNormalTable[14] = &sidEmu::sidModeLock;
01554 sidModeNormalTable[15] = &sidEmu::sidModeLock;
01555
01556
01557 sidModeRingTable[0] = &sidEmu::sidMode00;
01558 sidModeRingTable[1] = &sidEmu::sidMode14;
01559 sidModeRingTable[2] = &sidEmu::sidMode00;
01560 sidModeRingTable[3] = &sidEmu::sidMode34;
01561 sidModeRingTable[4] = &sidEmu::sidMode00;
01562 sidModeRingTable[5] = &sidEmu::sidMode54;
01563 sidModeRingTable[6] = &sidEmu::sidMode00;
01564 sidModeRingTable[7] = &sidEmu::sidMode74;
01565 sidModeRingTable[8] = &sidEmu::sidModeLock;
01566 sidModeRingTable[9] = &sidEmu::sidModeLock;
01567 sidModeRingTable[10] = &sidEmu::sidModeLock;
01568 sidModeRingTable[11] = &sidEmu::sidModeLock;
01569 sidModeRingTable[12] = &sidEmu::sidModeLock;
01570 sidModeRingTable[13] = &sidEmu::sidModeLock;
01571 sidModeRingTable[14] = &sidEmu::sidModeLock;
01572 sidModeRingTable[15] = &sidEmu::sidModeLock;
01573
01574 iTheEnvelope = new Envelope();
01575 iTheSampler = new Sample(aEmuEngine->iThe6510);
01576
01577
01578 memset(&optr1, sizeof(sidOperator), 0);
01579 memset(&optr2, sizeof(sidOperator), 0);
01580 memset(&optr3, sizeof(sidOperator), 0);
01581
01582 iThe6510 = aEmuEngine->iThe6510;
01583 c64mem1 = iThe6510->c64mem1;
01584 c64mem2 = iThe6510->c64mem2;
01585
01586 }
01587
01588
01589 sidEmu::~sidEmu()
01593 {
01594 DTOR(sidEmu);
01595
01596 delete triangleTable;
01597 delete sawtoothTable;
01598 delete squareTable;
01599
01600 delete waveform50;
01601
01602 #if defined(LARGE_NOISE_TABLE)
01603 delete noiseTableMSB;
01604 delete noiseTableLSB;
01605 #else
01606 delete noiseTableMSB;
01607 delete noiseTableMID;
01608 delete noiseTableLSB;
01609 #endif
01610
01611 delete iTheEnvelope;
01612 delete iTheSampler;
01613
01614 }
01615
01616