1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
4 
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #include <memory.h>
20 
21 #include "GBA.h"
22 #include "Globals.h"
23 #include "Sound.h"
24 #include "Util.h"
25 
26 #define USE_TICKS_AS  380
27 #define SOUND_MAGIC   0x60000000
28 #define SOUND_MAGIC_2 0x30000000
29 #define NOISE_MAGIC 5
30 
31 extern bool stopState;
32 
33 u8 soundWavePattern[4][32] = {
34   {0x01,0x01,0x01,0x01,
35    0xff,0xff,0xff,0xff,
36    0xff,0xff,0xff,0xff,
37    0xff,0xff,0xff,0xff,
38    0xff,0xff,0xff,0xff,
39    0xff,0xff,0xff,0xff,
40    0xff,0xff,0xff,0xff,
41    0xff,0xff,0xff,0xff},
42   {0x01,0x01,0x01,0x01,
43    0x01,0x01,0x01,0x01,
44    0xff,0xff,0xff,0xff,
45    0xff,0xff,0xff,0xff,
46    0xff,0xff,0xff,0xff,
47    0xff,0xff,0xff,0xff,
48    0xff,0xff,0xff,0xff,
49    0xff,0xff,0xff,0xff},
50   {0x01,0x01,0x01,0x01,
51    0x01,0x01,0x01,0x01,
52    0x01,0x01,0x01,0x01,
53    0x01,0x01,0x01,0x01,
54    0xff,0xff,0xff,0xff,
55    0xff,0xff,0xff,0xff,
56    0xff,0xff,0xff,0xff,
57    0xff,0xff,0xff,0xff},
58   {0x01,0x01,0x01,0x01,
59    0x01,0x01,0x01,0x01,
60    0x01,0x01,0x01,0x01,
61    0x01,0x01,0x01,0x01,
62    0x01,0x01,0x01,0x01,
63    0x01,0x01,0x01,0x01,
64    0xff,0xff,0xff,0xff,
65    0xff,0xff,0xff,0xff}
66 };
67 
68 int soundFreqRatio[8] = {
69   1048576, // 0
70   524288,  // 1
71   262144,  // 2
72   174763,  // 3
73   131072,  // 4
74   104858,  // 5
75   87381,   // 6
76   74898    // 7
77 };
78 
79 int soundShiftClock[16]= {
80       2, // 0
81       4, // 1
82       8, // 2
83      16, // 3
84      32, // 4
85      64, // 5
86     128, // 6
87     256, // 7
88     512, // 8
89    1024, // 9
90    2048, // 10
91    4096, // 11
92    8192, // 12
93   16384, // 13
94   1,     // 14
95   1      // 15
96 };
97 
98 int soundVolume = 0;
99 
100 u8 soundBuffer[6][735];
101 u16 soundFinalWave[1470];
102 
103 int soundBufferLen = 1470;
104 int soundBufferTotalLen = 14700;
105 int soundQuality = 2;
106 int soundPaused = 1;
107 int soundPlay = 0;
108 int soundTicks = soundQuality * USE_TICKS_AS;
109 int SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
110 u32 soundNextPosition = 0;
111 
112 int soundLevel1 = 0;
113 int soundLevel2 = 0;
114 int soundBalance = 0;
115 int soundMasterOn = 0;
116 int soundIndex = 0;
117 int soundBufferIndex = 0;
118 int soundDebug = 0;
119 bool soundOffFlag = false;
120 
121 int sound1On = 0;
122 int sound1ATL = 0;
123 int sound1Skip = 0;
124 int sound1Index = 0;
125 int sound1Continue = 0;
126 int sound1EnvelopeVolume =  0;
127 int sound1EnvelopeATL = 0;
128 int sound1EnvelopeUpDown = 0;
129 int sound1EnvelopeATLReload = 0;
130 int sound1SweepATL = 0;
131 int sound1SweepATLReload = 0;
132 int sound1SweepSteps = 0;
133 int sound1SweepUpDown = 0;
134 int sound1SweepStep = 0;
135 u8 *sound1Wave = soundWavePattern[2];
136 
137 int sound2On = 0;
138 int sound2ATL = 0;
139 int sound2Skip = 0;
140 int sound2Index = 0;
141 int sound2Continue = 0;
142 int sound2EnvelopeVolume =  0;
143 int sound2EnvelopeATL = 0;
144 int sound2EnvelopeUpDown = 0;
145 int sound2EnvelopeATLReload = 0;
146 u8 *sound2Wave = soundWavePattern[2];
147 
148 int sound3On = 0;
149 int sound3ATL = 0;
150 int sound3Skip = 0;
151 int sound3Index = 0;
152 int sound3Continue = 0;
153 int sound3OutputLevel = 0;
154 int sound3Last = 0;
155 u8 sound3WaveRam[0x20];
156 int sound3Bank = 0;
157 int sound3DataSize = 0;
158 int sound3ForcedOutput = 0;
159 
160 int sound4On = 0;
161 int sound4Clock = 0;
162 int sound4ATL = 0;
163 int sound4Skip = 0;
164 int sound4Index = 0;
165 int sound4ShiftRight = 0x7f;
166 int sound4ShiftSkip = 0;
167 int sound4ShiftIndex = 0;
168 int sound4NSteps = 0;
169 int sound4CountDown = 0;
170 int sound4Continue = 0;
171 int sound4EnvelopeVolume =  0;
172 int sound4EnvelopeATL = 0;
173 int sound4EnvelopeUpDown = 0;
174 int sound4EnvelopeATLReload = 0;
175 
176 int soundControl = 0;
177 
178 int soundDSFifoAIndex = 0;
179 int soundDSFifoACount = 0;
180 int soundDSFifoAWriteIndex = 0;
181 bool soundDSAEnabled = false;
182 int soundDSATimer = 0;
183 u8  soundDSFifoA[32];
184 u8 soundDSAValue = 0;
185 
186 int soundDSFifoBIndex = 0;
187 int soundDSFifoBCount = 0;
188 int soundDSFifoBWriteIndex = 0;
189 bool soundDSBEnabled = false;
190 int soundDSBTimer = 0;
191 u8  soundDSFifoB[32];
192 u8 soundDSBValue = 0;
193 
194 int soundEnableFlag = 0x3ff;
195 
196 s16 soundFilter[4000];
197 s16 soundRight[5] = { 0, 0, 0, 0, 0 };
198 s16 soundLeft[5] = { 0, 0, 0, 0, 0 };
199 int soundEchoIndex = 0;
200 bool soundEcho = false;
201 bool soundLowPass = false;
202 bool soundReverse = false;
203 
204 variable_desc soundSaveStruct[] = {
205   { &soundPaused, sizeof(int) },
206   { &soundPlay, sizeof(int) },
207   { &soundTicks, sizeof(int) },
208   { &SOUND_CLOCK_TICKS, sizeof(int) },
209   { &soundLevel1, sizeof(int) },
210   { &soundLevel2, sizeof(int) },
211   { &soundBalance, sizeof(int) },
212   { &soundMasterOn, sizeof(int) },
213   { &soundIndex, sizeof(int) },
214   { &sound1On, sizeof(int) },
215   { &sound1ATL, sizeof(int) },
216   { &sound1Skip, sizeof(int) },
217   { &sound1Index, sizeof(int) },
218   { &sound1Continue, sizeof(int) },
219   { &sound1EnvelopeVolume, sizeof(int) },
220   { &sound1EnvelopeATL, sizeof(int) },
221   { &sound1EnvelopeATLReload, sizeof(int) },
222   { &sound1EnvelopeUpDown, sizeof(int) },
223   { &sound1SweepATL, sizeof(int) },
224   { &sound1SweepATLReload, sizeof(int) },
225   { &sound1SweepSteps, sizeof(int) },
226   { &sound1SweepUpDown, sizeof(int) },
227   { &sound1SweepStep, sizeof(int) },
228   { &sound2On, sizeof(int) },
229   { &sound2ATL, sizeof(int) },
230   { &sound2Skip, sizeof(int) },
231   { &sound2Index, sizeof(int) },
232   { &sound2Continue, sizeof(int) },
233   { &sound2EnvelopeVolume, sizeof(int) },
234   { &sound2EnvelopeATL, sizeof(int) },
235   { &sound2EnvelopeATLReload, sizeof(int) },
236   { &sound2EnvelopeUpDown, sizeof(int) },
237   { &sound3On, sizeof(int) },
238   { &sound3ATL, sizeof(int) },
239   { &sound3Skip, sizeof(int) },
240   { &sound3Index, sizeof(int) },
241   { &sound3Continue, sizeof(int) },
242   { &sound3OutputLevel, sizeof(int) },
243   { &sound4On, sizeof(int) },
244   { &sound4ATL, sizeof(int) },
245   { &sound4Skip, sizeof(int) },
246   { &sound4Index, sizeof(int) },
247   { &sound4Clock, sizeof(int) },
248   { &sound4ShiftRight, sizeof(int) },
249   { &sound4ShiftSkip, sizeof(int) },
250   { &sound4ShiftIndex, sizeof(int) },
251   { &sound4NSteps, sizeof(int) },
252   { &sound4CountDown, sizeof(int) },
253   { &sound4Continue, sizeof(int) },
254   { &sound4EnvelopeVolume, sizeof(int) },
255   { &sound4EnvelopeATL, sizeof(int) },
256   { &sound4EnvelopeATLReload, sizeof(int) },
257   { &sound4EnvelopeUpDown, sizeof(int) },
258   { &soundEnableFlag, sizeof(int) },
259   { &soundControl, sizeof(int) },
260   { &soundDSFifoAIndex, sizeof(int) },
261   { &soundDSFifoACount, sizeof(int) },
262   { &soundDSFifoAWriteIndex, sizeof(int) },
263   { &soundDSAEnabled, sizeof(bool) },
264   { &soundDSATimer, sizeof(int) },
265   { &soundDSFifoA[0], 32 },
266   { &soundDSAValue, sizeof(u8) },
267   { &soundDSFifoBIndex, sizeof(int) },
268   { &soundDSFifoBCount, sizeof(int) },
269   { &soundDSFifoBWriteIndex, sizeof(int) },
270   { &soundDSBEnabled, sizeof(int) },
271   { &soundDSBTimer, sizeof(int) },
272   { &soundDSFifoB[0], 32 },
273   { &soundDSBValue, sizeof(int) },
274   { &soundBuffer[0][0], 6*735 },
275   { &soundFinalWave[0], 2*735 },
276   { NULL, 0 }
277 };
278 
279 variable_desc soundSaveStructV2[] = {
280   { &sound3WaveRam[0], 0x20 },
281   { &sound3Bank, sizeof(int) },
282   { &sound3DataSize, sizeof(int) },
283   { &sound3ForcedOutput, sizeof(int) },
284   { NULL, 0 }
285 };
286 
soundEvent(u32 address,u8 data)287 void soundEvent(u32 address, u8 data)
288 {
289   int freq = 0;
290 
291   switch(address) {
292   case NR10:
293     data &= 0x7f;
294     sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
295     sound1SweepSteps = data & 7;
296     sound1SweepUpDown = data & 0x08;
297     sound1SweepStep = 0;
298     ioMem[address] = data;
299     break;
300   case NR11:
301     sound1Wave = soundWavePattern[data >> 6];
302     sound1ATL  = 172 * (64 - (data & 0x3f));
303     ioMem[address] = data;
304     break;
305   case NR12:
306     sound1EnvelopeUpDown = data & 0x08;
307     sound1EnvelopeATLReload = 689 * (data & 7);
308     if((data & 0xF8) == 0)
309       sound1EnvelopeVolume = 0;
310     ioMem[address] = data;
311     break;
312   case NR13:
313     freq = (((int)(ioMem[NR14] & 7)) << 8) | data;
314     sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
315     freq = 2048 - freq;
316     if(freq) {
317       sound1Skip = SOUND_MAGIC / freq;
318     } else
319       sound1Skip = 0;
320     ioMem[address] = data;
321     break;
322   case NR14:
323     data &= 0xC7;
324     freq = (((int)(data&7) << 8) | ioMem[NR13]);
325     freq = 2048 - freq;
326     sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
327     sound1Continue = data & 0x40;
328     if(freq) {
329       sound1Skip = SOUND_MAGIC / freq;
330     } else
331       sound1Skip = 0;
332     if(data & 0x80) {
333       ioMem[NR52] |= 1;
334       sound1EnvelopeVolume = ioMem[NR12] >> 4;
335       sound1EnvelopeUpDown = ioMem[NR12] & 0x08;
336       sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
337       sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (ioMem[NR12] & 7);
338       sound1SweepATL = sound1SweepATLReload = 344 * ((ioMem[NR10] >> 4) & 7);
339       sound1SweepSteps = ioMem[NR10] & 7;
340       sound1SweepUpDown = ioMem[NR10] & 0x08;
341       sound1SweepStep = 0;
342 
343       sound1Index = 0;
344       sound1On = 1;
345     }
346     ioMem[address] = data;
347     break;
348   case NR21:
349     sound2Wave = soundWavePattern[data >> 6];
350     sound2ATL  = 172 * (64 - (data & 0x3f));
351     ioMem[address] = data;
352     break;
353   case NR22:
354     sound2EnvelopeUpDown = data & 0x08;
355     sound2EnvelopeATLReload = 689 * (data & 7);
356     if((data & 0xF8) == 0)
357       sound2EnvelopeVolume = 0;
358     ioMem[address] = data;
359     break;
360   case NR23:
361     freq = (((int)(ioMem[NR24] & 7)) << 8) | data;
362     sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
363     freq = 2048 - freq;
364     if(freq) {
365       sound2Skip = SOUND_MAGIC / freq;
366     } else
367       sound2Skip = 0;
368     ioMem[address] = data;
369     break;
370   case NR24:
371     data &= 0xC7;
372     freq = (((int)(data&7) << 8) | ioMem[NR23]);
373     freq = 2048 - freq;
374     sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
375     sound2Continue = data & 0x40;
376     if(freq) {
377       sound2Skip = SOUND_MAGIC / freq;
378     } else
379       sound2Skip = 0;
380     if(data & 0x80) {
381       ioMem[NR52] |= 2;
382       sound2EnvelopeVolume = ioMem[NR22] >> 4;
383       sound2EnvelopeUpDown = ioMem[NR22] & 0x08;
384       sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
385       sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (ioMem[NR22] & 7);
386 
387       sound2Index = 0;
388       sound2On = 1;
389     }
390     break;
391     ioMem[address] = data;
392   case NR30:
393     data &= 0xe0;
394     if(!(data & 0x80)) {
395       ioMem[NR52] &= 0xfb;
396       sound3On = 0;
397     }
398     if(((data >> 6) & 1) != sound3Bank)
399       memcpy(&ioMem[0x90], &sound3WaveRam[(((data >> 6) & 1) * 0x10)^0x10],
400              0x10);
401     sound3Bank = (data >> 6) & 1;
402     sound3DataSize = (data >> 5) & 1;
403     ioMem[address] = data;
404     break;
405   case NR31:
406     sound3ATL = 172 * (256-data);
407     ioMem[address] = data;
408     break;
409   case NR32:
410     data &= 0xe0;
411     sound3OutputLevel = (data >> 5) & 3;
412     sound3ForcedOutput = (data >> 7) & 1;
413     ioMem[address] = data;
414     break;
415   case NR33:
416     freq = 2048 - (((int)(ioMem[NR34]&7) << 8) | data);
417     if(freq) {
418       sound3Skip = SOUND_MAGIC_2 / freq;
419     } else
420       sound3Skip = 0;
421     ioMem[address] = data;
422     break;
423   case NR34:
424     data &= 0xc7;
425     freq = 2048 - (((data &7) << 8) | (int)ioMem[NR33]);
426     if(freq) {
427       sound3Skip = SOUND_MAGIC_2 / freq;
428     } else {
429       sound3Skip = 0;
430     }
431     sound3Continue = data & 0x40;
432     if((data & 0x80) && (ioMem[NR30] & 0x80)) {
433       ioMem[NR52] |= 4;
434       sound3ATL = 172 * (256 - ioMem[NR31]);
435       sound3Index = 0;
436       sound3On = 1;
437     }
438     ioMem[address] = data;
439     break;
440   case NR41:
441     data &= 0x3f;
442     sound4ATL  = 172 * (64 - (data & 0x3f));
443     ioMem[address] = data;
444     break;
445   case NR42:
446     sound4EnvelopeUpDown = data & 0x08;
447     sound4EnvelopeATLReload = 689 * (data & 7);
448     if((data & 0xF8) == 0)
449       sound4EnvelopeVolume = 0;
450     ioMem[address] = data;
451     break;
452   case NR43:
453     freq = soundFreqRatio[data & 7];
454     sound4NSteps = data & 0x08;
455 
456     sound4Skip = (freq << 8) / NOISE_MAGIC;
457 
458     sound4Clock = data >> 4;
459 
460     freq = freq / soundShiftClock[sound4Clock];
461 
462     sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
463     ioMem[address] = data;
464     break;
465   case NR44:
466     data &= 0xc0;
467     sound4Continue = data & 0x40;
468     if(data & 0x80) {
469       ioMem[NR52] |= 8;
470       sound4EnvelopeVolume = ioMem[NR42] >> 4;
471       sound4EnvelopeUpDown = ioMem[NR42] & 0x08;
472       sound4ATL = 172 * (64 - (ioMem[NR41] & 0x3f));
473       sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (ioMem[NR42] & 7);
474 
475       sound4On = 1;
476 
477       sound4Index = 0;
478       sound4ShiftIndex = 0;
479 
480       freq = soundFreqRatio[ioMem[NR43] & 7];
481 
482       sound4Skip = (freq << 8) / NOISE_MAGIC;
483 
484       sound4NSteps = ioMem[NR43] & 0x08;
485 
486       freq = freq / soundShiftClock[ioMem[NR43] >> 4];
487 
488       sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
489       if(sound4NSteps)
490         sound4ShiftRight = 0x7fff;
491       else
492         sound4ShiftRight = 0x7f;
493     }
494     ioMem[address] = data;
495     break;
496   case NR50:
497     data &= 0x77;
498     soundLevel1 = data & 7;
499     soundLevel2 = (data >> 4) & 7;
500     ioMem[address] = data;
501     break;
502   case NR51:
503     soundBalance = (data & soundEnableFlag);
504     ioMem[address] = data;
505     break;
506   case NR52:
507     data &= 0x80;
508     data |= ioMem[NR52] & 15;
509     soundMasterOn = data & 0x80;
510     if(!(data & 0x80)) {
511       sound1On = 0;
512       sound2On = 0;
513       sound3On = 0;
514       sound4On = 0;
515     }
516     ioMem[address] = data;
517     break;
518   case 0x90:
519   case 0x91:
520   case 0x92:
521   case 0x93:
522   case 0x94:
523   case 0x95:
524   case 0x96:
525   case 0x97:
526   case 0x98:
527   case 0x99:
528   case 0x9a:
529   case 0x9b:
530   case 0x9c:
531   case 0x9d:
532   case 0x9e:
533   case 0x9f:
534     sound3WaveRam[(sound3Bank*0x10)^0x10+(address&15)] = data;
535     break;
536   }
537 }
538 
soundEvent(u32 address,u16 data)539 void soundEvent(u32 address, u16 data)
540 {
541   switch(address) {
542   case SGCNT0_H:
543     data &= 0xFF0F;
544     soundControl = data & 0x770F;;
545     if(data & 0x0800) {
546       soundDSFifoAWriteIndex = 0;
547       soundDSFifoAIndex = 0;
548       soundDSFifoACount = 0;
549       soundDSAValue = 0;
550       memset(soundDSFifoA, 0, 32);
551     }
552     soundDSAEnabled = (data & 0x0300) ? true : false;
553     soundDSATimer = (data & 0x0400) ? 1 : 0;
554     if(data & 0x8000) {
555       soundDSFifoBWriteIndex = 0;
556       soundDSFifoBIndex = 0;
557       soundDSFifoBCount = 0;
558       soundDSBValue = 0;
559       memset(soundDSFifoB, 0, 32);
560     }
561     soundDSBEnabled = (data & 0x3000) ? true : false;
562     soundDSBTimer = (data & 0x4000) ? 1 : 0;
563     *((u16 *)&ioMem[address]) = data;
564     break;
565   case FIFOA_L:
566   case FIFOA_H:
567     soundDSFifoA[soundDSFifoAWriteIndex++] = data & 0xFF;
568     soundDSFifoA[soundDSFifoAWriteIndex++] = data >> 8;
569     soundDSFifoACount += 2;
570     soundDSFifoAWriteIndex &= 31;
571     *((u16 *)&ioMem[address]) = data;
572     break;
573   case FIFOB_L:
574   case FIFOB_H:
575     soundDSFifoB[soundDSFifoBWriteIndex++] = data & 0xFF;
576     soundDSFifoB[soundDSFifoBWriteIndex++] = data >> 8;
577     soundDSFifoBCount += 2;
578     soundDSFifoBWriteIndex &= 31;
579     *((u16 *)&ioMem[address]) = data;
580     break;
581   case 0x88:
582     data &= 0xC3FF;
583     *((u16 *)&ioMem[address]) = data;
584     break;
585   case 0x90:
586   case 0x92:
587   case 0x94:
588   case 0x96:
589   case 0x98:
590   case 0x9a:
591   case 0x9c:
592   case 0x9e:
593     *((u16 *)&sound3WaveRam[(sound3Bank*0x10)^0x10+(address&14)]) = data;
594     *((u16 *)&ioMem[address]) = data;
595     break;
596   }
597 }
598 
soundChannel1()599 void soundChannel1()
600 {
601   int vol = sound1EnvelopeVolume;
602 
603   int freq = 0;
604   int value = 0;
605 
606   if(sound1On && (sound1ATL || !sound1Continue)) {
607     sound1Index += soundQuality*sound1Skip;
608     sound1Index &= 0x1fffffff;
609 
610     value = ((s8)sound1Wave[sound1Index>>24]) * vol;
611   }
612 
613   soundBuffer[0][soundIndex] = value;
614 
615 
616   if(sound1On) {
617     if(sound1ATL) {
618       sound1ATL-=soundQuality;
619 
620       if(sound1ATL <=0 && sound1Continue) {
621         ioMem[NR52] &= 0xfe;
622         sound1On = 0;
623       }
624     }
625 
626     if(sound1EnvelopeATL) {
627       sound1EnvelopeATL-=soundQuality;
628 
629       if(sound1EnvelopeATL<=0) {
630         if(sound1EnvelopeUpDown) {
631           if(sound1EnvelopeVolume < 15)
632             sound1EnvelopeVolume++;
633         } else {
634           if(sound1EnvelopeVolume)
635             sound1EnvelopeVolume--;
636         }
637 
638         sound1EnvelopeATL += sound1EnvelopeATLReload;
639       }
640     }
641 
642     if(sound1SweepATL) {
643       sound1SweepATL-=soundQuality;
644 
645       if(sound1SweepATL<=0) {
646         freq = (((int)(ioMem[NR14]&7) << 8) | ioMem[NR13]);
647 
648         int updown = 1;
649 
650         if(sound1SweepUpDown)
651           updown = -1;
652 
653         int newfreq = 0;
654         if(sound1SweepSteps) {
655           newfreq = freq + updown * freq / (1 << sound1SweepSteps);
656           if(newfreq == freq)
657             newfreq = 0;
658         } else
659           newfreq = freq;
660 
661         if(newfreq < 0) {
662           sound1SweepATL += sound1SweepATLReload;
663         } else if(newfreq > 2047) {
664           sound1SweepATL = 0;
665           sound1On = 0;
666           ioMem[NR52] &= 0xfe;
667         } else {
668           sound1SweepATL += sound1SweepATLReload;
669           sound1Skip = SOUND_MAGIC/(2048 - newfreq);
670 
671           ioMem[NR13] = newfreq & 0xff;
672           ioMem[NR14] = (ioMem[NR14] & 0xf8) |((newfreq >> 8) & 7);
673         }
674       }
675     }
676   }
677 }
678 
soundChannel2()679 void soundChannel2()
680 {
681   //  int freq = 0;
682   int vol = sound2EnvelopeVolume;
683 
684   int value = 0;
685 
686   if(sound2On && (sound2ATL || !sound2Continue)) {
687     sound2Index += soundQuality*sound2Skip;
688     sound2Index &= 0x1fffffff;
689 
690     value = ((s8)sound2Wave[sound2Index>>24]) * vol;
691   }
692 
693   soundBuffer[1][soundIndex] = value;
694 
695   if(sound2On) {
696     if(sound2ATL) {
697       sound2ATL-=soundQuality;
698 
699       if(sound2ATL <= 0 && sound2Continue) {
700         ioMem[NR52] &= 0xfd;
701         sound2On = 0;
702       }
703     }
704 
705     if(sound2EnvelopeATL) {
706       sound2EnvelopeATL-=soundQuality;
707 
708       if(sound2EnvelopeATL <= 0) {
709         if(sound2EnvelopeUpDown) {
710           if(sound2EnvelopeVolume < 15)
711             sound2EnvelopeVolume++;
712         } else {
713           if(sound2EnvelopeVolume)
714             sound2EnvelopeVolume--;
715         }
716         sound2EnvelopeATL += sound2EnvelopeATLReload;
717       }
718     }
719   }
720 }
721 
soundChannel3()722 void soundChannel3()
723 {
724   int value = sound3Last;
725 
726   if(sound3On && (sound3ATL || !sound3Continue)) {
727     sound3Index += soundQuality*sound3Skip;
728     if(sound3DataSize) {
729       sound3Index &= 0x3fffffff;
730       value = sound3WaveRam[sound3Index>>25];
731     } else {
732       sound3Index &= 0x1fffffff;
733       value = sound3WaveRam[sound3Bank*0x10 + (sound3Index>>25)];
734     }
735 
736     if( (sound3Index & 0x01000000)) {
737       value &= 0x0f;
738     } else {
739       value >>= 4;
740     }
741 
742     value -= 8;
743     value *= 2;
744 
745     if(sound3ForcedOutput) {
746       value = ((value >> 1) + value) >> 1;
747     } else {
748       switch(sound3OutputLevel) {
749       case 0:
750         value = 0;
751         break;
752       case 1:
753         break;
754       case 2:
755         value = (value >> 1);
756         break;
757       case 3:
758         value = (value >> 2);
759         break;
760       }
761     }
762     sound3Last = value;
763   }
764 
765   soundBuffer[2][soundIndex] = value;
766 
767   if(sound3On) {
768     if(sound3ATL) {
769       sound3ATL-=soundQuality;
770 
771       if(sound3ATL <= 0 && sound3Continue) {
772         ioMem[NR52] &= 0xfb;
773         sound3On = 0;
774       }
775     }
776   }
777 }
778 
soundChannel4()779 void soundChannel4()
780 {
781   int vol = sound4EnvelopeVolume;
782 
783   int value = 0;
784 
785   if(sound4Clock <= 0x0c) {
786     if(sound4On && (sound4ATL || !sound4Continue)) {
787       sound4Index += soundQuality*sound4Skip;
788       sound4ShiftIndex += soundQuality*sound4ShiftSkip;
789 
790       if(sound4NSteps) {
791         while(sound4ShiftIndex > 0x1fffff) {
792           sound4ShiftRight = (((sound4ShiftRight << 6) ^
793                                (sound4ShiftRight << 5)) & 0x40) |
794             (sound4ShiftRight >> 1);
795           sound4ShiftIndex -= 0x200000;
796         }
797       } else {
798         while(sound4ShiftIndex > 0x1fffff) {
799           sound4ShiftRight = (((sound4ShiftRight << 14) ^
800                               (sound4ShiftRight << 13)) & 0x4000) |
801             (sound4ShiftRight >> 1);
802 
803           sound4ShiftIndex -= 0x200000;
804         }
805       }
806 
807       sound4Index &= 0x1fffff;
808       sound4ShiftIndex &= 0x1fffff;
809 
810       value = ((sound4ShiftRight & 1)*2-1) * vol;
811     } else {
812       value = 0;
813     }
814   }
815 
816   soundBuffer[3][soundIndex] = value;
817 
818   if(sound4On) {
819     if(sound4ATL) {
820       sound4ATL-=soundQuality;
821 
822       if(sound4ATL <= 0 && sound4Continue) {
823         ioMem[NR52] &= 0xfd;
824         sound4On = 0;
825       }
826     }
827 
828     if(sound4EnvelopeATL) {
829       sound4EnvelopeATL-=soundQuality;
830 
831       if(sound4EnvelopeATL <= 0) {
832         if(sound4EnvelopeUpDown) {
833           if(sound4EnvelopeVolume < 15)
834             sound4EnvelopeVolume++;
835         } else {
836           if(sound4EnvelopeVolume)
837             sound4EnvelopeVolume--;
838         }
839         sound4EnvelopeATL += sound4EnvelopeATLReload;
840       }
841     }
842   }
843 }
844 
soundDirectSoundA()845 void soundDirectSoundA()
846 {
847   soundBuffer[4][soundIndex] = soundDSAValue;
848 }
849 
soundDirectSoundATimer()850 void soundDirectSoundATimer()
851 {
852   if(soundDSAEnabled) {
853     if(soundDSFifoACount <= 16) {
854       CPUCheckDMA(3, 2);
855       if(soundDSFifoACount <= 16) {
856         soundEvent(FIFOA_L, (u16)0);
857         soundEvent(FIFOA_H, (u16)0);
858         soundEvent(FIFOA_L, (u16)0);
859         soundEvent(FIFOA_H, (u16)0);
860         soundEvent(FIFOA_L, (u16)0);
861         soundEvent(FIFOA_H, (u16)0);
862         soundEvent(FIFOA_L, (u16)0);
863         soundEvent(FIFOA_H, (u16)0);
864       }
865     }
866 
867     soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
868     soundDSFifoAIndex = (++soundDSFifoAIndex) & 31;
869     soundDSFifoACount--;
870   } else
871     soundDSAValue = 0;
872 }
873 
soundDirectSoundB()874 void soundDirectSoundB()
875 {
876   soundBuffer[5][soundIndex] = soundDSBValue;
877 }
878 
soundDirectSoundBTimer()879 void soundDirectSoundBTimer()
880 {
881   if(soundDSBEnabled) {
882     if(soundDSFifoBCount <= 16) {
883       CPUCheckDMA(3, 4);
884       if(soundDSFifoBCount <= 16) {
885         soundEvent(FIFOB_L, (u16)0);
886         soundEvent(FIFOB_H, (u16)0);
887         soundEvent(FIFOB_L, (u16)0);
888         soundEvent(FIFOB_H, (u16)0);
889         soundEvent(FIFOB_L, (u16)0);
890         soundEvent(FIFOB_H, (u16)0);
891         soundEvent(FIFOB_L, (u16)0);
892         soundEvent(FIFOB_H, (u16)0);
893       }
894     }
895 
896     soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]);
897     soundDSFifoBIndex = (++soundDSFifoBIndex) & 31;
898     soundDSFifoBCount--;
899   } else {
900     soundDSBValue = 0;
901   }
902 }
903 
soundTimerOverflow(int timer)904 void soundTimerOverflow(int timer)
905 {
906   if(soundDSAEnabled && (soundDSATimer == timer)) {
907     soundDirectSoundATimer();
908   }
909   if(soundDSBEnabled && (soundDSBTimer == timer)) {
910     soundDirectSoundBTimer();
911   }
912 }
913 
914 #ifndef max
915 #define max(a,b) (a)<(b)?(b):(a)
916 #endif
917 
soundMix()918 void soundMix()
919 {
920   int res = 0;
921   int cgbRes = 0;
922   int ratio = ioMem[0x82] & 3;
923   int dsaRatio = ioMem[0x82] & 4;
924   int dsbRatio = ioMem[0x82] & 8;
925 
926   if(soundBalance & 16) {
927     cgbRes = ((s8)soundBuffer[0][soundIndex]);
928   }
929   if(soundBalance & 32) {
930     cgbRes += ((s8)soundBuffer[1][soundIndex]);
931   }
932   if(soundBalance & 64) {
933     cgbRes += ((s8)soundBuffer[2][soundIndex]);
934   }
935   if(soundBalance & 128) {
936     cgbRes += ((s8)soundBuffer[3][soundIndex]);
937   }
938 
939   if((soundControl & 0x0200) && (soundEnableFlag & 0x100)){
940     if(!dsaRatio)
941       res = ((s8)soundBuffer[4][soundIndex])>>1;
942     else
943       res = ((s8)soundBuffer[4][soundIndex]);
944   }
945 
946   if((soundControl & 0x2000) && (soundEnableFlag & 0x200)){
947     if(!dsbRatio)
948       res += ((s8)soundBuffer[5][soundIndex])>>1;
949     else
950       res += ((s8)soundBuffer[5][soundIndex]);
951   }
952 
953   res = (res * 170);
954   cgbRes = (cgbRes * 52 * soundLevel1);
955 
956   switch(ratio) {
957   case 0:
958   case 3: // prohibited, but 25%
959     cgbRes >>= 2;
960     break;
961   case 1:
962     cgbRes >>= 1;
963     break;
964   case 2:
965     break;
966   }
967 
968   res += cgbRes;
969 
970   if(soundEcho) {
971     res *= 2;
972     res += soundFilter[soundEchoIndex];
973     res /= 2;
974     soundFilter[soundEchoIndex++] = res;
975   }
976 
977   if(soundLowPass) {
978     soundLeft[4] = soundLeft[3];
979     soundLeft[3] = soundLeft[2];
980     soundLeft[2] = soundLeft[1];
981     soundLeft[1] = soundLeft[0];
982     soundLeft[0] = res;
983     res = (soundLeft[4] + 2*soundLeft[3] + 8*soundLeft[2] + 2*soundLeft[1] +
984            soundLeft[0])/14;
985   }
986 
987   switch(soundVolume) {
988   case 0:
989   case 1:
990   case 2:
991   case 3:
992     res *= (soundVolume+1);
993     break;
994   case 4:
995     res >>= 2;
996     break;
997   case 5:
998     res >>= 1;
999     break;
1000   }
1001 
1002   if(res > 32767)
1003     res = 32767;
1004   if(res < -32768)
1005     res = -32768;
1006 
1007   if(soundReverse)
1008     soundFinalWave[++soundBufferIndex] = res;
1009   else
1010     soundFinalWave[soundBufferIndex++] = res;
1011 
1012   res = 0;
1013   cgbRes = 0;
1014 
1015   if(soundBalance & 1) {
1016     cgbRes = ((s8)soundBuffer[0][soundIndex]);
1017   }
1018   if(soundBalance & 2) {
1019     cgbRes += ((s8)soundBuffer[1][soundIndex]);
1020   }
1021   if(soundBalance & 4) {
1022     cgbRes += ((s8)soundBuffer[2][soundIndex]);
1023   }
1024   if(soundBalance & 8) {
1025     cgbRes += ((s8)soundBuffer[3][soundIndex]);
1026   }
1027 
1028   if((soundControl & 0x0100) && (soundEnableFlag & 0x100)){
1029     if(!dsaRatio)
1030       res = ((s8)soundBuffer[4][soundIndex])>>1;
1031     else
1032       res = ((s8)soundBuffer[4][soundIndex]);
1033   }
1034 
1035   if((soundControl & 0x1000) && (soundEnableFlag & 0x200)){
1036     if(!dsbRatio)
1037       res += ((s8)soundBuffer[5][soundIndex])>>1;
1038     else
1039       res += ((s8)soundBuffer[5][soundIndex]);
1040   }
1041 
1042   res = (res * 170);
1043   cgbRes = (cgbRes * 52 * soundLevel1);
1044 
1045   switch(ratio) {
1046   case 0:
1047   case 3: // prohibited, but 25%
1048     cgbRes >>= 2;
1049     break;
1050   case 1:
1051     cgbRes >>= 1;
1052     break;
1053   case 2:
1054     break;
1055   }
1056 
1057   res += cgbRes;
1058 
1059   if(soundEcho) {
1060     res *= 2;
1061     res += soundFilter[soundEchoIndex];
1062     res /= 2;
1063     soundFilter[soundEchoIndex++] = res;
1064 
1065     if(soundEchoIndex >= 4000)
1066       soundEchoIndex = 0;
1067   }
1068 
1069   if(soundLowPass) {
1070     soundRight[4] = soundRight[3];
1071     soundRight[3] = soundRight[2];
1072     soundRight[2] = soundRight[1];
1073     soundRight[1] = soundRight[0];
1074     soundRight[0] = res;
1075     res = (soundRight[4] + 2*soundRight[3] + 8*soundRight[2] + 2*soundRight[1] +
1076            soundRight[0])/14;
1077   }
1078 
1079   switch(soundVolume) {
1080   case 0:
1081   case 1:
1082   case 2:
1083   case 3:
1084     res *= (soundVolume+1);
1085     break;
1086   case 4:
1087     res >>= 2;
1088     break;
1089   case 5:
1090     res >>= 1;
1091     break;
1092   }
1093 
1094   if(res > 32767)
1095     res = 32767;
1096   if(res < -32768)
1097     res = -32768;
1098 
1099   if(soundReverse)
1100     soundFinalWave[-1+soundBufferIndex++] = res;
1101   else
1102     soundFinalWave[soundBufferIndex++] = res;
1103 }
1104 
soundTick()1105 void soundTick()
1106 {
1107   if(systemSoundOn) {
1108     if(soundMasterOn && !stopState) {
1109       soundChannel1();
1110       soundChannel2();
1111       soundChannel3();
1112       soundChannel4();
1113       soundDirectSoundA();
1114       soundDirectSoundB();
1115       soundMix();
1116     } else {
1117       soundFinalWave[soundBufferIndex++] = 0;
1118       soundFinalWave[soundBufferIndex++] = 0;
1119     }
1120 
1121     soundIndex++;
1122 
1123     if(2*soundBufferIndex >= soundBufferLen) {
1124       if(systemSoundOn) {
1125         if(soundPaused) {
1126           soundResume();
1127         }
1128 
1129         systemWriteDataToSoundBuffer();
1130       }
1131       soundIndex = 0;
1132       soundBufferIndex = 0;
1133     }
1134   }
1135 }
1136 
soundShutdown()1137 void soundShutdown()
1138 {
1139   systemSoundShutdown();
1140 }
1141 
soundPause()1142 void soundPause()
1143 {
1144   systemSoundPause();
1145   soundPaused = 1;
1146 }
1147 
soundResume()1148 void soundResume()
1149 {
1150   systemSoundResume();
1151   soundPaused = 0;
1152 }
1153 
soundEnable(int channels)1154 void soundEnable(int channels)
1155 {
1156   int c = channels & 0x0f;
1157 
1158   soundEnableFlag |= ((channels & 0x30f) |c | (c << 4));
1159   if(ioMem)
1160     soundBalance = (ioMem[NR51] & soundEnableFlag);
1161 }
1162 
soundDisable(int channels)1163 void soundDisable(int channels)
1164 {
1165   int c = channels & 0x0f;
1166 
1167   soundEnableFlag &= (~((channels & 0x30f)|c|(c<<4)));
1168   if(ioMem)
1169     soundBalance = (ioMem[NR51] & soundEnableFlag);
1170 }
1171 
soundGetEnable()1172 int soundGetEnable()
1173 {
1174   return (soundEnableFlag & 0x30f);
1175 }
1176 
soundReset()1177 void soundReset()
1178 {
1179   systemSoundReset();
1180 
1181   soundPaused = 1;
1182   soundPlay = 0;
1183   SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
1184   soundTicks = SOUND_CLOCK_TICKS;
1185   soundNextPosition = 0;
1186   soundMasterOn = 1;
1187   soundIndex = 0;
1188   soundBufferIndex = 0;
1189   soundLevel1 = 7;
1190   soundLevel2 = 7;
1191 
1192   sound1On = 0;
1193   sound1ATL = 0;
1194   sound1Skip = 0;
1195   sound1Index = 0;
1196   sound1Continue = 0;
1197   sound1EnvelopeVolume =  0;
1198   sound1EnvelopeATL = 0;
1199   sound1EnvelopeUpDown = 0;
1200   sound1EnvelopeATLReload = 0;
1201   sound1SweepATL = 0;
1202   sound1SweepATLReload = 0;
1203   sound1SweepSteps = 0;
1204   sound1SweepUpDown = 0;
1205   sound1SweepStep = 0;
1206   sound1Wave = soundWavePattern[2];
1207 
1208   sound2On = 0;
1209   sound2ATL = 0;
1210   sound2Skip = 0;
1211   sound2Index = 0;
1212   sound2Continue = 0;
1213   sound2EnvelopeVolume =  0;
1214   sound2EnvelopeATL = 0;
1215   sound2EnvelopeUpDown = 0;
1216   sound2EnvelopeATLReload = 0;
1217   sound2Wave = soundWavePattern[2];
1218 
1219   sound3On = 0;
1220   sound3ATL = 0;
1221   sound3Skip = 0;
1222   sound3Index = 0;
1223   sound3Continue = 0;
1224   sound3OutputLevel = 0;
1225   sound3Last = 0;
1226   sound3Bank = 0;
1227   sound3DataSize = 0;
1228   sound3ForcedOutput = 0;
1229 
1230   sound4On = 0;
1231   sound4Clock = 0;
1232   sound4ATL = 0;
1233   sound4Skip = 0;
1234   sound4Index = 0;
1235   sound4ShiftRight = 0x7f;
1236   sound4NSteps = 0;
1237   sound4CountDown = 0;
1238   sound4Continue = 0;
1239   sound4EnvelopeVolume =  0;
1240   sound4EnvelopeATL = 0;
1241   sound4EnvelopeUpDown = 0;
1242   sound4EnvelopeATLReload = 0;
1243 
1244   sound1On = 0;
1245   sound2On = 0;
1246   sound3On = 0;
1247   sound4On = 0;
1248 
1249   int addr = 0x90;
1250 
1251   while(addr < 0xA0) {
1252     ioMem[addr++] = 0x00;
1253     ioMem[addr++] = 0xff;
1254   }
1255 
1256   addr = 0;
1257   while(addr < 0x20) {
1258     sound3WaveRam[addr++] = 0x00;
1259     sound3WaveRam[addr++] = 0xff;
1260   }
1261 
1262   memset(soundFinalWave, 0, soundBufferLen);
1263 
1264   memset(soundFilter, 0, sizeof(soundFilter));
1265   soundEchoIndex = 0;
1266 }
1267 
soundInit()1268 bool soundInit()
1269 {
1270   if(systemSoundInit()) {
1271     memset(soundBuffer[0], 0, 735*2);
1272     memset(soundBuffer[1], 0, 735*2);
1273     memset(soundBuffer[2], 0, 735*2);
1274     memset(soundBuffer[3], 0, 735*2);
1275 
1276     memset(soundFinalWave, 0, soundBufferLen);
1277 
1278     soundPaused = true;
1279     return true;
1280   }
1281   return false;
1282 }
1283 
soundSetQuality(int quality)1284 void soundSetQuality(int quality)
1285 {
1286   if(soundQuality != quality && systemCanChangeSoundQuality()) {
1287     if(!soundOffFlag)
1288       soundShutdown();
1289     soundQuality = quality;
1290     soundNextPosition = 0;
1291     if(!soundOffFlag)
1292       soundInit();
1293     SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
1294     soundIndex = 0;
1295     soundBufferIndex = 0;
1296   } else if(soundQuality != quality) {
1297     soundNextPosition = 0;
1298     SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
1299     soundIndex = 0;
1300     soundBufferIndex = 0;
1301   }
1302 }
1303 
soundSaveGame(gzFile gzFile)1304 void soundSaveGame(gzFile gzFile)
1305 {
1306   utilWriteData(gzFile, soundSaveStruct);
1307   utilWriteData(gzFile, soundSaveStructV2);
1308 
1309   utilGzWrite(gzFile, &soundQuality, sizeof(int));
1310 }
1311 
soundReadGame(gzFile gzFile,int version)1312 void soundReadGame(gzFile gzFile, int version)
1313 {
1314   utilReadData(gzFile, soundSaveStruct);
1315   if(version >= SAVE_GAME_VERSION_3) {
1316     utilReadData(gzFile, soundSaveStructV2);
1317   } else {
1318     sound3Bank = (ioMem[NR30] >> 6) & 1;
1319     sound3DataSize = (ioMem[NR30] >> 5) & 1;
1320     sound3ForcedOutput = (ioMem[NR32] >> 7) & 1;
1321     // nothing better to do here...
1322     memcpy(&sound3WaveRam[0x00], &ioMem[0x90], 0x10);
1323     memcpy(&sound3WaveRam[0x10], &ioMem[0x90], 0x10);
1324   }
1325   soundBufferIndex = soundIndex * 2;
1326 
1327   int quality = 1;
1328   utilGzRead(gzFile, &quality, sizeof(int));
1329   soundSetQuality(quality);
1330 
1331   sound1Wave = soundWavePattern[ioMem[NR11] >> 6];
1332   sound2Wave = soundWavePattern[ioMem[NR21] >> 6];
1333 }
1334