home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / Sound.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  30.6 KB  |  1,334 lines

  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  845. void soundDirectSoundA()
  846. {
  847.   soundBuffer[4][soundIndex] = soundDSAValue;
  848. }
  849.  
  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.  
  874. void soundDirectSoundB()
  875. {
  876.   soundBuffer[5][soundIndex] = soundDSBValue;
  877. }
  878.  
  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.  
  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.  
  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.  
  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.  
  1137. void soundShutdown()
  1138. {
  1139.   systemSoundShutdown();
  1140. }
  1141.  
  1142. void soundPause()
  1143. {
  1144.   systemSoundPause();
  1145.   soundPaused = 1;
  1146. }
  1147.  
  1148. void soundResume()
  1149. {
  1150.   systemSoundResume();
  1151.   soundPaused = 0;
  1152. }
  1153.  
  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.  
  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.  
  1172. int soundGetEnable()
  1173. {
  1174.   return (soundEnableFlag & 0x30f);
  1175. }
  1176.  
  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.  
  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.  
  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.  
  1304. void soundSaveGame(gzFile gzFile)
  1305. {
  1306.   utilWriteData(gzFile, soundSaveStruct);
  1307.   utilWriteData(gzFile, soundSaveStructV2);
  1308.   
  1309.   utilGzWrite(gzFile, &soundQuality, sizeof(int));
  1310. }
  1311.  
  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.