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