1 //
2 // /home/ms/source/sidplay/libsidplay/emu/RCS/6581_.cpp,v
3 //
4 // --------------------------------------------------------------------------
5 // Copyright (c) 1994-1997 Michael Schwendt. All rights reserved.
6 //
7 // Contributions:
8 //
9 // Noise generation algorithm is used courtesy of Asger Alstrup Nielsen.
10 // His original publication can be found on the SID home page.
11 //
12 // Noise table optimization proposed by Phillip Wooller. The output of
13 // each table does not differ.
14 //
15 // MOS-8580 R5 combined waveforms recorded by Dennis "Deadman" Lindroos.
16 //
17 //  This program is free software; you can redistribute it and/or modify
18 //  it under the terms of the GNU General Public License as published by
19 //  the Free Software Foundation; either version 2 of the License, or
20 //  (at your option) any later version.
21 //
22 //  This program is distributed in the hope that it will be useful,
23 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
24 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 //  GNU General Public License for more details.
26 //
27 //  You should have received a copy of the GNU General Public License
28 //  along with this program; if not, write to the Free Software
29 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30 //
31 // THIS SOFTWARE  IS PROVIDED  BY THE  AUTHOR ``AS  IS'' AND  ANY EXPRESS OR
32 // IMPLIED  WARRANTIES,  INCLUDING,   BUT  NOT  LIMITED   TO,  THE   IMPLIED
33 // WARRANTIES OF MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR PURPOSE  ARE
34 // DISCLAIMED.  IN NO EVENT SHALL  THE AUTHOR OR CONTRIBUTORS BE LIABLE  FOR
35 // ANY DIRECT,  INDIRECT, INCIDENTAL,  SPECIAL, EXEMPLARY,  OR CONSEQUENTIAL
36 // DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS
37 // OR SERVICES;  LOSS OF  USE, DATA,  OR PROFITS;  OR BUSINESS INTERRUPTION)
38 // HOWEVER  CAUSED  AND  ON  ANY  THEORY  OF LIABILITY, WHETHER IN CONTRACT,
39 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  IN
40 // ANY  WAY  OUT  OF  THE  USE  OF  THIS  SOFTWARE,  EVEN  IF ADVISED OF THE
41 // POSSIBILITY OF SUCH DAMAGE.
42 // --------------------------------------------------------------------------
43 
44 #include "mytypes.h"
45 #include "myendian.h"
46 #include "sidtune.h"
47 #include "6510_.h"
48 #include "emucfg.h"
49 #include "envelope.h"
50 #include "opstruct.h"
51 #include "samples.h"
52 #include "wave6581.h"
53 #include "wave8580.h"
54 
55 extern ubyte masterVolume;
56 extern uword masterVolumeAmplIndex;
57 
58 sbyte* ampMod1x8;
59 
60 sidOperator optr1, optr2, optr3;
61 // Voice 4 does not use a sidOperator structure.
62 uword voice4_gainLeft, voice4_gainRight;
63 
64 static bool doAutoPanning;
65 static bool updateAutoPanning;
66 static uword apCount;
67 static const uword apSpeed = 0x4000;
68 
69 bool filterEnabled = true;
70 filterfloat filterTable[0x800];
71 filterfloat bandPassParam[0x800];
72 filterfloat filterResTable[16];
73 static filterfloat filterDy, filterResDy;
74 #define lowPassParam filterTable
75 static ubyte filterType = 0;
76 static ubyte filterCurType = 0;
77 static uword filterValue;
78 
79 static ubyte triangleTable[4096];
80 static ubyte sawtoothTable[4096];
81 static ubyte squareTable[2*4096];
82 static ubyte* waveform30;
83 static ubyte* waveform50;
84 static ubyte* waveform60;
85 static ubyte* waveform70;
86 #if defined(LARGE_NOISE_TABLE)
87   static ubyte noiseTableMSB[1<<8];
88   static ubyte noiseTableLSB[1L<<16];
89 #else
90   static ubyte noiseTableMSB[1<<8];
91   static ubyte noiseTableMID[1<<8];
92   static ubyte noiseTableLSB[1<<8];
93 #endif
94 
95 static const udword noiseSeed = 0x7ffff8;
96 udword PCMfreq;
97 static udword PCMsid, PCMsidNoise;
98 
99 // Song clock speed (PAL or NTSC). Does not affect pitch.
100 static udword sidtuneClockSpeed = 985248;
101 
102 // Master clock speed. Affects pitch of SID and CIA samples.
103 udword C64_clockSpeed = 985248;
104 static float C64_fClockSpeed = 985248.4;
105 
106 // -------------------------------------------------------------------- Speed
107 
108 static uword calls = 50;               // calls per second (here a default)
109 static uword fastForwardFactor = 128;  // normal speed
110 
111 #if defined(DIRECT_FIXPOINT)
112     cpuLword VALUES, VALUESadd, VALUESorg;
113 #else
114     uword VALUES, VALUESorg;
115     udword VALUESadd, VALUEScomma;
116 #endif
117 
118 static uword defaultTimer, timer;
119 
120 
calcValuesPerCall()121 inline void calcValuesPerCall()
122 {
123 	udword fastForwardFreq = PCMfreq;
124 	if ( fastForwardFactor != 128 )
125 	{
126 		fastForwardFreq = (PCMfreq * fastForwardFactor) >> 7;  // divide by 128
127 	}
128 #if defined(DIRECT_FIXPOINT)
129    	VALUES.l = ( VALUESorg.l = (((fastForwardFreq<<12)/calls)<<4) );
130 	VALUESadd.l = 0;
131 #else
132 	VALUES = (VALUESorg = (fastForwardFreq / calls));
133 	VALUEScomma = ((fastForwardFreq % calls) * 65536UL) / calls;
134 	VALUESadd = 0;
135 #endif
136 }
137 
138 
sidEmuChangeReplayingSpeed()139 static void sidEmuChangeReplayingSpeed()
140 {
141 	calcValuesPerCall();
142 }
143 
144 // PAL: Clock speed: 985248.4 Hz
145 //      CIA 1 Timer A: $4025 (60 Hz)
146 //
147 // NTSC: Clock speed: 1022727.14 Hz
148 //      CIA 1 Timer A: $4295 (60 Hz)
149 
sidEmuSetClockSpeed(int clockMode)150 static void sidEmuSetClockSpeed(int clockMode)
151 {
152 	switch (clockMode)
153 	{
154 	 case SIDTUNE_CLOCK_NTSC:
155 		{
156 			C64_clockSpeed = 1022727;
157 			C64_fClockSpeed = 1022727.14;
158 			break;
159 		}
160 	 case SIDTUNE_CLOCK_PAL:
161 	 default:
162 		{
163 			C64_clockSpeed = 985248;
164 			C64_fClockSpeed = 985248.4;
165 			break;
166 		}
167 	}
168 }
169 
170 
sidEmuSetReplayingSpeed(int clockMode,uword callsPerSec)171 void sidEmuSetReplayingSpeed(int clockMode, uword callsPerSec)
172 {
173 	switch (clockMode)
174 	{
175 	 case SIDTUNE_CLOCK_NTSC:
176 		{
177 			sidtuneClockSpeed = 1022727;
178 			timer = (defaultTimer = 0x4295);
179 			break;
180 		}
181 	 case SIDTUNE_CLOCK_PAL:
182 	 default:
183 		{
184 			sidtuneClockSpeed = 985248;
185 			timer = (defaultTimer = 0x4025);
186 			break;
187 		}
188 	}
189 	switch (callsPerSec)
190 	{
191 	 case SIDTUNE_SPEED_CIA_1A:
192 		{
193 			timer = readLEword(c64mem2+0xdc04);
194 			if (timer < 16)  // prevent overflow
195 			{
196 				timer = defaultTimer;
197 			}
198 			calls = ( ((sidtuneClockSpeed<<1)/timer) +1) >>1;
199 			break;
200 		}
201 	 default:
202 		{
203 			calls = callsPerSec;
204 			break;
205 		}
206 	}
207 	calcValuesPerCall();
208 }
209 
210 
sidEmuUpdateReplayingSpeed()211 static void sidEmuUpdateReplayingSpeed()
212 {
213 	if ( timer != readLEword(c64mem2+0xdc04) )
214 	{
215 		timer = readLEword(c64mem2+0xdc04);
216 		// Prevent overflow
217 		if ( timer < 16 )
218 			timer = defaultTimer;
219 		calls = ( ((sidtuneClockSpeed<<1)/timer) +1) >>1;
220 		calcValuesPerCall();
221 	}
222 }
223 
224 // --------------------------------------------------------------------------
225 
waveAdvance(struct sidOperator * pVoice)226 inline void waveAdvance(struct sidOperator* pVoice)
227 {
228 #if defined(DIRECT_FIXPOINT)
229 	pVoice->waveStep.l += pVoice->waveStepAdd.l;
230 	pVoice->waveStep.w[HI] &= 4095;
231 #else
232 	pVoice->waveStepPnt += pVoice->waveStepAddPnt;
233 	pVoice->waveStep += ( pVoice->waveStepAdd + ( pVoice->waveStepPnt > 65535 ));
234 	pVoice->waveStepPnt &= 0xFFFF;
235 	pVoice->waveStep &= 4095;
236 #endif
237 }
238 
noiseAdvance(sidOperator * pVoice)239 inline void noiseAdvance(sidOperator* pVoice)
240 {
241 	pVoice->noiseStep += pVoice->noiseStepAdd;
242 	if (pVoice->noiseStep >= (1L<<20))
243 	{
244 		pVoice->noiseStep -= (1L<<20);
245 #if defined(DIRECT_FIXPOINT)
246 		pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
247 			(((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
248 #else
249 		pVoice->noiseReg = (pVoice->noiseReg << 1) |
250 			(((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
251 #endif
252 #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE)
253 		pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]]
254 							   |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]);
255 #elif defined(DIRECT_FIXPOINT)
256 		pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]]
257 							   |noiseTableMID[pVoice->noiseReg.b[LOHI]]
258 							   |noiseTableMSB[pVoice->noiseReg.b[HILO]]);
259 #else
260 		pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff]
261 							   |noiseTableMID[pVoice->noiseReg>>8&0xff]
262 							   |noiseTableMSB[pVoice->noiseReg>>16&0xff]);
263 #endif
264 	}
265 }
266 
noiseAdvanceHp(sidOperator * pVoice)267 inline void noiseAdvanceHp(sidOperator* pVoice)
268 {
269 	udword tmp = pVoice->noiseStepAdd;
270 	while (tmp >= (1L<<20))
271 	{
272 		tmp -= (1L<<20);
273 #if defined(DIRECT_FIXPOINT)
274 		pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
275 			(((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
276 #else
277 		pVoice->noiseReg = (pVoice->noiseReg << 1) |
278 			(((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
279 #endif
280 	}
281 	pVoice->noiseStep += tmp;
282 	if (pVoice->noiseStep >= (1L<<20))
283 	{
284 		pVoice->noiseStep -= (1L<<20);
285 #if defined(DIRECT_FIXPOINT)
286 		pVoice->noiseReg.l = (pVoice->noiseReg.l << 1) |
287 			(((pVoice->noiseReg.l >> 22) ^ (pVoice->noiseReg.l >> 17)) & 1);
288 #else
289 		pVoice->noiseReg = (pVoice->noiseReg << 1) |
290 			(((pVoice->noiseReg >> 22) ^ (pVoice->noiseReg >> 17)) & 1);
291 #endif
292 	}
293 #if defined(DIRECT_FIXPOINT) && defined(LARGE_NOISE_TABLE)
294 	pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.w[LO]]
295 						   |noiseTableMSB[pVoice->noiseReg.w[HI]&0xff]);
296 #elif defined(DIRECT_FIXPOINT)
297 	pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg.b[LOLO]]
298 						   |noiseTableMID[pVoice->noiseReg.b[LOHI]]
299 						   |noiseTableMSB[pVoice->noiseReg.b[HILO]]);
300 #else
301 	pVoice->noiseOutput = (noiseTableLSB[pVoice->noiseReg&0xff]
302 						   |noiseTableMID[pVoice->noiseReg>>8&0xff]
303 						   |noiseTableMSB[pVoice->noiseReg>>16&0xff]);
304 #endif
305 }
306 
307 
308 #if defined(DIRECT_FIXPOINT)
309   #define triangle triangleTable[pVoice->waveStep.w[HI]]
310   #define sawtooth sawtoothTable[pVoice->waveStep.w[HI]]
311   #define square squareTable[pVoice->waveStep.w[HI] + pVoice->pulseIndex]
312   #define triSaw waveform30[pVoice->waveStep.w[HI]]
313   #define triSquare waveform50[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
314   #define sawSquare waveform60[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
315   #define triSawSquare waveform70[pVoice->waveStep.w[HI] + pVoice->SIDpulseWidth]
316 #else
317   #define triangle triangleTable[pVoice->waveStep]
318   #define sawtooth sawtoothTable[pVoice->waveStep]
319   #define square squareTable[pVoice->waveStep + pVoice->pulseIndex]
320   #define triSaw waveform30[pVoice->waveStep]
321   #define triSquare waveform50[pVoice->waveStep + pVoice->SIDpulseWidth]
322   #define sawSquare waveform60[pVoice->waveStep + pVoice->SIDpulseWidth]
323   #define triSawSquare waveform70[pVoice->waveStep + pVoice->SIDpulseWidth]
324 #endif
325 
326 
sidMode00(struct sidOperator * pVoice)327 static void sidMode00(struct sidOperator* pVoice)  {
328 	pVoice->output = (pVoice->filtIO-0x80);
329 	waveAdvance(pVoice);
330 }
331 
sidModeReal00(struct sidOperator * pVoice)332 static void sidModeReal00(struct sidOperator* pVoice)  {
333 	pVoice->output = 0;
334 	waveAdvance(pVoice);
335 }
336 
sidMode10(struct sidOperator * pVoice)337 static void sidMode10(struct sidOperator* pVoice)  {
338   pVoice->output = triangle;
339   waveAdvance(pVoice);
340 }
341 
sidMode20(struct sidOperator * pVoice)342 static void sidMode20(struct sidOperator* pVoice)  {
343   pVoice->output = sawtooth;
344   waveAdvance(pVoice);
345 }
346 
sidMode30(struct sidOperator * pVoice)347 static void sidMode30(struct sidOperator* pVoice)  {
348   pVoice->output = triSaw;
349   waveAdvance(pVoice);
350 }
351 
sidMode40(struct sidOperator * pVoice)352 static void sidMode40(struct sidOperator* pVoice)  {
353   pVoice->output = square;
354   waveAdvance(pVoice);
355 }
356 
sidMode50(struct sidOperator * pVoice)357 static void sidMode50(struct sidOperator* pVoice)  {
358   pVoice->output = triSquare;
359   waveAdvance(pVoice);
360 }
361 
sidMode60(struct sidOperator * pVoice)362 static void sidMode60(struct sidOperator* pVoice)  {
363   pVoice->output = sawSquare;
364   waveAdvance(pVoice);
365 }
366 
sidMode70(struct sidOperator * pVoice)367 static void sidMode70(struct sidOperator* pVoice)  {
368   pVoice->output = triSawSquare;
369   waveAdvance(pVoice);
370 }
371 
sidMode80(struct sidOperator * pVoice)372 static void sidMode80(struct sidOperator* pVoice)  {
373   pVoice->output = pVoice->noiseOutput;
374   waveAdvance(pVoice);
375   noiseAdvance(pVoice);
376 }
377 
sidMode80hp(struct sidOperator * pVoice)378 static void sidMode80hp(struct sidOperator* pVoice)  {
379   pVoice->output = pVoice->noiseOutput;
380   waveAdvance(pVoice);
381   noiseAdvanceHp(pVoice);
382 }
383 
sidModeLock(sidOperator * pVoice)384 static void sidModeLock(sidOperator* pVoice)
385 {
386 	pVoice->noiseIsLocked = true;
387 	pVoice->output = (pVoice->filtIO-0x80);
388 	waveAdvance(pVoice);
389 }
390 
391 //
392 //
393 //
394 
sidMode14(struct sidOperator * pVoice)395 static void sidMode14(struct sidOperator* pVoice)
396 {
397 #if defined(DIRECT_FIXPOINT)
398   if ( pVoice->modulator->waveStep.w[HI] < 2048 )
399 #else
400   if ( pVoice->modulator->waveStep < 2048 )
401 #endif
402 	pVoice->output = triangle;
403   else
404 	pVoice->output = 0xFF ^ triangle;
405   waveAdvance(pVoice);
406 }
407 
sidMode34(struct sidOperator * pVoice)408 static void sidMode34(struct sidOperator* pVoice)  {
409 #if defined(DIRECT_FIXPOINT)
410   if ( pVoice->modulator->waveStep.w[HI] < 2048 )
411 #else
412   if ( pVoice->modulator->waveStep < 2048 )
413 #endif
414 	pVoice->output = triSaw;
415   else
416 	pVoice->output = 0xFF ^ triSaw;
417   waveAdvance(pVoice);
418 }
419 
sidMode54(struct sidOperator * pVoice)420 static void sidMode54(struct sidOperator* pVoice)  {
421 #if defined(DIRECT_FIXPOINT)
422   if ( pVoice->modulator->waveStep.w[HI] < 2048 )
423 #else
424   if ( pVoice->modulator->waveStep < 2048 )
425 #endif
426 	pVoice->output = triSquare;
427   else
428     pVoice->output = 0xFF ^ triSquare;
429   waveAdvance(pVoice);
430 }
431 
sidMode74(struct sidOperator * pVoice)432 static void sidMode74(struct sidOperator* pVoice)  {
433 #if defined(DIRECT_FIXPOINT)
434   if ( pVoice->modulator->waveStep.w[HI] < 2048 )
435 #else
436   if ( pVoice->modulator->waveStep < 2048 )
437 #endif
438 	pVoice->output = triSawSquare;
439   else
440     pVoice->output = 0xFF ^ triSawSquare;
441   waveAdvance(pVoice);
442 }
443 
444 //
445 //
446 //
447 
waveCalcCycleLen(struct sidOperator * pVoice)448 inline void waveCalcCycleLen(struct sidOperator* pVoice)
449 {
450 #if defined(DIRECT_FIXPOINT)
451 	pVoice->cycleAddLen.w[HI] = 0;
452 	pVoice->cycleAddLen.l += pVoice->cycleLen.l;
453 	pVoice->cycleLenCount = pVoice->cycleAddLen.w[HI];
454 #else
455 	pVoice->cycleAddLenPnt += pVoice->cycleLenPnt;
456 	pVoice->cycleLenCount = pVoice->cycleLen + ( pVoice->cycleAddLenPnt > 65535 );
457 	pVoice->cycleAddLenPnt &= 0xFFFF;
458 #endif
459 	// If we keep the value cycleLen between 1 <= x <= 65535,
460 	// the following check is not required.
461 //	if ( pVoice->cycleLenCount == 0 )
462 //	{
463 //#if defined(DIRECT_FIXPOINT)
464 //		pVoice->waveStep.l = 0;
465 //#else
466 //		pVoice->waveStep = (pVoice->waveStepPnt = 0);
467 //#endif
468 //		pVoice->cycleLenCount = 0;
469 //	}
470 //	else
471 //	{
472 #if defined(DIRECT_FIXPOINT)
473 		register uword diff = pVoice->cycleLenCount - pVoice->cycleLen.w[HI];
474 #else
475 		register uword diff = pVoice->cycleLenCount - pVoice->cycleLen;
476 #endif
477 		if ( pVoice->wavePre[diff].len != pVoice->cycleLenCount )
478 		{
479 			pVoice->wavePre[diff].len = pVoice->cycleLenCount;
480 #if defined(DIRECT_FIXPOINT)
481 			pVoice->wavePre[diff].stp = (pVoice->waveStepAdd.l = (4096UL*65536UL) / pVoice->cycleLenCount);
482 #else
483 			pVoice->wavePre[diff].stp = (pVoice->waveStepAdd = 4096UL / pVoice->cycleLenCount);
484 			pVoice->wavePre[diff].pnt = (pVoice->waveStepAddPnt = ((4096UL % pVoice->cycleLenCount) * 65536UL) / pVoice->cycleLenCount);
485 #endif
486 		}
487 		else
488 		{
489 #if defined(DIRECT_FIXPOINT)
490 			pVoice->waveStepAdd.l = pVoice->wavePre[diff].stp;
491 #else
492 			pVoice->waveStepAdd = pVoice->wavePre[diff].stp;
493 			pVoice->waveStepAddPnt = pVoice->wavePre[diff].pnt;
494 #endif
495 		}
496 //	}  // see above (opening bracket)
497 }
498 
waveCalcFilter(struct sidOperator * pVoice)499 inline void waveCalcFilter(struct sidOperator* pVoice)
500 {
501 	if ( pVoice->filtEnabled )
502 	{
503 		if ( filterType != 0 )
504 		{
505 			if ( filterType == 0x20 )
506 			{
507 				pVoice->filtLow += ( pVoice->filtRef * filterDy );
508 				filterfloat tmp = (filterfloat)pVoice->filtIO - pVoice->filtLow;
509 				tmp -= pVoice->filtRef * filterResDy;
510 				pVoice->filtRef += ( tmp * (filterDy) );
511 				pVoice->filtIO = (sbyte)(pVoice->filtRef-pVoice->filtLow/4);
512 			}
513 			else if (filterType == 0x40)
514 			{
515 				pVoice->filtLow += ( pVoice->filtRef * filterDy * 0.1 );
516 				filterfloat tmp = (filterfloat)pVoice->filtIO - pVoice->filtLow;
517 				tmp -= pVoice->filtRef * filterResDy;
518 				pVoice->filtRef += ( tmp * (filterDy) );
519 				filterfloat tmp2 = pVoice->filtRef - pVoice->filtIO/8;
520 				if (tmp2 < -128)
521 					tmp2 = -128;
522 				if (tmp2 > 127)
523 					tmp2 = 127;
524 				pVoice->filtIO = (sbyte)tmp2;
525 			}
526 			else
527 			{
528 				pVoice->filtLow += ( pVoice->filtRef * filterDy );
529 				filterfloat sample = pVoice->filtIO;
530 				filterfloat sample2 = sample - pVoice->filtLow;
531 				int tmp = (int)sample2;
532 				sample2 -= pVoice->filtRef * filterResDy;
533 				pVoice->filtRef += ( sample2 * filterDy );
534 
535 				if ( filterType == 0x10 )
536 				{
537 					pVoice->filtIO = (sbyte)pVoice->filtLow;
538 				}
539 				else if ( filterType == 0x30 )
540 				{
541 					pVoice->filtIO = (sbyte)pVoice->filtLow;
542 				}
543 				else if ( filterType == 0x50 )
544 				{
545 					pVoice->filtIO = (sbyte)(sample - (tmp >> 1));
546 				}
547 				else if ( filterType == 0x60 )
548 				{
549 					pVoice->filtIO = (sbyte)tmp;
550 				}
551 				else if ( filterType == 0x70 )
552 				{
553 					pVoice->filtIO = (sbyte)(sample - (tmp >> 1));
554 				}
555 			}
556 		}
557 		else // filterType == 0x00
558 		{
559 			pVoice->filtIO = 0;
560 		}
561 	}
562 }
563 
564 
waveCalcMute(struct sidOperator * pVoice)565 sbyte waveCalcMute(struct sidOperator* pVoice)
566 {
567 	(*pVoice->ADSRproc)(pVoice);  // just process envelope
568 	return pVoice->filtIO&pVoice->outputMask;
569 }
570 
571 
waveCalcNormal(struct sidOperator * pVoice)572 sbyte waveCalcNormal(struct sidOperator* pVoice)
573 {
574 	if ( pVoice->cycleLenCount <= 0 )
575 	{
576 		waveCalcCycleLen(pVoice);
577 		if (( pVoice->SIDctrl & 0x40 ) == 0x40 )
578 		{
579 			pVoice->pulseIndex = pVoice->newPulseIndex;
580 			if ( pVoice->pulseIndex > 2048 )
581 			{
582 #if defined(DIRECT_FIXPOINT)
583 				pVoice->waveStep.w[HI] = 0;
584 #else
585 				pVoice->waveStep = 0;
586 #endif
587 			}
588 		}
589 	}
590 	(*pVoice->waveProc)(pVoice);
591 	pVoice->filtIO = ampMod1x8[(*pVoice->ADSRproc)(pVoice)|pVoice->output];
592 	waveCalcFilter(pVoice);
593 	return pVoice->filtIO&pVoice->outputMask;
594 }
595 
waveCalcRangeCheck(struct sidOperator * pVoice)596 sbyte waveCalcRangeCheck(struct sidOperator* pVoice)
597 {
598 #if defined(DIRECT_FIXPOINT)
599 	pVoice->waveStepOld = pVoice->waveStep.w[HI];
600 	(*pVoice->waveProc)(pVoice);
601 	if (pVoice->waveStep.w[HI] < pVoice->waveStepOld)
602 #else
603 	pVoice->waveStepOld = pVoice->waveStep;
604 	(*pVoice->waveProc)(pVoice);
605 	if (pVoice->waveStep < pVoice->waveStepOld)
606 #endif
607 	{
608 		// Next step switch back to normal calculation.
609 		pVoice->cycleLenCount = 0;
610 		pVoice->outProc = &waveCalcNormal;
611 #if defined(DIRECT_FIXPOINT)
612 				pVoice->waveStep.w[HI] = 4095;
613 #else
614 				pVoice->waveStep = 4095;
615 #endif
616 	}
617 	pVoice->filtIO = ampMod1x8[(*pVoice->ADSRproc)(pVoice)|pVoice->output];
618 	waveCalcFilter(pVoice);
619 	return pVoice->filtIO&pVoice->outputMask;
620 }
621 
622 // -------------------------------------------------- Operator frame set-up 1
623 
sidEmuSet(struct sidOperator * pVoice,uword sidIndex)624 inline void sidEmuSet(struct sidOperator* pVoice, uword sidIndex)
625 {
626 	pVoice->SIDfreq = readLEword(c64mem2+sidIndex);
627 
628 	pVoice->SIDpulseWidth = (readLEword(c64mem2+sidIndex+2) & 0x0FFF);
629 	pVoice->newPulseIndex = 4096 - pVoice->SIDpulseWidth;
630 #if defined(DIRECT_FIXPOINT)
631 	if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) >= 0x1000)
632 		&& ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) >= 0x1000) )
633 	{
634 		pVoice->pulseIndex = pVoice->newPulseIndex;
635 	}
636 	else if ( ((pVoice->waveStep.w[HI] + pVoice->pulseIndex) < 0x1000)
637 		&& ((pVoice->waveStep.w[HI] + pVoice->newPulseIndex) < 0x1000) )
638 	{
639 		pVoice->pulseIndex = pVoice->newPulseIndex;
640 	}
641 #else
642 	if ( ((pVoice->waveStep + pVoice->pulseIndex) >= 0x1000)
643 		&& ((pVoice->waveStep + pVoice->newPulseIndex) >= 0x1000) )
644 	{
645 		pVoice->pulseIndex = pVoice->newPulseIndex;
646 	}
647 	else if ( ((pVoice->waveStep + pVoice->pulseIndex) < 0x1000)
648 		&& ((pVoice->waveStep + pVoice->newPulseIndex) < 0x1000) )
649 	{
650 		pVoice->pulseIndex = pVoice->newPulseIndex;
651 	}
652 #endif
653 
654     ubyte enveTemp, newWave, oldWave;
655 
656 	oldWave = pVoice->SIDctrl;
657 	enveTemp = pVoice->ADSRctrl;
658 	pVoice->SIDctrl = (newWave = c64mem2[sidIndex +4]);
659 
660 	if (( newWave & 1 ) ==0 )
661 	{
662 		if (( oldWave & 1 ) !=0 )
663 			enveTemp = ENVE_STARTRELEASE;
664 //		else if ( pVoice->gateOnCtrl )
665 //		{
666 //			enveTemp = ENVE_STARTSHORTATTACK;
667 //		}
668 	}
669 	else if ( pVoice->gateOffCtrl || ((oldWave&1)==0) )
670 	{
671 		enveTemp = ENVE_STARTATTACK;
672 		if (doAutoPanning && updateAutoPanning)
673 		{
674 			// Swap source/destination position.
675 			uword tmp = pVoice->gainSource;
676 			pVoice->gainSource = pVoice->gainDest;
677 			pVoice->gainDest = tmp;
678 			if ((pVoice->gainDest^pVoice->gainSource) == 0)
679 			{
680 				// Mute voice.
681 				pVoice->gainLeft = (pVoice->gainRight = 0x0000+0x80);
682 			}
683 			else
684 			{
685 				// Start from middle position.
686 				pVoice->gainLeft = pVoice->gainLeftCentered;
687 				pVoice->gainRight = pVoice->gainRightCentered;
688 			}
689 			// Determine direction.
690 			// true  = L > R : L down, R up
691 			// false = L < R : L up, R down
692 			pVoice->gainDirec = (pVoice->gainLeft > pVoice->gainDest);
693 		}
694 	}
695 
696 	if (doAutoPanning && updateAutoPanning && (enveTemp!=ENVE_STARTATTACK))
697 	{
698 		if (pVoice->gainDirec)
699 		{
700 			if (pVoice->gainLeft > pVoice->gainDest)
701 			{
702 				pVoice->gainLeft -= 0x0100;
703 				pVoice->gainRight += 0x0100;
704 			}
705 			else
706 			{
707 				// Swap source/destination position.
708 				uword tmp = pVoice->gainSource;
709 				pVoice->gainSource = pVoice->gainDest;
710 				pVoice->gainDest = tmp;
711 				// Inverse direction.
712 				pVoice->gainDirec = false;
713 			}
714 		}
715 		else
716 		{
717 			if (pVoice->gainRight > pVoice->gainSource)
718 			{
719 				pVoice->gainLeft += 0x0100;
720 				pVoice->gainRight -= 0x0100;
721 			}
722 			else
723 			{
724 				pVoice->gainDirec = true;
725 				// Swap source/destination position.
726 				uword tmp = pVoice->gainSource;
727 				pVoice->gainSource = pVoice->gainDest;
728 				// Inverse direction.
729 				pVoice->gainDest = tmp;
730 			}
731 		}
732 	}
733 
734 	if ((( oldWave ^ newWave ) & 0xF0 ) != 0 )
735 	{
736 		pVoice->cycleLenCount = 0;
737 	}
738 
739 	ubyte ADtemp = c64mem2[sidIndex +5];
740 	ubyte SRtemp = c64mem2[sidIndex +6];
741 	if ( pVoice->SIDAD != ADtemp )
742 	{
743 		enveTemp |= ENVE_ALTER;
744 	}
745 	else if ( pVoice->SIDSR != SRtemp )
746 	{
747 		enveTemp |= ENVE_ALTER;
748 	}
749 	pVoice->SIDAD = ADtemp;
750 	pVoice->SIDSR = SRtemp;
751 	extern const ubyte masterVolumeLevels[16];  // -> envelope.cpp
752 	ubyte tmpSusVol = masterVolumeLevels[SRtemp >> 4];
753 	if (pVoice->ADSRctrl != ENVE_SUSTAIN)  // !!!
754 	{
755 		pVoice->enveSusVol = tmpSusVol;
756 	}
757 	else
758 	{
759 		if ( pVoice->enveSusVol > pVoice->enveVol )
760 			pVoice->enveSusVol = 0;
761 		else
762 			pVoice->enveSusVol = tmpSusVol;
763 	}
764 
765 	extern ptr2sidUwordFunc enveModeTable[];   // -> envelope.cpp
766 	pVoice->ADSRproc = enveModeTable[enveTemp>>1];  // shifting out the KEY-bit
767 	pVoice->ADSRctrl = enveTemp & (255-ENVE_ALTER-1);
768 
769     pVoice->filtEnabled = filterEnabled &&
770         ((c64mem2[0xd417]&pVoice->filtVoiceMask)!=0);
771 }
772 
773 // -------------------------------------------------- Operator frame set-up 2
774 
775 // MOS-8580, MOS-6581 (no 70)
776 static ptr2sidVoidFunc sidModeNormalTable[16] =
777 {
778   sidMode00, sidMode10, sidMode20, sidMode30, sidMode40, sidMode50, sidMode60, sidMode70,
779   sidMode80, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock
780 };
781 
782 // MOS-8580, MOS-6581 (no 74)
783 static ptr2sidVoidFunc sidModeRingTable[16] =
784 {
785   sidMode00, sidMode14, sidMode00, sidMode34, sidMode00, sidMode54, sidMode00, sidMode74,
786   sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock, sidModeLock
787 };
788 
789 
sidEmuSet2(struct sidOperator * pVoice)790 inline void sidEmuSet2(struct sidOperator* pVoice)
791 {
792 	pVoice->outProc = &waveCalcNormal;
793 	pVoice->sync = false;
794 
795 	if ( (pVoice->SIDfreq < 16)
796 		|| ((pVoice->SIDctrl & 8) != 0) )
797 	{
798 		pVoice->outProc = &waveCalcMute;
799 		if (pVoice->SIDfreq == 0)
800 		{
801 #if defined(DIRECT_FIXPOINT)
802 			pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0);
803 			pVoice->waveStep.l = 0;
804 #else
805 			pVoice->cycleLen = (pVoice->cycleLenPnt = 0);
806 			pVoice->cycleAddLenPnt = 0;
807 			pVoice->waveStep = 0;
808 			pVoice->waveStepPnt = 0;
809 #endif
810 			pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0);
811 			pVoice->noiseStepAdd = 0;
812 			pVoice->cycleLenCount = 0;
813 		}
814 		if ((pVoice->SIDctrl & 8) != 0)
815 		{
816 			if (pVoice->noiseIsLocked)
817 			{
818 				pVoice->noiseIsLocked = false;
819 #if defined(DIRECT_FIXPOINT)
820 				pVoice->noiseReg.l = noiseSeed;
821 #else
822 				pVoice->noiseReg = noiseSeed;
823 #endif
824 			}
825 		}
826 	}
827 	else
828 	{
829 		if ( pVoice->curSIDfreq != pVoice->SIDfreq )
830 		{
831 			pVoice->curSIDfreq = pVoice->SIDfreq;
832 			// We keep the value cycleLen between 1 <= x <= 65535.
833 			// This makes a range-check in waveCalcCycleLen() unrequired.
834 #if defined(DIRECT_FIXPOINT)
835 			pVoice->cycleLen.l = ((PCMsid << 12) / pVoice->SIDfreq) << 4;
836 			if (pVoice->cycleLenCount > 0)
837 			{
838 				waveCalcCycleLen(pVoice);
839 				pVoice->outProc = &waveCalcRangeCheck;
840 			}
841 #else
842 			pVoice->cycleLen = PCMsid / pVoice->SIDfreq;
843 			pVoice->cycleLenPnt = (( PCMsid % pVoice->SIDfreq ) * 65536UL ) / pVoice->SIDfreq;
844 			if (pVoice->cycleLenCount > 0)
845 			{
846 				waveCalcCycleLen(pVoice);
847 				pVoice->outProc = &waveCalcRangeCheck;
848 			}
849 #endif
850 		}
851 
852 		if ((( pVoice->SIDctrl & 0x80 ) == 0x80 ) && ( pVoice->curNoiseFreq != pVoice->SIDfreq ))
853 		{
854 			pVoice->curNoiseFreq = pVoice->SIDfreq;
855 			pVoice->noiseStepAdd = (PCMsidNoise * pVoice->SIDfreq) >> 8;
856 			if (pVoice->noiseStepAdd >= (1L<<21))
857 				sidModeNormalTable[8] = sidMode80hp;
858 			else
859 				sidModeNormalTable[8] = sidMode80;
860 		}
861 
862 		if (( pVoice->SIDctrl & 2 ) != 0 )
863 		{
864 			if ( ( pVoice->modulator->SIDfreq == 0 ) || (( pVoice->modulator->SIDctrl & 8 ) != 0 ) )
865 			{
866 				;
867 			}
868 			else if ( (( pVoice->carrier->SIDctrl & 2 ) != 0 ) &&
869 					 ( pVoice->modulator->SIDfreq >= ( pVoice->SIDfreq << 1 )) )
870 			{
871 				;
872 			}
873 			else
874 			{
875 				pVoice->sync = true;
876 			}
877 		}
878 
879 		if ((( pVoice->SIDctrl & 0x14 ) == 0x14 ) && ( pVoice->modulator->SIDfreq != 0 ))
880 			pVoice->waveProc = sidModeRingTable[pVoice->SIDctrl >> 4];
881 		else
882 			pVoice->waveProc = sidModeNormalTable[pVoice->SIDctrl >> 4];
883 	}
884 }
885 
886 // -------------------------------------------------------------- Buffer fill
887 
888 static uword toFill;
889 ubyte bufferScale;
890 ubyte playRamRom;
891 
892 #if defined(SIDEMU_TIME_COUNT)
893 static udword prevBufferLen;    // need for fast_forward time count
894 static udword scaledBufferLen;
895 #endif
896 
897 void* fill8bitMono(void*, udword); // only need one fill()-prototype here
898 void* (*sidEmuFillFunc)(void*, udword) = &fill8bitMono; // default
899 
900 
sidEmuFillBuffer(emuEngine & thisEmu,sidTune & thisTune,void * buffer,udword bufferLen)901 void sidEmuFillBuffer( emuEngine& thisEmu,
902 					   sidTune& thisTune,
903 					   void* buffer, udword bufferLen )
904 {
905 	// Ensure a sane status of the whole emulator.
906 	if ( thisEmu.isReady && thisTune.getStatus() )
907 	{
908 		// Both, 16-bit and stereo samples take more memory.
909 		// Hence fewer samples fit into the buffer.
910 		bufferLen >>= bufferScale;
911 
912 		// Split sample buffer into pieces for # voices:
913 		// splitBufferLen * bytesPerSample * voices = bufferLen
914 		if ( thisEmu.config.volumeControl == SIDEMU_HWMIXING )
915 		{
916 			bufferLen >>= 2; // or /4
917 			extern udword splitBufferLen;
918 			splitBufferLen = bufferLen;
919 		}
920 
921 #if defined(SIDEMU_TIME_COUNT)
922 		if (prevBufferLen != bufferLen)
923 		{
924 			prevBufferLen = bufferLen;
925 			scaledBufferLen = (bufferLen<<7) / fastForwardFactor;
926 		}
927 		thisEmu.bytesCountTotal += bufferLen;
928         thisEmu.bytesCountSong += scaledBufferLen;
929 		while (thisEmu.bytesCountTotal >= thisEmu.config.frequency)
930 		{
931 			thisEmu.bytesCountTotal -= thisEmu.config.frequency;
932 			thisEmu.secondsTotal++;
933 		}
934 		while (thisEmu.bytesCountSong >= thisEmu.config.frequency)
935 		{
936 			thisEmu.bytesCountSong -= thisEmu.config.frequency;
937 			thisEmu.secondsThisSong++;
938 		}
939 #endif
940 
941 		while ( bufferLen > 0 )
942 		{
943 			if ( toFill > bufferLen )
944 			{
945 				buffer = (*sidEmuFillFunc)(buffer, bufferLen);
946 				toFill -= bufferLen;
947 				bufferLen = 0;
948 			}
949 			else if ( toFill > 0 )
950 			{
951 				buffer = (*sidEmuFillFunc)(buffer, toFill);
952 				bufferLen -= toFill;
953 				toFill = 0;
954 			}
955 
956 			if ( toFill == 0 )
957 			{
958 				optr3readWave = optr3.output;
959 				optr3readEnve = optr3.enveVol;
960 
961 				uword replayPC = thisTune.getPlayAddr();
962 				// playRamRom was set by external player interface.
963 				if ( replayPC == 0 )
964 				{
965  					playRamRom = c64mem1[1];
966  					if ((playRamRom & 2) != 0)  // isKernal ?
967  					{
968  						replayPC = readLEword(c64mem1+0x0314);  // IRQ
969  					}
970  					else
971  					{
972  						replayPC = readLEword(c64mem1+0xfffe);  // NMI
973 					}
974 				}
975 				//bool retcode =
976 				interpreter(replayPC, playRamRom, 0, 0, 0);
977 
978 				if (thisTune.getSongSpeed() == SIDTUNE_SPEED_CIA_1A)
979 				{
980 					sidEmuUpdateReplayingSpeed();
981 				}
982 
983 				masterVolume = ( c64mem2[0xd418] & 15 );
984 				masterVolumeAmplIndex = masterVolume << 8;
985 
986 				optr1.gateOnCtrl = sidKeysOn[4];
987 				optr1.gateOffCtrl = sidKeysOff[4];
988 				sidEmuSet( &optr1, 0xd400 );
989 				optr2.gateOnCtrl = sidKeysOn[4+7];
990 				optr2.gateOffCtrl = sidKeysOff[4+7];
991 				sidEmuSet( &optr2, 0xd407 );
992 				optr3.gateOnCtrl = sidKeysOn[4+14];
993 				optr3.gateOffCtrl = sidKeysOff[4+14];
994 				sidEmuSet( &optr3, 0xd40e );
995 
996 				if ((c64mem2[0xd418]&0x80) &&
997                     ((c64mem2[0xd417]&optr3.filtVoiceMask)==0))
998 					optr3.outputMask = 0;     // off
999 				else
1000 					optr3.outputMask = 0xff;  // on
1001 
1002 				filterType = c64mem2[0xd418] & 0x70;
1003 				if (filterType != filterCurType)
1004 				{
1005 					filterCurType = filterType;
1006 					optr1.filtLow = (optr1.filtRef = 0);
1007 					optr2.filtLow = (optr2.filtRef = 0);
1008 					optr3.filtLow = (optr3.filtRef = 0);
1009 				}
1010 				if ( filterEnabled )
1011 				{
1012 					filterValue = 0x7ff & ( (c64mem2[0xd415]&7) | ( (uword)c64mem2[0xd416] << 3 ));
1013 					if (filterType == 0x20)
1014 						filterDy = bandPassParam[filterValue];
1015 					else
1016 						filterDy = lowPassParam[filterValue];
1017 					filterResDy = filterResTable[c64mem2[0xd417] >> 4] - filterDy;
1018 					if ( filterResDy < 1.0 )
1019 						filterResDy = 1.0;
1020 				}
1021 
1022 				sidEmuSet2( &optr1 );
1023 				sidEmuSet2( &optr2 );
1024 				sidEmuSet2( &optr3 );
1025 
1026 				sampleEmuCheckForInit();
1027 
1028 #if defined(DIRECT_FIXPOINT)
1029 				VALUESadd.w[HI] = 0;
1030 				VALUESadd.l += VALUES.l;
1031 				toFill = VALUESadd.w[HI];
1032 #else
1033 				udword temp = (VALUESadd + VALUEScomma);
1034 				VALUESadd = temp & 0xFFFF;
1035 				toFill = VALUES + (temp > 65535);
1036 #endif
1037 
1038 				// Decide whether to update/start auto-panning.
1039 				if ((apCount += timer) >= apSpeed)
1040 				{
1041 					apCount -= apSpeed;
1042 					updateAutoPanning = true;
1043 				}
1044 				else
1045 				{
1046 					updateAutoPanning = false;
1047 				}
1048 
1049 			}
1050 		} // end while bufferLen
1051 	} // end if status
1052 }
1053 
1054 
sidEmuFastForwardReplay(int percent)1055 bool sidEmuFastForwardReplay( int percent )
1056 {
1057 	if (( percent < 1 ) || ( percent > 100 ))
1058 	{
1059 		return false;
1060 	}
1061 	else
1062 	{
1063 		fastForwardFactor = (percent<<7)/100;  // we use 2^7 as divider
1064 #if defined(SIDEMU_TIME_COUNT)
1065 		scaledBufferLen = (prevBufferLen<<7)/fastForwardFactor;
1066 #endif
1067 		calcValuesPerCall();
1068 		// Ensure that we calculate at least a single sample per player call.
1069 		// Still possible would be also (0 < x < 1.0).
1070 		// Else (x = 0) this would cause a deadlock in the buffer fill loop.
1071 #if defined(DIRECT_FIXPOINT)
1072 		if (VALUES.w[HI] < 1)
1073 		{
1074 			VALUES.l = (VALUESorg.l = 0);
1075 			VALUES.w[HI] = (VALUESorg.w[HI] = 1);
1076 		}
1077 #else
1078 		if (VALUES < 1)
1079 		{
1080 			VALUES = (VALUESorg = 1);
1081 			VALUEScomma = 0;
1082 		}
1083 #endif
1084 		return true;
1085 	}
1086 }
1087 
1088 // --------------------------------------------------------------------- Init
1089 
initWaveformTables(bool isNewSID)1090 void initWaveformTables(bool isNewSID)
1091 {
1092 	int i,j;
1093 	uword k;
1094 
1095 	k = 0;
1096 	for ( i = 0; i < 256; i++ )
1097 		for ( j = 0; j < 8; j++ )
1098 			triangleTable[k++] = i;
1099 	for ( i = 255; i >= 0; i-- )
1100 		for ( j = 0; j < 8; j++ )
1101 			triangleTable[k++] = i;
1102 
1103 	k = 0;
1104 	for ( i = 0; i < 256; i++ )
1105 		for ( j = 0; j < 16; j++ )
1106 			sawtoothTable[k++] = i;
1107 
1108 	k = 0;
1109 	for ( i = 0; i < 4096; i++ )
1110 		squareTable[k++] = 0;
1111 	for ( i = 0; i < 4096; i++ )
1112 		squareTable[k++] = 255;
1113 
1114 	if ( isNewSID )
1115 	{
1116         waveform30 = waveform30_8580;
1117         waveform50 = waveform50_8580;
1118         waveform60 = waveform60_8580;
1119         waveform70 = waveform70_8580;
1120 	}
1121 	else
1122 	{
1123         waveform30 = waveform30_6581;
1124         waveform50 = waveform50_6581;
1125         waveform60 = waveform60_6581;
1126         waveform70 = waveform70_6581;  // really audible?
1127 	}
1128 
1129 	for ( i = 4096; i < 8192; i++ )
1130 	{
1131 		waveform50[i] = 0;
1132 		waveform60[i] = 0;
1133 		waveform70[i] = 0;
1134 	}
1135 
1136 	if ( isNewSID )
1137 	{
1138 		sidModeNormalTable[3] = sidMode30;
1139 		sidModeNormalTable[6] = sidMode60;
1140 		sidModeNormalTable[7] = sidMode70;
1141 		sidModeRingTable[7] = sidMode74;
1142 	}
1143 	else
1144 	{
1145 		sidModeNormalTable[3] = sidMode30;
1146 		sidModeNormalTable[6] = sidMode60;
1147 		sidModeNormalTable[7] = sidMode00;  // really audible?
1148 		sidModeRingTable[7] = sidMode00;    //
1149 	}
1150 
1151 #if defined(LARGE_NOISE_TABLE)
1152 	udword ni;
1153 	for (ni = 0; ni < sizeof(noiseTableLSB); ni++)
1154 	{
1155 		noiseTableLSB[ni] = (ubyte)
1156 			(((ni >> (13-4)) & 0x10) |
1157 			 ((ni >> (11-3)) & 0x08) |
1158 			 ((ni >> (7-2)) & 0x04) |
1159 			 ((ni >> (4-1)) & 0x02) |
1160 			 ((ni >> (2-0)) & 0x01));
1161 	}
1162 	for (ni = 0; ni < sizeof(noiseTableMSB); ni++)
1163 	{
1164 		noiseTableMSB[ni] = (ubyte)
1165 			(((ni << (7-(22-16))) & 0x80) |
1166 			 ((ni << (6-(20-16))) & 0x40) |
1167 			 ((ni << (5-(16-16))) & 0x20));
1168 	}
1169 #else
1170 	udword ni;
1171 	for (ni = 0; ni < sizeof(noiseTableLSB); ni++)
1172 	{
1173 		noiseTableLSB[ni] = (ubyte)
1174 			(((ni >> (7-2)) & 0x04) |
1175 			 ((ni >> (4-1)) & 0x02) |
1176 			 ((ni >> (2-0)) & 0x01));
1177 	}
1178 	for (ni = 0; ni < sizeof(noiseTableMID); ni++)
1179 	{
1180 		noiseTableMID[ni] = (ubyte)
1181 			(((ni >> (13-8-4)) & 0x10) |
1182 			 ((ni << (3-(11-8))) & 0x08));
1183 	}
1184 	for (ni = 0; ni < sizeof(noiseTableMSB); ni++)
1185 	{
1186 		noiseTableMSB[ni] = (ubyte)
1187 			(((ni << (7-(22-16))) & 0x80) |
1188 			 ((ni << (6-(20-16))) & 0x40) |
1189 			 ((ni << (5-(16-16))) & 0x20));
1190 	}
1191 #endif
1192 }
1193 
1194 // Here set everything that depends on clock speed and frequency.
1195 // The player interface imports this.
sidEmuConfigureClock(int clockSpeed)1196 void sidEmuConfigureClock( int clockSpeed )
1197 {
1198 	sidEmuSetClockSpeed( clockSpeed );
1199 
1200 	PCMsid = (udword)(PCMfreq * (16777216.0 / C64_fClockSpeed));
1201 	PCMsidNoise = (udword)((C64_fClockSpeed*256.0)/PCMfreq);
1202 
1203     sidEmuChangeReplayingSpeed();
1204 	sampleEmuInit();
1205 }
1206 
sidEmuConfigure(udword PCMfrequency,bool measuredEnveValues,bool isNewSID,bool emulateFilter,int clockSpeed)1207 void sidEmuConfigure(udword PCMfrequency, bool measuredEnveValues,
1208 					 bool isNewSID, bool emulateFilter, int clockSpeed)
1209 {
1210 	PCMfreq = PCMfrequency;
1211 	sidEmuConfigureClock( clockSpeed );
1212 
1213 	filterEnabled = emulateFilter;
1214 	initWaveformTables(isNewSID);
1215 
1216 	extern void enveEmuInit(udword updateFreq, bool measuredValues);
1217 	enveEmuInit(PCMfreq,measuredEnveValues);
1218 }
1219 
1220 
1221 // Reset.
1222 
sidEmuReset()1223 bool sidEmuReset()
1224 {
1225 	void clearSidOperator( struct sidOperator* );
1226 	extern void enveEmuResetOperator(sidOperator* pVoice);
1227 
1228 	clearSidOperator( &optr1 );
1229 	enveEmuResetOperator( &optr1 );
1230 	clearSidOperator( &optr2 );
1231 	enveEmuResetOperator( &optr2 );
1232 	clearSidOperator( &optr3 );
1233 	enveEmuResetOperator( &optr3 );
1234 
1235 	optr1.modulator = &optr3;
1236 	optr3.carrier = &optr1;
1237 	optr1.filtVoiceMask = 1;
1238 
1239 	optr2.modulator = &optr1;
1240 	optr1.carrier = &optr2;
1241 	optr2.filtVoiceMask = 2;
1242 
1243 	optr3.modulator = &optr2;
1244 	optr2.carrier = &optr3;
1245 	optr3.filtVoiceMask = 4;
1246 
1247 	// Used for detecting changes of the GATE-bit (aka KEY-bit).
1248 	// 6510-interpreter clears these before each call.
1249 	sidKeysOff[4] = (sidKeysOff[4+7] = (sidKeysOff[4+14] = false));
1250 	sidKeysOn[4] = (sidKeysOn[4+7] = (sidKeysOn[4+14] = false));
1251 
1252 	sampleEmuReset();
1253 
1254 	filterType = (filterCurType = 0);
1255 	filterValue = 0;
1256 	filterDy = (filterResDy = 0);
1257 
1258 	toFill = 0;
1259 #if defined(SIDEMU_TIME_COUNT)
1260 	prevBufferLen = (scaledBufferLen = 0);
1261 #endif
1262 
1263 	return true;
1264 }
1265 
1266 
clearSidOperator(struct sidOperator * pVoice)1267 void clearSidOperator( struct sidOperator* pVoice )
1268 {
1269 	pVoice->SIDfreq = 0;
1270 	pVoice->SIDctrl = 0;
1271 	pVoice->SIDAD = 0;
1272 	pVoice->SIDSR = 0;
1273 
1274 	pVoice->sync = false;
1275 
1276 	pVoice->pulseIndex = (pVoice->newPulseIndex = (pVoice->SIDpulseWidth = 0));
1277 	pVoice->curSIDfreq = (pVoice->curNoiseFreq = 0);
1278 
1279 	pVoice->output = (pVoice->noiseOutput = 0);
1280 	pVoice->outputMask = 0xff;  // on
1281 	pVoice->filtIO = 0;
1282 
1283 	pVoice->filtEnabled = false;
1284 	pVoice->filtLow = (pVoice->filtRef = 0);
1285 
1286 	pVoice->cycleLenCount = 0;
1287 #if defined(DIRECT_FIXPOINT)
1288 	pVoice->cycleLen.l = (pVoice->cycleAddLen.l = 0);
1289 #else
1290 	pVoice->cycleLen = (pVoice->cycleLenPnt = 0);
1291 	pVoice->cycleAddLenPnt = 0;
1292 #endif
1293 
1294 	extern sbyte waveCalcMute(struct sidOperator*);
1295 	pVoice->outProc = &waveCalcMute;
1296 
1297 #if defined(DIRECT_FIXPOINT)
1298 	pVoice->waveStepAdd.l = (pVoice->waveStep.l = 0);
1299 	pVoice->wavePre[0].len = (pVoice->wavePre[0].stp = 0);
1300 	pVoice->wavePre[1].len = (pVoice->wavePre[1].stp = 0);
1301 #else
1302 	pVoice->waveStepAdd = (pVoice->waveStepAddPnt = 0);
1303 	pVoice->waveStep = (pVoice->waveStepPnt = 0);
1304 	pVoice->wavePre[0].len = 0;
1305 	pVoice->wavePre[0].stp = (pVoice->wavePre[0].pnt = 0);
1306 	pVoice->wavePre[1].len = 0;
1307 	pVoice->wavePre[1].stp = (pVoice->wavePre[1].pnt = 0);
1308 #endif
1309 	pVoice->waveStepOld = 0;
1310 
1311 #if defined(DIRECT_FIXPOINT)
1312 	pVoice->noiseReg.l = noiseSeed;
1313 #else
1314 	pVoice->noiseReg = noiseSeed;
1315 #endif
1316 	pVoice->noiseStepAdd = (pVoice->noiseStep = 0);
1317 	pVoice->noiseIsLocked = false;
1318 }
1319 
1320 
sidEmuResetAutoPanning(int autoPanning)1321 void sidEmuResetAutoPanning(int autoPanning)
1322 {
1323 	doAutoPanning = (autoPanning!=SIDEMU_NONE);
1324 	updateAutoPanning = false;
1325 	apCount = 0;
1326 	// Auto-panning see sidEmuSet(). Reset volume levels to default.
1327 	if (doAutoPanning)
1328 	{
1329 		optr1.gainLeft = (optr1.gainSource = 0xa080);
1330 		optr1.gainRight = (optr1.gainDest = 0x2080);
1331 		optr1.gainDirec = (optr1.gainLeft > optr1.gainRight);
1332 		optr1.gainLeftCentered = 0x8080;  // middle
1333 		optr1.gainRightCentered = 0x7f80;
1334 
1335 		optr2.gainLeft = (optr2.gainSource = 0x2080);  // this one mirrored
1336 		optr2.gainRight = (optr2.gainDest = 0xa080);
1337 		optr2.gainDirec = (optr2.gainLeft > optr2.gainRight);
1338 		optr2.gainLeftCentered = 0x8080;  // middle
1339 		optr2.gainRightCentered = 0x7f80;
1340 
1341 		optr3.gainLeft = (optr3.gainSource = 0xa080);
1342 		optr3.gainRight = (optr3.gainDest = 0x2080);
1343 		optr3.gainDirec = (optr3.gainLeft > optr3.gainRight);
1344 		optr3.gainLeftCentered = 0x8080;  // middle
1345 		optr3.gainRightCentered = 0x7f80;
1346 
1347 		voice4_gainLeft = 0x8080;   // middle, not moving
1348 		voice4_gainRight = 0x7f80;
1349 	}
1350 }
1351 
1352 
sidEmuSetVoiceVolume(int voice,uword leftLevel,uword rightLevel,uword total)1353 void sidEmuSetVoiceVolume(int voice, uword leftLevel, uword rightLevel, uword total)
1354 {
1355 	leftLevel *= total;
1356 	leftLevel >>= 8;
1357 	rightLevel *= total;
1358 	rightLevel >>= 8;
1359 	uword centeredLeftLevel = (0x80*total)>>8;
1360 	uword centeredRightLevel = (0x7f*total)>>8;
1361 	// Signed 8-bit samples will be added to base array index.
1362 	// So middle must be 0x80.
1363 	// [-80,-81,...,-FE,-FF,0,1,...,7E,7F]
1364 	uword leftIndex = 0x0080 + (leftLevel<<8);
1365 	uword rightIndex = 0x0080 + (rightLevel<<8);
1366 	uword gainLeftCentered = 0x0080 + (centeredLeftLevel<<8);
1367 	uword gainRightCentered = 0x0080 + (centeredRightLevel<<8);
1368 	switch ( voice )
1369 	{
1370 	 case 1:
1371 		{
1372 			optr1.gainLeft = leftIndex;
1373 			optr1.gainRight = rightIndex;
1374 			//
1375 			optr1.gainSource = leftIndex;
1376 			optr1.gainDest = rightIndex;
1377 			optr1.gainLeftCentered = gainLeftCentered;
1378 			optr1.gainRightCentered = gainRightCentered;
1379 			optr1.gainDirec = (optr1.gainLeft > optr1.gainDest);
1380 			break;
1381 		}
1382 	 case 2:
1383 		{
1384 			optr2.gainLeft = leftIndex;
1385 			optr2.gainRight = rightIndex;
1386 			//
1387 			optr2.gainSource = leftIndex;
1388 			optr2.gainDest = rightIndex;
1389 			optr2.gainLeftCentered = gainLeftCentered;
1390 			optr2.gainRightCentered = gainRightCentered;
1391 			optr2.gainDirec = (optr2.gainLeft > optr2.gainDest);
1392 			break;
1393 		}
1394 	 case 3:
1395 		{
1396 			optr3.gainLeft = leftIndex;
1397 			optr3.gainRight = rightIndex;
1398 			//
1399 			optr3.gainSource = leftIndex;
1400 			optr3.gainDest = rightIndex;
1401 			optr3.gainLeftCentered = gainLeftCentered;
1402 			optr3.gainRightCentered = gainRightCentered;
1403 			optr3.gainDirec = (optr3.gainLeft > optr3.gainDest);
1404 			break;
1405 		}
1406 	 case 4:
1407 		{
1408 			voice4_gainLeft = leftIndex;
1409 			voice4_gainRight = rightIndex;
1410 			break;
1411 		}
1412 	 default:
1413 		{
1414 			break;
1415 		}
1416 	}
1417 }
1418 
1419 
sidEmuReturnVoiceVolume(int voice)1420 uword sidEmuReturnVoiceVolume( int voice )
1421 {
1422 	uword left = 0;
1423 	uword right = 0;
1424 	switch ( voice )
1425 	{
1426 	 case 1:
1427 		{
1428 			left = optr1.gainLeft;
1429 			right = optr1.gainRight;
1430 			break;
1431 		}
1432 	 case 2:
1433 		{
1434 			left = optr2.gainLeft;
1435 			right = optr2.gainRight;
1436 			break;
1437 		}
1438 	 case 3:
1439 		{
1440 			left = optr3.gainLeft;
1441 			right = optr3.gainRight;
1442 			break;
1443 		}
1444 	 case 4:
1445 		{
1446 			left = voice4_gainLeft;
1447 			right = voice4_gainRight;
1448 			break;
1449 		}
1450 	 default:
1451 		{
1452 			break;
1453 		}
1454 	}
1455 	return (left&0xff00)|(right>>8);
1456 }
1457