// license:BSD-3-Clause // copyright-holders:Peter Trauner #include "emu.h" #include "sidvoice.h" #include "sid.h" #include "sidenvel.h" #include "sidw6581.h" #include "sidw8580.h" static UINT8 triangleTable[4096]; static UINT8 sawtoothTable[4096]; static UINT8 squareTable[2*4096]; static const UINT8* waveform30; static const UINT8* waveform50; static const UINT8* waveform60; static const UINT8* waveform70; #if defined(LARGE_NOISE_TABLE) static UINT8 noiseTableMSB[1<<8]; static UINT8 noiseTableLSB[1L<<16]; #else static UINT8 noiseTableMSB[1<<8]; static UINT8 noiseTableMID[1<<8]; static UINT8 noiseTableLSB[1<<8]; #endif static INT8* ampMod1x8; static const UINT32 noiseSeed = 0x7ffff8; void sidInitMixerEngine(running_machine &machine) { UINT16 uk; INT32 si, sj ; /* 8-bit volume modulation tables. */ float filterAmpl = 0.7f; ampMod1x8=auto_alloc_array(machine, INT8, 256*256); uk = 0; for ( si = 0; si < 256; si++ ) { for ( sj = -128; sj < 128; sj++, uk++ ) { ampMod1x8[uk] = (INT8)(((si*sj)/255)*filterAmpl); } } } INLINE void waveAdvance(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) pVoice->waveStep.l += pVoice->waveStepAdd.l; pVoice->waveStep.w[HI] &= 4095; #else pVoice->waveStepPnt += pVoice->waveStepAddPnt; pVoice->waveStep += pVoice->waveStepAdd; if (pVoice->waveStepPnt > 65535 ) pVoice->waveStep++; pVoice->waveStepPnt &= 0xFFFF; pVoice->waveStep &= 4095; #endif } INLINE void noiseAdvance(sidOperator* pVoice) { pVoice->noiseStep += pVoice->noiseStepAdd; if (pVoice->noiseStep >= (1L<<20)) { pVoice->noiseStep -= (1L<<20); #if defined(DIRECT_FIXPOINT) pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) | (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1); #else pVoice->noiseReg = (pVoice->noiseReg << 1) | (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1); #endif #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE) pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]] |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]); #elif defined(DIRECT_FIXPOINT) pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]] |noiseTableMID[pVoice->noiseReg.b[LOHI]] |noiseTableMSB[pVoice->noiseReg.b[HILO]]); #else pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff] |noiseTableMID[pVoice->noiseReg>>8&0xff] |noiseTableMSB[pVoice->noiseReg>>16&0xff]); #endif } } INLINE void noiseAdvanceHp(sidOperator* pVoice) { UINT32 tmp = pVoice->noiseStepAdd; while (tmp >= (1L<<20)) { tmp -= (1L<<20); #if defined(DIRECT_FIXPOINT) pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) | (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1); #else pVoice->noiseReg = (pVoice->noiseReg << 1) | (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1); #endif } pVoice->noiseStep += tmp; if (pVoice->noiseStep >= (1L<<20)) { pVoice->noiseStep -= (1L<<20); #if defined(DIRECT_FIXPOINT) pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) | (((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1); #else pVoice->noiseReg = (pVoice->noiseReg << 1) | (((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1); #endif } #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE) pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]] |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]); #elif defined(DIRECT_FIXPOINT) pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]] |noiseTableMID[pVoice->noiseReg.b[LOHI]] |noiseTableMSB[pVoice->noiseReg.b[HILO]]); #else pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff] |noiseTableMID[pVoice->noiseReg>>8&0xff] |noiseTableMSB[pVoice->noiseReg>>16&0xff]); #endif } #if defined(DIRECT_FIXPOINT) #define triangle triangleTable[pVoice->waveStep.w[HI]] #define sawtooth sawtoothTable[pVoice->waveStep.w[HI]] #define square squareTable[pVoice->waveStep.w[HI] + pVoice->pulseIndex] #define triSaw waveform30[pVoice->waveStep.w[HI]] #define triSquare waveform50[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth] #define sawSquare waveform60[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth] #define triSawSquare waveform70[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth] #else #define triangle triangleTable[pVoice->waveStep] #define sawtooth sawtoothTable[pVoice->waveStep] #define square squareTable[pVoice->waveStep + pVoice->pulseIndex] #define triSaw waveform30[pVoice->waveStep] #define triSquare waveform50[pVoice->waveStep + pVoice->SIDpulseWidth] #define sawSquare waveform60[pVoice->waveStep + pVoice->SIDpulseWidth] #define triSawSquare waveform70[pVoice->waveStep + pVoice->SIDpulseWidth] #endif static void sidMode00(sidOperator* pVoice) { pVoice->output = (pVoice->filtIO-0x80); waveAdvance(pVoice); } #if 0 /* not used */ static void sidModeReal00(sidOperator* pVoice) { pVoice->output = 0; waveAdvance(pVoice); } #endif static void sidMode10(sidOperator* pVoice) { pVoice->output = triangle; waveAdvance(pVoice); } static void sidMode20(sidOperator* pVoice) { pVoice->output = sawtooth; waveAdvance(pVoice); } static void sidMode30(sidOperator* pVoice) { pVoice->output = triSaw; waveAdvance(pVoice); } static void sidMode40(sidOperator* pVoice) { pVoice->output = square; waveAdvance(pVoice); } static void sidMode50(sidOperator* pVoice) { pVoice->output = triSquare; waveAdvance(pVoice); } static void sidMode60(sidOperator* pVoice) { pVoice->output = sawSquare; waveAdvance(pVoice); } static void sidMode70(sidOperator* pVoice) { pVoice->output = triSawSquare; waveAdvance(pVoice); } static void sidMode80(sidOperator* pVoice) { pVoice->output = pVoice->noiseOutput; waveAdvance(pVoice); noiseAdvance(pVoice); } static void sidMode80hp(sidOperator* pVoice) { pVoice->output = pVoice->noiseOutput; waveAdvance(pVoice); noiseAdvanceHp(pVoice); } static void sidModeLock(sidOperator* pVoice) { pVoice->noiseIsLocked = TRUE; pVoice->output = (pVoice->filtIO-0x80); waveAdvance(pVoice); } /* */ /* */ /* */ static void sidMode14(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) if ( pVoice->modulator->waveStep.w[HI] < 2048 ) #else if ( pVoice->modulator->waveStep < 2048 ) #endif pVoice->output = triangle; else pVoice->output = 0xFF ^ triangle; waveAdvance(pVoice); } static void sidMode34(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) if ( pVoice->modulator->waveStep.w[HI] < 2048 ) #else if ( pVoice->modulator->waveStep < 2048 ) #endif pVoice->output = triSaw; else pVoice->output = 0xFF ^ triSaw; waveAdvance(pVoice); } static void sidMode54(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) if ( pVoice->modulator->waveStep.w[HI] < 2048 ) #else if ( pVoice->modulator->waveStep < 2048 ) #endif pVoice->output = triSquare; else pVoice->output = 0xFF ^ triSquare; waveAdvance(pVoice); } static void sidMode74(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) if ( pVoice->modulator->waveStep.w[HI] < 2048 ) #else if ( pVoice->modulator->waveStep < 2048 ) #endif pVoice->output = triSawSquare; else pVoice->output = 0xFF ^ triSawSquare; waveAdvance(pVoice); } /* */ /* */ /* */ INLINE void waveCalcCycleLen(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) pVoice->cycleAddLen.w[HI] = 0; pVoice->cycleAddLen.l += pVoice->cycleLen.l; pVoice->cycleLenCount = pVoice->cycleAddLen.w[HI]; #else pVoice->cycleAddLenPnt += pVoice->cycleLenPnt; pVoice->cycleLenCount = pVoice->cycleLen; if ( pVoice->cycleAddLenPnt > 65535 ) pVoice->cycleLenCount++; pVoice->cycleAddLenPnt &= 0xFFFF; #endif /* If we keep the value cycleLen between 1 <= x <= 65535, */ /* the following check is not required. */ /* if ( pVoice->cycleLenCount == 0 ) */ /* { */ /*#if defined(DIRECT_FIXPOINT) */ /* pVoice->waveStep.l = 0; */ /*#else */ /* pVoice->waveStep = (pVoice->waveStepPnt = 0); */ /*#endif */ /* pVoice->cycleLenCount = 0; */ /* } */ /* else */ { #if defined(DIRECT_FIXPOINT) register UINT16 diff = pVoice->cycleLenCount - pVoice->cycleLen.w[HI]; #else register UINT16 diff = pVoice->cycleLenCount - pVoice->cycleLen; #endif if ( pVoice->wavePre[diff].len != pVoice->cycleLenCount ) { pVoice->wavePre[diff].len = pVoice->cycleLenCount; #if defined(DIRECT_FIXPOINT) pVoice->wavePre[diff].stp = (pVoice->waveStepAdd.l = (4096UL*65536UL) / pVoice->cycleLenCount); #else pVoice->wavePre[diff].stp = (pVoice->waveStepAdd = 4096UL / pVoice->cycleLenCount); pVoice->wavePre[diff].pnt = (pVoice->waveStepAddPnt = ((4096UL % pVoice->cycleLenCount) * 65536UL) / pVoice->cycleLenCount); #endif } else { #if defined(DIRECT_FIXPOINT) pVoice->waveStepAdd.l = pVoice->wavePre[diff].stp; #else pVoice->waveStepAdd = pVoice->wavePre[diff].stp; pVoice->waveStepAddPnt = pVoice->wavePre[diff].pnt; #endif } } /* see above (opening bracket) */ } INLINE void waveCalcFilter(sidOperator* pVoice) { if ( pVoice->filtEnabled ) { if ( pVoice->sid->filter.Type != 0 ) { if ( pVoice->sid->filter.Type == 0x20 ) { float tmp; pVoice->filtLow += ( pVoice->filtRef * pVoice->sid->filter.Dy ); tmp = (float)pVoice->filtIO - pVoice->filtLow; tmp -= pVoice->filtRef * pVoice->sid->filter.ResDy; pVoice->filtRef += ( tmp * (pVoice->sid->filter.Dy) ); pVoice->filtIO = (INT8)(pVoice->filtRef-pVoice->filtLow/4); } else if (pVoice->sid->filter.Type == 0x40) { float tmp, tmp2; pVoice->filtLow += ( pVoice->filtRef * pVoice->sid->filter.Dy * 0.1 ); tmp = (float)pVoice->filtIO - pVoice->filtLow; tmp -= pVoice->filtRef * pVoice->sid->filter.ResDy; pVoice->filtRef += ( tmp * (pVoice->sid->filter.Dy) ); tmp2 = pVoice->filtRef - pVoice->filtIO/8; if (tmp2 < -128) tmp2 = -128; if (tmp2 > 127) tmp2 = 127; pVoice->filtIO = (INT8)tmp2; } else { float sample, sample2; int tmp; pVoice->filtLow += ( pVoice->filtRef * pVoice->sid->filter.Dy ); sample = pVoice->filtIO; sample2 = sample - pVoice->filtLow; tmp = (int)sample2; sample2 -= pVoice->filtRef * pVoice->sid->filter.ResDy; pVoice->filtRef += ( sample2 * pVoice->sid->filter.Dy ); if ( pVoice->sid->filter.Type == 0x10 ) { pVoice->filtIO = (INT8)pVoice->filtLow; } else if ( pVoice->sid->filter.Type == 0x30 ) { pVoice->filtIO = (INT8)pVoice->filtLow; } else if ( pVoice->sid->filter.Type == 0x50 ) { pVoice->filtIO = (INT8)(sample - (tmp >> 1)); } else if ( pVoice->sid->filter.Type == 0x60 ) { pVoice->filtIO = (INT8)tmp; } else if ( pVoice->sid->filter.Type == 0x70 ) { pVoice->filtIO = (INT8)(sample - (tmp >> 1)); } } } else /* pVoice->sid->filter.Type == 0x00 */ { pVoice->filtIO = 0; } } } static INT8 waveCalcMute(sidOperator* pVoice) { (*pVoice->ADSRproc)(pVoice); /* just process envelope */ return pVoice->filtIO;//&pVoice->outputMask; } INT8 sidWaveCalcNormal(sidOperator* pVoice) { if ( pVoice->cycleLenCount <= 0 ) { waveCalcCycleLen(pVoice); if (( pVoice->SIDctrl & 0x40 ) == 0x40 ) { pVoice->pulseIndex = pVoice->newPulseIndex; if ( pVoice->pulseIndex > 2048 ) { #if defined(DIRECT_FIXPOINT) pVoice->waveStep.w[HI] = 0; #else pVoice->waveStep = 0; #endif } } } (*pVoice->waveProc)(pVoice); pVoice->filtIO = ampMod1x8[(*pVoice->ADSRproc)(pVoice)|pVoice->output]; // pVoice->filtIO = pVoice->sid->masterVolume; // test for digi sound waveCalcFilter(pVoice); return pVoice->filtIO;//&pVoice->outputMask; } static INT8 waveCalcRangeCheck(sidOperator* pVoice) { #if defined(DIRECT_FIXPOINT) pVoice->waveStepOld = pVoice->waveStep.w[HI]; (*pVoice->waveProc)(pVoice); if (pVoice->waveStep.w[HI] < pVoice->waveStepOld) #else pVoice->waveStepOld = pVoice->waveStep; (*pVoice->waveProc)(pVoice); if (pVoice->waveStep < pVoice->waveStepOld) #endif { /* Next step switch back to normal calculation. */ pVoice->cycleLenCount = 0; pVoice->outProc = &sidWaveCalcNormal; #if defined(DIRECT_FIXPOINT) pVoice->waveStep.w[HI] = 4095; #else pVoice->waveStep = 4095; #endif } pVoice->filtIO = ampMod1x8[(*pVoice->ADSRproc)(pVoice)|pVoice->output]; waveCalcFilter(pVoice); return pVoice->filtIO;//&pVoice->outputMask; } /* -------------------------------------------------- Operator frame set-up 1 */ void sidEmuSet(sidOperator* pVoice) { UINT8 enveTemp, newWave, oldWave; UINT8 ADtemp; UINT8 SRtemp; UINT8 tmpSusVol; pVoice->SIDfreq = pVoice->reg[0]|(pVoice->reg[1]<<8); pVoice->SIDpulseWidth = (pVoice->reg[2]|(pVoice->reg[3]<<8)) & 0x0FFF; pVoice->newPulseIndex = 4096 - pVoice->SIDpulseWidth; #if defined(DIRECT_FIXPOINT) if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) >= 0x1000) && ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) >= 0x1000) ) { pVoice->pulseIndex = pVoice->newPulseIndex; } else if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) < 0x1000) && ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) < 0x1000) ) { pVoice->pulseIndex = pVoice->newPulseIndex; } #else if ( ((pVoice->waveStep + pVoice->pulseIndex) >= 0x1000) && ((pVoice->waveStep + pVoice->newPulseIndex) >= 0x1000) ) { pVoice->pulseIndex = pVoice->newPulseIndex; } else if ( ((pVoice->waveStep + pVoice->pulseIndex) < 0x1000) && ((pVoice->waveStep + pVoice->newPulseIndex) < 0x1000) ) { pVoice->pulseIndex = pVoice->newPulseIndex; } #endif oldWave = pVoice->SIDctrl; enveTemp = pVoice->ADSRctrl; pVoice->SIDctrl = (newWave = pVoice->reg[4]|(pVoice->reg[5]<<8)); if (( newWave & 1 ) ==0 ) { if (( oldWave & 1 ) !=0 ) enveTemp = ENVE_STARTRELEASE; /* else if ( pVoice->gateOnCtrl ) */ /* { */ /* enveTemp = ENVE_STARTSHORTATTACK; */ /* } */ } else if ( /*pVoice->gateOffCtrl || */((oldWave&1)==0) ) { enveTemp = ENVE_STARTATTACK; } if ((( oldWave ^ newWave ) & 0xF0 ) != 0 ) { pVoice->cycleLenCount = 0; } ADtemp = pVoice->reg[5]; SRtemp = pVoice->reg[6]; if ( pVoice->SIDAD != ADtemp ) { enveTemp |= ENVE_ALTER; } else if ( pVoice->SIDSR != SRtemp ) { enveTemp |= ENVE_ALTER; } pVoice->SIDAD = ADtemp; pVoice->SIDSR = SRtemp; tmpSusVol = masterVolumeLevels[SRtemp >> 4]; if (pVoice->ADSRctrl != ENVE_SUSTAIN) /* !!! */ { pVoice->enveSusVol = tmpSusVol; } else { if ( pVoice->enveSusVol > pVoice->enveVol ) pVoice->enveSusVol = 0; else pVoice->enveSusVol = tmpSusVol; } pVoice->ADSRproc = enveModeTable[enveTemp>>1]; /* shifting out the KEY-bit */ pVoice->ADSRctrl = enveTemp & (255-ENVE_ALTER-1); pVoice->filtEnabled = pVoice->sid->filter.Enabled && ((pVoice->sid->reg[0x17] & pVoice->filtVoiceMask)!=0); } /* -------------------------------------------------- Operator frame set-up 2 */ /* MOS-8580, MOS-6581 (no 70) */ static ptr2sidVoidFunc sidModeNormalTable[16] = { sidMode00, sidMode10, sidMode20, sidMode30, sidMode40, sidMode50, sidMode60, sidMode70, sidMode80, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock }; /* MOS-8580, MOS-6581 (no 74) */ static ptr2sidVoidFunc sidModeRingTable[16] = { sidMode00, sidMode14, sidMode00, sidMode34, sidMode00, sidMode54, sidMode00, sidMode74, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock }; void sidClearOperator( sidOperator* pVoice ) { pVoice->SIDfreq = 0; pVoice->SIDctrl = 0; pVoice->SIDAD = 0; pVoice->SIDSR = 0; pVoice->sync = FALSE; pVoice->pulseIndex = (pVoice->newPulseIndex = (pVoice->SIDpulseWidth = 0)); pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0); pVoice->output = (pVoice->noiseOutput = 0); pVoice->filtIO = 0; pVoice->filtEnabled = FALSE; pVoice->filtLow = (pVoice->filtRef = 0); pVoice->cycleLenCount = 0; #if defined(DIRECT_FIXPOINT) pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0); #else pVoice->cycleLen = (pVoice->cycleLenPnt = 0); pVoice->cycleAddLenPnt = 0; #endif pVoice->outProc = waveCalcMute; #if defined(DIRECT_FIXPOINT) pVoice->waveStepAdd.l = (pVoice->waveStep.l = 0); pVoice->wavePre[0].len = (pVoice->wavePre[0].stp = 0); pVoice->wavePre[1].len = (pVoice->wavePre[1].stp = 0); #else pVoice->waveStepAdd = (pVoice->waveStepAddPnt = 0); pVoice->waveStep = (pVoice->waveStepPnt = 0); pVoice->wavePre[0].len = 0; pVoice->wavePre[0].stp = (pVoice->wavePre[0].pnt = 0); pVoice->wavePre[1].len = 0; pVoice->wavePre[1].stp = (pVoice->wavePre[1].pnt = 0); #endif pVoice->waveStepOld = 0; #if defined(DIRECT_FIXPOINT) pVoice->noiseReg.l = noiseSeed; #else pVoice->noiseReg = noiseSeed; #endif pVoice->noiseStepAdd = (pVoice->noiseStep = 0); pVoice->noiseIsLocked = FALSE; } void sidEmuSet2(sidOperator* pVoice) { pVoice->outProc = &sidWaveCalcNormal; pVoice->sync = FALSE; if ( (pVoice->SIDfreq < 16) || ((pVoice->SIDctrl & 8) != 0) ) // if ( /*(pVoice->SIDfreq < 16) || */((pVoice->SIDctrl & 8) != 0) ) { pVoice->outProc = waveCalcMute; if (pVoice->SIDfreq == 0) { #if defined(DIRECT_FIXPOINT) pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0); pVoice->waveStep.l = 0; #else pVoice->cycleLen = (pVoice->cycleLenPnt = 0); pVoice->cycleAddLenPnt = 0; pVoice->waveStep = 0; pVoice->waveStepPnt = 0; #endif pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0); pVoice->noiseStepAdd = 0; pVoice->cycleLenCount = 0; } if ((pVoice->SIDctrl & 8) != 0) { if (pVoice->noiseIsLocked) { pVoice->noiseIsLocked = FALSE; #if defined(DIRECT_FIXPOINT) pVoice->noiseReg.l = noiseSeed; #else pVoice->noiseReg = noiseSeed; #endif } } } else { if ( pVoice->curSIDfreq != pVoice->SIDfreq ) { pVoice->curSIDfreq = pVoice->SIDfreq; /* We keep the value cycleLen between 1 <= x <= 65535. */ /* This makes a range-check in waveCalcCycleLen() unrequired. */ #if defined(DIRECT_FIXPOINT) pVoice->cycleLen.l = ((pVoice->sid->PCMsid << 12) / pVoice->SIDfreq) << 4; if (pVoice->cycleLenCount > 0) { waveCalcCycleLen(pVoice); pVoice->outProc = &waveCalcRangeCheck; } #else pVoice->cycleLen = pVoice->sid->PCMsid / pVoice->SIDfreq; pVoice->cycleLenPnt = (( pVoice->sid->PCMsid % pVoice->SIDfreq ) * 65536UL ) / pVoice->SIDfreq; if (pVoice->cycleLenCount > 0) { waveCalcCycleLen(pVoice); pVoice->outProc = &waveCalcRangeCheck; } #endif } if ((( pVoice->SIDctrl & 0x80 ) == 0x80 ) && ( pVoice->curNoiseFreq != pVoice->SIDfreq )) { pVoice->curNoiseFreq = pVoice->SIDfreq; pVoice->noiseStepAdd = (pVoice->sid->PCMsidNoise * pVoice->SIDfreq) >> 8; if (pVoice->noiseStepAdd >= (1L<<21)) sidModeNormalTable[8] = sidMode80hp; else sidModeNormalTable[8] = sidMode80; } if (( pVoice->SIDctrl & 2 ) != 0 ) { if ( ( pVoice->modulator->SIDfreq == 0 ) || (( pVoice->modulator->SIDctrl & 8 ) != 0 ) ) { ; } else if ( (( pVoice->carrier->SIDctrl & 2 ) != 0 ) && ( pVoice->modulator->SIDfreq >= ( pVoice->SIDfreq << 1 )) ) { ; } else { pVoice->sync = TRUE; } } if ((( pVoice->SIDctrl & 0x14 ) == 0x14 ) && ( pVoice->modulator->SIDfreq != 0 )) pVoice->waveProc = sidModeRingTable[pVoice->SIDctrl >> 4]; else pVoice->waveProc = sidModeNormalTable[pVoice->SIDctrl >> 4]; } } void sidInitWaveformTables(int type) { int i,j; UINT16 k; k = 0; for ( i = 0; i < 256; i++ ) for ( j = 0; j < 8; j++ ) triangleTable[k++] = i; for ( i = 255; i >= 0; i-- ) for ( j = 0; j < 8; j++ ) triangleTable[k++] = i; k = 0; for ( i = 0; i < 256; i++ ) for ( j = 0; j < 16; j++ ) sawtoothTable[k++] = i; k = 0; for ( i = 0; i < 4096; i++ ) squareTable[k++] = 255; //0; my estimation; especial for digi sound for ( i = 0; i < 4096; i++ ) squareTable[k++] = 0; //255; if ( type==mos6581_device::TYPE_8580 ) { waveform30 = waveform30_8580; waveform50 = waveform50_8580; waveform60 = waveform60_8580; waveform70 = waveform70_8580; } else { waveform30 = waveform30_6581; waveform50 = waveform50_6581; waveform60 = waveform60_6581; waveform70 = waveform70_6581; /* really audible? */ } if ( type==mos6581_device::TYPE_8580 ) { sidModeNormalTable[3] = sidMode30; sidModeNormalTable[6] = sidMode60; sidModeNormalTable[7] = sidMode70; sidModeRingTable[7] = sidMode74; } else { sidModeNormalTable[3] = sidMode30; sidModeNormalTable[6] = sidMode60; sidModeNormalTable[7] = sidMode00; /* really audible? */ sidModeRingTable[7] = sidMode00; /* */ } { #if defined(LARGE_NOISE_TABLE) UINT32 ni; for (ni = 0; ni < sizeof(noiseTableLSB); ni++) { noiseTableLSB[ni] = (UINT8) (((ni >> (13-4)) & 0x10) | ((ni >> (11-3)) & 0x08) | ((ni >> (7-2)) & 0x04) | ((ni >> (4-1)) & 0x02) | ((ni >> (2-0)) & 0x01)); } for (ni = 0; ni < sizeof(noiseTableMSB); ni++) { noiseTableMSB[ni] = (UINT8) (((ni << (7-(22-16))) & 0x80) | ((ni << (6-(20-16))) & 0x40) | ((ni << (5-(16-16))) & 0x20)); } #else UINT32 ni; for (ni = 0; ni < sizeof(noiseTableLSB); ni++) { noiseTableLSB[ni] = (UINT8) (((ni >> (7-2)) & 0x04) | ((ni >> (4-1)) & 0x02) | ((ni >> (2-0)) & 0x01)); } for (ni = 0; ni < sizeof(noiseTableMID); ni++) { noiseTableMID[ni] = (UINT8) (((ni >> (13-8-4)) & 0x10) | ((ni << (3-(11-8))) & 0x08)); } for (ni = 0; ni < sizeof(noiseTableMSB); ni++) { noiseTableMSB[ni] = (UINT8) (((ni << (7-(22-16))) & 0x80) | ((ni << (6-(20-16))) & 0x40) | ((ni << (5-(16-16))) & 0x20)); } #endif } }