1 //////////////////////////////////////////////////
2 //                                              //
3 // Emu64                                        //
4 // von Thorsten Kattanek                        //
5 //                                              //
6 // #file: mos6581_8085class.cpp                 //
7 //                                              //
8 // Dieser Sourcecode ist Copyright geschützt!   //
9 // Geistiges Eigentum von Th.Kattanek           //
10 //                                              //
11 // Letzte Änderung am 21.08.2019                //
12 // www.emu64.de                                 //
13 //                                              //
14 //////////////////////////////////////////////////
15 
16 #include "mos6581_8085_class.h"
17 #include "mos6581_8085_calc.h"
18 #include "mos6581_8085_wellenformen.h"
19 
20 unsigned int RateCounterPeriod[]={9,32,63,95,149,220,267,313,392,977,1954,3126,3907,11720,19532,31251};
21 unsigned int SustainLevel[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
22 fc_point f0_points_6581[31]={{0,220},{0,220},{128,230},{256,250},{384,300},{512,420},{640,780},{768,1600},{832,2300},{896,3200},{960,4300},{992,5000},{1008,5400},{1016,5700},{1023,6000},{1023,6000},{1024,4600},{1024,4600},{1032,4800},{1056,5300},{1088,6000},{1120,6600},{1152,7200},{1280,9500},{1408,12000},{1536,14500},{1664,16000},{1792,17100},{1920,17700},{2047,18000},{2047,18000}};
23 fc_point f0_points_8580[19]={{0,0},{0,0},{128,800},{256,1600},{384,2500},{512,3300},{640,4100},{768,4800},{896,5600},{1024,6500},{1152,7500},{1280,8400},{1408,9200},{1536,9800},{1664,10500},{1792,11000},{1920,11700},{2047,12500},{2047,12500}};
24 
MOS6581_8085(int nummer,int samplerate,int puffersize,int * error)25 MOS6581_8085::MOS6581_8085(int nummer,int samplerate,int puffersize,int *error)
26 {
27     Voice[0] = new VOICEClass();
28     Voice[1] = new VOICEClass();
29     Voice[2] = new VOICEClass();
30 
31     SidNummer = nummer;
32     this->FilterFrequenz=0;
33     Samplerate=(double)samplerate;
34     C64ZyklenSek = 985248;
35     FreqConvAddWert=((double)1.0)/((double)C64ZyklenSek/Samplerate);
36     FreqConvCounter=0.0;
37 
38     IODelayEnable = false;
39     IODelayRPos = 0;
40     IODelayWPos = 1000;
41 
42     LastWriteValue = 0;
43 
44     for(int i=0; i<1048576; i++)
45     {
46         IODelayPuffer[i][0] = 0x20;
47         IODelayPuffer[i][1] = 0;
48     }
49 
50     Voice[0]->OscEnable = true;
51     Voice[1]->OscEnable = true;
52     Voice[2]->OscEnable = true;
53 
54     this->FilterOn=true;
55     Voice[0]->SyncSource=2;
56     Voice[1]->SyncSource=0;
57     Voice[2]->SyncSource=1;
58     Voice[0]->SyncDestination=1;
59     Voice[1]->SyncDestination=2;
60     Voice[2]->SyncDestination=0;
61 
62     interpolate(f0_points_6581, f0_points_6581+ sizeof(f0_points_6581)/sizeof(*f0_points_6581) - 1,PointPlotter<int>(f0_6581), 1.0);
63     interpolate(f0_points_8580, f0_points_8580+ sizeof(f0_points_8580)/sizeof(*f0_points_8580) - 1,PointPlotter<int>(f0_8580), 1.0);
64 
65     SoundOutputEnable=false;
66     SetChipType(0);
67 
68     this->CycleExact=false;
69 
70     IoDump = new SIDDumpClass(IO);
71     IoDump->WriteReg = &WriteReg;
72 
73     Zyklencounter = 0;
74     SoundBufferPos = 0;
75     SoundBufferSize = puffersize;
76     SoundBuffer = new short[SoundBufferSize];
77     SoundBufferV0 = new short[SoundBufferSize];
78     SoundBufferV1 = new short[SoundBufferSize];
79     SoundBufferV2 = new short[SoundBufferSize];
80 
81     PotX = PotY = 0xFF;
82 
83     Recording = false;
84     RecSampleCounter = 0;
85 
86     Reset();
87     *error = 0;
88 }
89 
~MOS6581_8085()90 MOS6581_8085::~MOS6581_8085()
91 {
92     delete SoundBuffer;
93     delete SoundBufferV0;
94     delete SoundBufferV1;
95     delete SoundBufferV2;
96 
97     delete IoDump;
98 
99     delete Voice[2];
100     delete Voice[1];
101     delete Voice[0];
102 }
103 
ChangeSampleRate(int samplerate,int puffersize)104 void MOS6581_8085::ChangeSampleRate(int samplerate,int puffersize)
105 {
106     delete SoundBuffer;
107     delete SoundBufferV0;
108     delete SoundBufferV1;
109     delete SoundBufferV2;
110 
111     Samplerate=(double)samplerate;
112     FreqConvAddWert=((double)1.0)/((double)C64ZyklenSek/Samplerate);
113     FreqConvCounter=0.0;
114 
115     SoundBufferPos = 0;
116     SoundBufferSize = puffersize;
117 
118     SoundBuffer = new short[SoundBufferSize];
119     SoundBufferV0 = new short[SoundBufferSize];
120     SoundBufferV1 = new short[SoundBufferSize];
121     SoundBufferV2 = new short[SoundBufferSize];
122 }
123 
Reset(void)124 void MOS6581_8085::Reset(void)
125 {
126     OscReset();
127     EnvReset();
128     FilterReset();
129 }
130 
SetChipType(int type)131 void MOS6581_8085::SetChipType(int type)
132 {
133     SidModel = type;
134 
135     if(SidModel==MOS_6581)
136     {
137         Wave0=Wave6581_0;
138         Wave1=Wave6581_1;
139         Wave2=Wave6581_2;
140         Wave3=Wave6581_3;
141 
142         WaveZero=0x380;
143         VoiceDC=0x800*0xFF;
144 
145         MixerDC=-0xfff*0xff/18>>7;
146         f0=f0_6581;
147         f0_points=f0_points_6581;
148         f0_count=sizeof(f0_points_6581)/sizeof(*f0_points_6581);
149     }
150     else
151     {
152         Wave0=Wave8580_0;
153         Wave1=Wave8580_1;
154         Wave2=Wave8580_2;
155         Wave3=Wave8580_3;
156 
157         WaveZero=0x800;
158         VoiceDC=0;
159 
160         MixerDC=0;
161         f0=f0_8580;
162         f0_points=f0_points_8580;
163         f0_count=sizeof(f0_points_8580)/sizeof(*f0_points_8580);
164     }
165     SetW0();
166     SetQ();
167 }
168 
SetC64Zyklen(float C64ZyklenSek)169 void MOS6581_8085::SetC64Zyklen(float C64ZyklenSek)
170 {
171     this->C64ZyklenSek = C64ZyklenSek;
172     FreqConvAddWert=((double)1.0)/((double)C64ZyklenSek/Samplerate);
173 }
174 
SetVoiceEnable(int nr,bool status)175 void MOS6581_8085::SetVoiceEnable(int nr, bool status)
176 {
177     Voice[nr]->OscEnable = status;
178 }
179 
SetPotXY(unsigned char pot_x,unsigned char pot_y)180 void MOS6581_8085::SetPotXY(unsigned char pot_x, unsigned char pot_y)
181 {
182     PotX = pot_x;
183     PotY = pot_y;
184 }
185 
ZeroSoundBufferPos()186 void MOS6581_8085::ZeroSoundBufferPos()
187 {
188     SoundBufferPos = 0;
189 }
190 
OneZyklus(void)191 bool MOS6581_8085::OneZyklus(void)
192 {
193     ret = false;
194 
195     if(!*RESET) Reset();
196 
197     if(LastWriteCounter > 0)
198     {
199         LastWriteCounter--;
200         if(LastWriteCounter == 0)
201             LastWriteValue = 0;
202     }
203 
204     if(CycleExact)
205     {
206     	OscZyklus();
207     	EnvZyklus();
208         FilterZyklus(VoiceOutput(0),VoiceOutput(1),VoiceOutput(2),0);
209     }
210 
211     Zyklencounter++;
212     FreqConvCounter+=FreqConvAddWert;
213     if(FreqConvCounter>=(double)1.0)
214     {
215     	FreqConvCounter-=(double)1.0;
216     	if(!CycleExact)
217     	{
218             OscZyklus(Zyklencounter);
219             EnvZyklus(Zyklencounter);
220             FilterZyklus(Zyklencounter,VoiceOutput(0),VoiceOutput(1),VoiceOutput(2),0);
221     	}
222     	Zyklencounter=0;
223 
224         if(SoundOutputEnable)
225         {
226             if(SoundBufferPos < SoundBufferSize)
227             {
228                 SoundBufferV0[SoundBufferPos] = VoiceOutput(0);
229                 SoundBufferV1[SoundBufferPos] = VoiceOutput(1);
230                 SoundBufferV2[SoundBufferPos] = VoiceOutput(2);
231                 SoundBuffer[SoundBufferPos++]=FilterOutput()>>4;
232             }
233         }
234         else
235         {
236             if(SoundBufferPos < SoundBufferSize)
237             {
238                 SoundBufferV0[SoundBufferPos] = VoiceOutput(0);
239                 SoundBufferV1[SoundBufferPos] = VoiceOutput(1);
240                 SoundBufferV2[SoundBufferPos] = VoiceOutput(2);
241                 SoundBuffer[SoundBufferPos++]=0;
242             }
243         }
244         ret = true;
245     }
246 
247     ///////// IO DUMP //////////
248     ////////////////////////////
249 
250     // Capture
251     IoDump->CycleTickCapture();
252     // Playing
253     if(IoDump->CycleTickPlay())WriteIO(IoDump->RegOut,IoDump->RegWertOut);
254 
255     //////// RECORD ////////
256     if(Recording)
257     {
258         RecSampleBuffer[RecSampleCounter++] = FilterOutput()>>4;
259         if(RecSampleCounter == 19656) RecSampleCounter = 0;
260     }
261     WriteReg = 0xFF;
262 
263     //////// IO Delay ///////
264     if(IODelayEnable)
265     {
266         if(IODelayPuffer[IODelayRPos][0] < 0x20)
267             WriteIO(IODelayPuffer[IODelayRPos][0],IODelayPuffer[IODelayRPos][1]);
268 
269         IODelayRPos++;
270         IODelayRPos &= 0xFFFFF;
271         IODelayWPos++;
272         IODelayWPos &= 0xFFFFF;
273 
274         IODelayPuffer[IODelayWPos][0] = 0x20;
275     }
276 
277     return ret;
278 }
279 
SaveFreez(FILE * File)280 bool MOS6581_8085::SaveFreez(FILE* File)
281 {
282     fwrite(IO,1,32,File);
283     return true;
284 }
285 
LoadFreez(FILE * File,unsigned short Version)286 bool MOS6581_8085::LoadFreez(FILE *File,unsigned short Version)
287 {
288     switch(Version)
289     {
290     case 0x0100:
291     case 0x0101:
292         int size_read = fread(IO,1,32,File);
293         if(size_read == 32) for(int i=0;i<32;i++) WriteIO(i,IO[i]);
294         return false;
295         break;
296     }
297     return true;
298 }
299 
ReadIO(unsigned short adresse)300 unsigned char MOS6581_8085::ReadIO(unsigned short adresse)
301 {
302     switch(adresse&0x1F)
303     {
304     case 25: // AD Wandler 1
305         if(SidNummer == 0)
306             return PotX;
307          break;
308 
309     case 26: // AD Wandler 2
310         if(SidNummer == 0)
311             return PotY;
312         break;
313 
314     case 27:
315         return OscOutput(2)>>4;
316 
317     case 28:
318         return EnvOutput(2);
319 
320     default:
321         return LastWriteValue;
322     }
323     return 0;
324 }
325 
SetIODelayEnable(bool enable)326 void MOS6581_8085::SetIODelayEnable(bool enable)
327 {
328     IODelayEnable = enable;
329 }
330 
WriteIO(unsigned short adresse,unsigned char wert)331 void MOS6581_8085::WriteIO(unsigned short adresse,unsigned char wert)
332 {
333 
334     LastWriteValue = wert;
335     LastWriteCounter = LAST_WRITE_COUNTER_START;
336 
337     static bool KeyNext;
338 
339     if(!IODelayEnable)
340     {
341         WriteReg = adresse & 0x1F;
342         IO[adresse & 0x1F]=wert;
343     }
344     else
345     {
346         if(adresse > 0xD3FF)  // kommt von CPU
347         {
348             IODelayPuffer[IODelayWPos][0] = adresse & 0x1F;
349             IODelayPuffer[IODelayWPos][1] = wert;
350             return;
351         }
352         else                // kommt aus Delas
353         {
354             wert = IODelayPuffer[IODelayRPos][1];
355             WriteReg = adresse & 0x1F;
356             IO[adresse & 0x1F]=wert;
357         }
358     }
359 
360     switch(adresse&0x1F)
361     {
362     case 0: // FrequenzLO für Stimme 0
363         Voice[0]->Frequenz=(Voice[0]->Frequenz & 0xFF00) | (wert & 0x00FF);
364         break;
365 
366     case 1: // FrequenzHI für Stimme 0
367         Voice[0]->Frequenz=((wert<<8) & 0xFF00) | (Voice[0]->Frequenz & 0x00FF);
368         break;
369 
370     case 2: // PulsweiteLO für Stimme 0
371         Voice[0]->Pulsweite=(Voice[0]->Pulsweite & 0xF00) | (wert & 0x0FF);
372         break;
373 
374     case 3: // PulsweiteHI für Stimme 0
375         Voice[0]->Pulsweite=((wert<<8) & 0xF00) | (Voice[0]->Pulsweite & 0x0FF);
376         break;
377 
378     case 4: // Kontrol Register für Stimme 0
379         Voice[0]->Waveform=(wert>>4) & 0x0F;
380         Voice[0]->RingBit = !(~wert & 0x04);
381         Voice[0]->SyncBit = !(~wert & 0x02);
382         if(wert & 0x08)
383         {
384             Voice[0]->Accu=0;
385             Voice[0]->ShiftReg=0;
386         }
387         else if(Voice[0]->TestBit) Voice[0]->ShiftReg=0x7FFFF8;
388         Voice[0]->TestBit = !(~wert & 0x08);
389 
390         KeyNext = wert & 0x01;
391         if (!Voice[0]->KeyBit&&KeyNext)
392         {
393             Voice[0]->State=ATTACK;
394             Voice[0]->RatePeriod=RateCounterPeriod[Voice[0]->Attack];
395             Voice[0]->HoldZero=false;
396         }
397         else if (Voice[0]->KeyBit&&!KeyNext)
398         {
399             Voice[0]->State=RELEASE;
400             Voice[0]->RatePeriod=RateCounterPeriod[Voice[0]->Release];
401         }
402         Voice[0]->KeyBit=KeyNext;
403         break;
404 
405     case 5: // Attack-Decay für Stimme 0
406         Voice[0]->Attack=(wert>>4)&0x0F;
407         Voice[0]->Decay=wert&0x0F;
408         if(Voice[0]->State==ATTACK) Voice[0]->RatePeriod=RateCounterPeriod[Voice[0]->Attack];
409         else if (Voice[0]->State==DECAY_SUSTAIN) Voice[0]->RatePeriod=RateCounterPeriod[Voice[0]->Decay];
410         break;
411 
412     case 6:		// Sustain-Release für Stimme 0
413         Voice[0]->Sustain=(wert>>4)&0x0F;
414         Voice[0]->Release=wert&0x0F;
415         if (Voice[0]->State==RELEASE) Voice[0]->RatePeriod=RateCounterPeriod[Voice[0]->Release];
416         break;
417 
418         /////////////////////////////////////////////////////////////
419 
420     case 7: // FrequenzLO für Stimme 1
421         Voice[1]->Frequenz=(Voice[1]->Frequenz & 0xFF00) | (wert & 0x00FF);
422         break;
423 
424     case 8: // FrequenzHI für Stimme 1
425         Voice[1]->Frequenz=((wert<<8) & 0xFF00) | (Voice[1]->Frequenz & 0x00FF);
426         break;
427 
428     case 9: // PulsweiteLO für Stimme 1
429         Voice[1]->Pulsweite=(Voice[1]->Pulsweite & 0xF00) | (wert & 0x0FF);
430         break;
431 
432     case 10: // PulsweiteHI für Stimme 1
433         Voice[1]->Pulsweite=((wert<<8) & 0xF00) | (Voice[1]->Pulsweite & 0x0FF);
434         break;
435 
436     case 11: // Kontrol Register für Stimme 1
437         Voice[1]->Waveform=(wert>>4)&0x0F;
438         Voice[1]->RingBit = !(~wert&0x04);
439         Voice[1]->SyncBit = !(~wert&0x02);
440         if(wert&0x08)
441         {
442             Voice[1]->Accu=0;
443             Voice[1]->ShiftReg=0;
444         }
445         else if(Voice[1]->TestBit) Voice[1]->ShiftReg=0x7FFFF8;
446         Voice[1]->TestBit = !(~wert&0x08);
447 
448         KeyNext=wert&0x01;
449         if (!Voice[1]->KeyBit&&KeyNext)
450         {
451             Voice[1]->State=ATTACK;
452             Voice[1]->RatePeriod=RateCounterPeriod[Voice[1]->Attack];
453             Voice[1]->HoldZero=false;
454         }
455         else if (Voice[1]->KeyBit&&!KeyNext)
456         {
457             Voice[1]->State=RELEASE;
458             Voice[1]->RatePeriod=RateCounterPeriod[Voice[1]->Release];
459         }
460         Voice[1]->KeyBit=KeyNext;
461         break;
462 
463     case 12: // Attack-Decay für Stimme 1
464         Voice[1]->Attack=(wert>>4)&0x0F;
465         Voice[1]->Decay=wert&0x0F;
466         if(Voice[1]->State==ATTACK) Voice[1]->RatePeriod=RateCounterPeriod[Voice[1]->Attack];
467         else if (Voice[1]->State==DECAY_SUSTAIN) Voice[1]->RatePeriod=RateCounterPeriod[Voice[1]->Decay];
468         break;
469 
470     case 13: // Sustain-Release für Stimme 1
471         Voice[1]->Sustain=(wert>>4)&0x0F;
472         Voice[1]->Release=wert&0x0F;
473         if (Voice[1]->State==RELEASE) Voice[1]->RatePeriod=RateCounterPeriod[Voice[1]->Release];
474         break;
475 
476         /////////////////////////////////////////////////////////////
477 
478     case 14: // FrequenzLO für Stimme 2
479         Voice[2]->Frequenz=(Voice[2]->Frequenz & 0xFF00) | (wert & 0x00FF);
480         break;
481 
482     case 15: // FrequenzHI für Stimme 2
483         Voice[2]->Frequenz=((wert<<8) & 0xFF00) | (Voice[2]->Frequenz & 0x00FF);
484         break;
485 
486     case 16: // PulsweiteLO für Stimme 2
487         Voice[2]->Pulsweite=(Voice[2]->Pulsweite & 0xF00) | (wert & 0x0FF);
488         break;
489 
490     case 17: // PulsweiteHI für Stimme 2
491         Voice[2]->Pulsweite=((wert<<8) & 0xF00) | (Voice[2]->Pulsweite & 0x0FF);
492         break;
493 
494     case 18: // Kontrol Register für Stimme 2
495         Voice[2]->Waveform=(wert>>4)&0x0F;
496         Voice[2]->RingBit = !(~wert&0x04);
497         Voice[2]->SyncBit = !(~wert&0x02);
498         if(wert&0x08)
499         {
500             Voice[2]->Accu=0;
501             Voice[2]->ShiftReg=0;
502         }
503         else if(Voice[2]->TestBit) Voice[2]->ShiftReg=0x7FFFF8;
504         Voice[2]->TestBit = !(~wert&0x08);
505 
506         KeyNext=wert&0x01;
507         if (!Voice[2]->KeyBit&&KeyNext)
508         {
509             Voice[2]->State=ATTACK;
510             Voice[2]->RatePeriod=RateCounterPeriod[Voice[2]->Attack];
511             Voice[2]->HoldZero=false;
512         }
513         else if (Voice[2]->KeyBit&&!KeyNext)
514         {
515             Voice[2]->State=RELEASE;
516             Voice[2]->RatePeriod=RateCounterPeriod[Voice[2]->Release];
517         }
518         Voice[2]->KeyBit=KeyNext;
519         break;
520 
521     case 19: // Attack-Decay für Stimme 2
522         Voice[2]->Attack=(wert>>4)&0x0F;
523         Voice[2]->Decay=wert&0x0F;
524         if(Voice[2]->State==ATTACK) Voice[2]->RatePeriod=RateCounterPeriod[Voice[2]->Attack];
525         else if (Voice[2]->State==DECAY_SUSTAIN) Voice[2]->RatePeriod=RateCounterPeriod[Voice[2]->Decay];
526         break;
527 
528     case 20: // Sustain-Release für Stimme 2
529         Voice[2]->Sustain=(wert>>4)&0x0F;
530         Voice[2]->Release=wert&0x0F;
531         if (Voice[2]->State==RELEASE) Voice[2]->RatePeriod=RateCounterPeriod[Voice[2]->Release];
532         break;
533 
534     case 21: // FilterfrequenzLO
535         FilterFrequenz=(FilterFrequenz & 0x7F8) | (wert & 0x007);
536         SetW0();
537         break;
538 
539     case 22: // FilterfrequenzHI
540         FilterFrequenz=((wert<<3) & 0x7F8) | (FilterFrequenz & 0x007);
541         SetW0();
542         break;
543 
544     case 23: // Filterkontrol_1 und Resonanz
545         FilterResonanz=(wert>>4)&0x0F;
546         SetQ();
547         FilterKey=wert&0x0F;
548         break;
549 
550     case 24: // Filterkontrol_2 und Lautstärke
551         Voice3Off=wert&0x80;
552         HpBpLp=(wert>>4)&0x07;
553         Volume=wert&0x0F;
554         break;
555     }
556 }
557 
558 //////////////// ALLE SID MODULE ////////////////
559 
VoiceOutput(int voice)560 inline int MOS6581_8085::VoiceOutput(int voice)
561 {
562     return (OscOutput(voice)-WaveZero)*EnvOutput(voice) + VoiceDC;
563 }
564 
565 ///////////////////////////////////////////////////////////////////////////////////////////////////
566 // Oscillator /////////////////////////////////////////////////////////////////////////////////////
567 
OscZyklus(void)568 inline void MOS6581_8085::OscZyklus(void)
569 {
570     static unsigned int AccuPrev;
571     static unsigned int Bit0;
572 
573     for(int i=0;i<3;i++)
574     {
575         v=Voice[i];
576         if(!v->TestBit)
577         {
578             AccuPrev=v->Accu;
579             v->Accu+=v->Frequenz;
580             v->Accu&=0xFFFFFF;
581             v->MsbRising=!(AccuPrev&0x800000)&&(v->Accu&0x800000);
582             if(!(AccuPrev&0x080000)&&(v->Accu&0x080000))
583             {
584                 Bit0=((v->ShiftReg>>22)^(v->ShiftReg>>17))&0x01;
585                 v->ShiftReg<<=1;
586                 v->ShiftReg&=0x7FFFFF;
587                 v->ShiftReg|=Bit0;
588             }
589         }
590     }
591 
592     /// Sycronisieren ?? ///
593     for(int i=0;i<3;i++)
594     {
595         v=Voice[i];
596         vs=Voice[v->SyncSource];
597         vd=Voice[v->SyncDestination];
598         if (v->MsbRising && vd->SyncBit && !(v->SyncBit && vs->MsbRising))
599         {
600             vd->Accu=0;
601         }
602     }
603 }
604 
OscZyklus(int zyklen)605 inline void MOS6581_8085::OscZyklus(int zyklen)
606 {
607     static unsigned int AccuPrev;
608     static unsigned int AccuDelta;
609     static unsigned int ShiftPeriod;
610     static unsigned int Bit0;
611 
612     for(int i=0;i<3;i++)
613     {
614         v=Voice[i];
615         if(!v->TestBit)
616         {
617             AccuPrev=v->Accu;
618             AccuDelta=zyklen*v->Frequenz;
619             v->Accu+=AccuDelta;
620             v->Accu&=0xFFFFFF;
621             v->MsbRising=!(AccuPrev&0x800000)&&(v->Accu&0x800000);
622             ShiftPeriod=0x100000;
623             while (AccuDelta)
624             {
625                 if (AccuDelta < ShiftPeriod)
626                 {
627                     ShiftPeriod=AccuDelta;
628                     if(ShiftPeriod<=0x80000)
629                     {
630                         if (((v->Accu-ShiftPeriod)&0x080000)||!(v->Accu& 0x080000))
631                         {
632                             break;
633                         }
634                     }
635                     else
636                     {
637                         if (((v->Accu-ShiftPeriod)&0x080000)&&!(v->Accu&0x080000))
638                         {
639                             break;
640                         }
641                     }
642                 }
643                 Bit0=((v->ShiftReg>>22)^(v->ShiftReg>>17))&0x01;
644                 v->ShiftReg<<=1;
645                 v->ShiftReg&=0x7FFFFF;
646                 v->ShiftReg|=Bit0;
647                 AccuDelta-=ShiftPeriod;
648             }
649         }
650     }
651 }
652 
OscOutput(int voice)653 inline unsigned int MOS6581_8085::OscOutput(int voice)
654 {
655     if(!Voice[voice]->OscEnable) return 0;
656 
657     v = Voice[voice];
658     vs = Voice[v->SyncSource];
659 
660     switch (v->Waveform)
661     {
662     case 0x01:
663         return WaveDreieck(v,vs);
664 
665     case 0x02:
666         return WaveSaegezahn(v);
667 
668     case 0x03:
669         return Wave0[WaveSaegezahn(v)]<<4;
670 
671     case 0x04:
672         return (v->TestBit||(v->Accu>>12)>=v->Pulsweite)?0xFFF:0x000;
673 
674     case 0x05:
675         return (Wave1[WaveDreieck(v,vs)>>1]<<4)&WaveRechteck(v);
676 
677     case 0x06:
678         return (Wave2[WaveSaegezahn(v)]<<4)&WaveRechteck(v);
679 
680     case 0x07:
681         return (Wave3[WaveSaegezahn(v)]<<4)&WaveRechteck(v);
682 
683     case 0x08:
684         return WaveRauschen(v);
685 
686     default:
687         return 0;
688     }
689 }
690 
WaveDreieck(VOICEClass * v,VOICEClass * vs)691 inline unsigned int MOS6581_8085::WaveDreieck(VOICEClass *v,VOICEClass *vs)
692 {
693     static unsigned int tmp;
694 
695     tmp = (v->RingBit ? v->Accu ^ vs->Accu : v->Accu)& 0x800000;
696     return ((tmp ? ~v->Accu : v->Accu) >> 11) & 0xfff;
697 }
698 
WaveSaegezahn(VOICEClass * v)699 inline unsigned int MOS6581_8085::WaveSaegezahn(VOICEClass *v)
700 {
701     return v->Accu>>12;
702 }
703 
WaveRechteck(VOICEClass * v)704 inline unsigned int MOS6581_8085::WaveRechteck(VOICEClass *v)
705 {
706     return (v->TestBit||(v->Accu>>12)>=v->Pulsweite)?0xFFF:0x000;
707 }
708 
WaveRauschen(VOICEClass * v)709 inline unsigned int MOS6581_8085::WaveRauschen(VOICEClass *v)
710 {
711     return ((v->ShiftReg&0x400000)>>11)|((v->ShiftReg&0x100000)>>10)|((v->ShiftReg&0x010000)>>7)|((v->ShiftReg&0x002000)>>5)|((v->ShiftReg&0x000800)>>4)|((v->ShiftReg&0x000080)>>1)|((v->ShiftReg&0x000010)<<1)|((v->ShiftReg&0x000004)<< 2);
712 }
713 
OscReset(void)714 inline void MOS6581_8085::OscReset(void)
715 {
716     for(int i=0;i<3;i++)
717     {
718         v=Voice[i];
719         v->Accu=0;
720         v->ShiftReg=0x7FFFF8;
721         v->Frequenz=0;
722         v->Pulsweite=0;
723         v->TestBit=false;
724         v->RingBit=false;
725         v->SyncBit=false;
726         v->MsbRising=false;
727     }
728 }
729 
730 ///////////////////////////////////////////////////////////////////////////////////////////////////
731 // Envelope ///////////////////////////////////////////////////////////////////////////////////////
732 
EnvZyklus(void)733 inline void MOS6581_8085::EnvZyklus(void)
734 {
735     for(int i=0;i<3;i++)
736     {
737         v=Voice[i];
738         if(++v->RateCounter & 0x8000) ++v->RateCounter &= 0x7FFF;
739         if(v->RateCounter != v->RatePeriod) goto L10;
740         v->RateCounter=0;
741         if(v->State == ATTACK || ++v->ExponentialCounter == v->ExponentialCounterPeriod)
742         {
743             v->ExponentialCounter=0;
744             if(v->HoldZero) goto L10;
745 
746             switch(v->State)
747             {
748             case ATTACK:
749                 ++v->EnvCounter &= 0xFF;
750                 if(v->EnvCounter==0xFF)
751                 {
752                     v->State=DECAY_SUSTAIN;
753                     v->RatePeriod=RateCounterPeriod[v->Decay];
754                 }
755                 break;
756 
757             case DECAY_SUSTAIN:
758                 if(v->EnvCounter != SustainLevel[v->Sustain]) --v->EnvCounter;
759                 break;
760 
761             case RELEASE:
762                 --v->EnvCounter &= 0xFF;
763                 break;
764             }
765 
766             switch(v->EnvCounter)
767             {
768             case 0xFF:
769                 v->ExponentialCounterPeriod=1;
770                 break;
771 
772             case 0x5D:
773                 v->ExponentialCounterPeriod=2;
774                 break;
775 
776             case 0x36:
777                 v->ExponentialCounterPeriod=4;
778                 break;
779 
780             case 0x1A:
781                 v->ExponentialCounterPeriod=8;
782                 break;
783 
784             case 0x0E:
785                 v->ExponentialCounterPeriod=16;
786                 break;
787 
788             case 0x06:
789                 v->ExponentialCounterPeriod=30;
790                 break;
791 
792             case 0x00:
793                 v->ExponentialCounterPeriod=1;
794                 v->HoldZero=true;
795                 break;
796             }
797         }
798 L10:;
799     }
800 }
801 
EnvZyklus(int zyklen)802 inline void MOS6581_8085::EnvZyklus(int zyklen)
803 {
804     for(int i=0;i<3;i++)
805     {
806         v=Voice[i];
807         int rate_step = v->RatePeriod-v->RateCounter;
808         if (rate_step <= 0)
809         {
810             rate_step += 0x7fff;
811         }
812 
813         while (zyklen)
814         {
815             if (zyklen < rate_step)
816             {
817                 v->RateCounter+=zyklen;
818                 if (v->RateCounter & 0x8000)
819                 {
820                     ++v->RateCounter &= 0x7fff;
821                 }
822                 goto L10;
823             }
824             v->RateCounter = 0;
825             zyklen -= rate_step;
826 
827             if(v->State == ATTACK || ++v->ExponentialCounter == v->ExponentialCounterPeriod)
828             {
829                 v->ExponentialCounter = 0;
830                 if (v->HoldZero)
831                 {
832                     rate_step = v->RatePeriod;
833                     continue;
834                 }
835 
836                 switch(v->State)
837                 {
838                 case ATTACK:
839                     ++v->EnvCounter &= 0xFF;
840                     if(v->EnvCounter==0xFF)
841                     {
842                         v->State=DECAY_SUSTAIN;
843                         v->RatePeriod=RateCounterPeriod[v->Decay];
844                     }
845                     break;
846 
847                 case DECAY_SUSTAIN:
848                     if(v->EnvCounter != SustainLevel[v->Sustain]) --v->EnvCounter;
849                     break;
850 
851                 case RELEASE:
852                     --v->EnvCounter &= 0xFF;
853                     break;
854                 }
855                 switch(v->EnvCounter)
856                 {
857                 case 0xFF:
858                     v->ExponentialCounterPeriod=1;
859                     break;
860 
861                 case 0x5D:
862                     v->ExponentialCounterPeriod=2;
863                     break;
864 
865                 case 0x36:
866                     v->ExponentialCounterPeriod=4;
867                     break;
868 
869                 case 0x1A:
870                     v->ExponentialCounterPeriod=8;
871                     break;
872 
873                 case 0x0E:
874                     v->ExponentialCounterPeriod=16;
875                     break;
876 
877                 case 0x06:
878                     v->ExponentialCounterPeriod=30;
879                     break;
880 
881                 case 0x00:
882                     v->ExponentialCounterPeriod=1;
883                     v->HoldZero=true;
884                     break;
885                 }
886             }
887             rate_step = v->RatePeriod;
888         }
889 	L10:;
890     }
891 }
892 
EnvReset(void)893 inline void MOS6581_8085::EnvReset(void)
894 {
895     for(int i=0;i<3;i++)
896     {
897         v=Voice[i];
898         v->EnvCounter=0;
899         v->Attack=0;
900         v->Decay=0;
901         v->Sustain=0;
902         v->Release=0;
903         v->KeyBit=false;
904         v->RateCounter=0;
905         v->State=RELEASE;
906         v->RatePeriod=RateCounterPeriod[v->Release];
907         v->HoldZero=true;
908         v->ExponentialCounter=0;
909         v->ExponentialCounterPeriod=1;
910     }
911 }
912 
EnvOutput(int voice)913 inline unsigned int MOS6581_8085::EnvOutput(int voice)
914 {
915     if(!Voice[voice]->OscEnable) return 0;
916     return Voice[voice]->EnvCounter;
917 }
918 
919 ///////////////////////////////////////////////////////////////////////////////////////////////////
920 // Filter /////////////////////////////////////////////////////////////////////////////////////////
921 
FilterZyklus(int voice1,int voice2,int voice3,int ext_in)922 inline void MOS6581_8085::FilterZyklus(int voice1,int voice2,int voice3,int ext_in)
923 {
924     voice1 >>= 7;
925     voice2 >>= 7;
926 
927     if(Voice3Off&&!(FilterKey&0x04))
928     {
929        voice3 = 0;
930     }
931     else
932     {
933         voice3 >>= 7;
934     }
935 
936     ext_in >>= 7;
937 
938     if(!FilterOn)
939     {
940         Vnf = voice1 + voice2 + voice3 + ext_in;
941         Vhp = Vbp = Vlp = 0;
942         return;
943     }
944 
945     int Vi;
946 
947     switch (FilterKey)
948     {
949     default:
950 
951     case 0x00:
952         Vi = 0;
953         Vnf = voice1 + voice2 + voice3 + ext_in;
954         break;
955 
956     case 0x01:
957         Vi = voice1;
958         Vnf = voice2 + voice3 + ext_in;
959         break;
960 
961     case 0x02:
962         Vi = voice2;
963         Vnf = voice1 + voice3 + ext_in;
964         break;
965 
966     case 0x03:
967         Vi = voice1 + voice2;
968         Vnf = voice3 + ext_in;
969         break;
970 
971     case 0x04:
972         Vi = voice3;
973         Vnf = voice1 + voice2 + ext_in;
974         break;
975 
976     case 0x05:
977         Vi = voice1 + voice3;
978         Vnf = voice2 + ext_in;
979         break;
980 
981     case 0x06:
982         Vi = voice2 + voice3;
983         Vnf = voice1 + ext_in;
984         break;
985 
986     case 0x07:
987         Vi = voice1 + voice2 + voice3;
988         Vnf = ext_in;
989         break;
990 
991     case 0x08:
992         Vi = ext_in;
993         Vnf = voice1 + voice2 + voice3;
994         break;
995 
996     case 0x09:
997         Vi = voice1 + ext_in;
998         Vnf = voice2 + voice3;
999         break;
1000 
1001     case 0x0A:
1002         Vi = voice2 + ext_in;
1003         Vnf = voice1 + voice3;
1004         break;
1005 
1006     case 0x0B:
1007         Vi = voice1 + voice2 + ext_in;
1008         Vnf = voice3;
1009         break;
1010 
1011     case 0x0C:
1012         Vi = voice3 + ext_in;
1013         Vnf = voice1 + voice2;
1014         break;
1015 
1016     case 0x0D:
1017         Vi = voice1 + voice3 + ext_in;
1018         Vnf = voice2;
1019         break;
1020 
1021     case 0x0E:
1022         Vi = voice2 + voice3 + ext_in;
1023         Vnf = voice1;
1024         break;
1025 
1026     case 0x0F:
1027         Vi = voice1 + voice2 + voice3 + ext_in;
1028         Vnf = 0;
1029         break;
1030     }
1031     int dVbp = (w0_ceil_1*Vhp>>20);
1032     int dVlp = (w0_ceil_1*Vbp>>20);
1033     Vbp-=dVbp;
1034     Vlp-=dVlp;
1035     Vhp=(Vbp*_1024_div_Q>>10)-Vlp-Vi;
1036 }
1037 
FilterZyklus(int zyklen,int voice1,int voice2,int voice3,int ext_in)1038 inline void MOS6581_8085::FilterZyklus(int zyklen,int voice1,int voice2,int voice3,int ext_in)
1039 {
1040     voice1 >>= 7;
1041     voice2 >>= 7;
1042 
1043     if(Voice3Off&&!(FilterKey&0x04)) voice3 = 0;
1044     else voice3 >>= 7;
1045 
1046     ext_in >>= 7;
1047 
1048     if(!FilterOn)
1049     {
1050         Vnf = voice1 + voice2 + voice3 + ext_in;
1051         Vhp = Vbp = Vlp = 0;
1052         return;
1053     }
1054 
1055     int Vi;
1056 
1057     switch (FilterKey)
1058     {
1059 
1060     default:
1061 
1062     case 0x00:
1063         Vi = 0;
1064         Vnf = voice1 + voice2 + voice3 + ext_in;
1065         break;
1066 
1067     case 0x01:
1068         Vi = voice1;
1069         Vnf = voice2 + voice3 + ext_in;
1070         break;
1071 
1072     case 0x02:
1073         Vi = voice2;
1074         Vnf = voice1 + voice3 + ext_in;
1075         break;
1076 
1077     case 0x03:
1078         Vi = voice1 + voice2;
1079         Vnf = voice3 + ext_in;
1080         break;
1081 
1082     case 0x04:
1083         Vi = voice3;
1084         Vnf = voice1 + voice2 + ext_in;
1085         break;
1086 
1087     case 0x05:
1088         Vi = voice1 + voice3;
1089         Vnf = voice2 + ext_in;
1090         break;
1091 
1092     case 0x06:
1093         Vi = voice2 + voice3;
1094         Vnf = voice1 + ext_in;
1095         break;
1096 
1097     case 0x07:
1098         Vi = voice1 + voice2 + voice3;
1099         Vnf = ext_in;
1100         break;
1101 
1102     case 0x08:
1103         Vi = ext_in;
1104         Vnf = voice1 + voice2 + voice3;
1105         break;
1106 
1107     case 0x09:
1108         Vi = voice1 + ext_in;
1109         Vnf = voice2 + voice3;
1110         break;
1111 
1112     case 0x0A:
1113         Vi = voice2 + ext_in;
1114         Vnf = voice1 + voice3;
1115         break;
1116 
1117     case 0x0B:
1118         Vi = voice1 + voice2 + ext_in;
1119         Vnf = voice3;
1120         break;
1121 
1122     case 0x0C:
1123         Vi = voice3 + ext_in;
1124         Vnf = voice1 + voice2;
1125         break;
1126 
1127     case 0x0D:
1128         Vi = voice1 + voice3 + ext_in;
1129         Vnf = voice2;
1130         break;
1131 
1132     case 0x0E:
1133         Vi = voice2 + voice3 + ext_in;
1134         Vnf = voice1;
1135         break;
1136 
1137     case 0x0F:
1138         Vi = voice1 + voice2 + voice3 + ext_in;
1139         Vnf = 0;
1140         break;
1141     }
1142 
1143     int delta_t_flt=8;
1144     while (zyklen)
1145     {
1146         if (zyklen < delta_t_flt)
1147         {
1148             delta_t_flt = zyklen;
1149         }
1150         int w0_delta_t = w0_ceil_dt*delta_t_flt>>6;
1151         int dVbp = (w0_delta_t*Vhp >> 14);
1152         int dVlp = (w0_delta_t*Vbp >> 14);
1153         Vbp-=dVbp;
1154         Vlp-=dVlp;
1155         Vhp=(Vbp*_1024_div_Q>>10)-Vlp-Vi;
1156         zyklen -= delta_t_flt;
1157     }
1158 }
1159 
FilterOutput(void)1160 inline int MOS6581_8085::FilterOutput(void)
1161 {
1162     if (!FilterOn)
1163     {
1164         return (Vnf + MixerDC)*static_cast<int>(Volume);
1165     }
1166 
1167     int Vf;
1168 
1169     switch(HpBpLp)
1170     {
1171     default:
1172 
1173     case 0x00:
1174         Vf=0;
1175         break;
1176 
1177     case 0x01:
1178         Vf=Vlp;
1179         break;
1180 
1181     case 0x02:
1182         Vf=Vbp;
1183         break;
1184 
1185     case 0x03:
1186         Vf=Vlp+Vbp;
1187         break;
1188 
1189     case 0x04:
1190         Vf=Vhp;
1191         break;
1192 
1193     case 0x05:
1194         Vf=Vlp+Vhp;
1195         break;
1196 
1197     case 0x06:
1198         Vf=Vbp+Vhp;
1199         break;
1200 
1201     case 0x07:
1202         Vf=Vlp+Vbp+Vhp;
1203         break;
1204     }
1205     return (Vnf+Vf+MixerDC)*static_cast<int>(Volume);
1206 }
1207 
FilterReset(void)1208 inline void MOS6581_8085::FilterReset(void)
1209 {
1210     FilterFrequenz=0;
1211     FilterResonanz=0;
1212     FilterKey=0;
1213     Voice3Off=0;
1214     HpBpLp=0;
1215     Volume=0;
1216 
1217     Vhp=0;
1218     Vbp=0;
1219     Vlp=0;
1220     Vnf=0;
1221 
1222     SetW0();
1223     SetQ();
1224 }
1225 
SetW0(void)1226 inline void MOS6581_8085::SetW0(void)
1227 {
1228     const double pi = 3.1415926535897932385;
1229     w0=(int)(2*pi*f0[FilterFrequenz]*1.048576);
1230     const int w0_max_1 = static_cast<int>(2*pi*16000*1.048576);
1231     w0_ceil_1 = w0 <= w0_max_1 ? w0 : w0_max_1;
1232     const int w0_max_dt = static_cast<int>(2*pi*4000*1.048576);
1233     w0_ceil_dt = w0 <= w0_max_dt ? w0 : w0_max_dt;
1234 }
1235 
SetQ(void)1236 inline void MOS6581_8085::SetQ(void)
1237 {
1238     _1024_div_Q = static_cast<int>(1024.0/(0.707 + 1.0*FilterResonanz/0x0F));
1239 }
1240