summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/sound/sidvoice.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/sound/sidvoice.c')
-rw-r--r--trunk/src/emu/sound/sidvoice.c809
1 files changed, 809 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/sidvoice.c b/trunk/src/emu/sound/sidvoice.c
new file mode 100644
index 00000000000..59da4ed3ba6
--- /dev/null
+++ b/trunk/src/emu/sound/sidvoice.c
@@ -0,0 +1,809 @@
+#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(SIDTYPE 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==MOS8580 )
+ {
+ 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==MOS8580 )
+ {
+ 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
+ }
+}
+