-#if 0\r
-//\r
-// SoundBlaster code\r
-//\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBStopSample() - Stops any active sampled sound and causes DMA\r
-// requests from the SoundBlaster to cease\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_SBStopSample(void)\r
-{\r
- byte is;\r
-\r
-asm pushf\r
-asm cli\r
-\r
- if (sbSamplePlaying)\r
- {\r
- sbSamplePlaying = false;\r
-\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0xd0); // Turn off DSP DMA\r
-\r
- is = inportb(0x21); // Restore interrupt mask bit\r
- if (sbOldIntMask & (1 << sbInterrupt))\r
- is |= (1 << sbInterrupt);\r
- else\r
- is &= ~(1 << sbInterrupt);\r
- outportb(0x21,is);\r
- }\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBPlaySeg() - Plays a chunk of sampled sound on the SoundBlaster\r
-// Insures that the chunk doesn't cross a bank boundary, programs the DMA\r
-// controller, and tells the SB to start doing DMA requests for DAC\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static dword\r
-SDL_SBPlaySeg(volatile byte huge *data,dword length)\r
-{\r
- unsigned datapage;\r
- dword dataofs,uselen;\r
-\r
- uselen = length;\r
- datapage = FP_SEG(data) >> 12;\r
- dataofs = ((FP_SEG(data) & 0xfff) << 4) + FP_OFF(data);\r
- if (dataofs >= 0x10000)\r
- {\r
- datapage++;\r
- dataofs -= 0x10000;\r
- }\r
-\r
- if (dataofs + uselen > 0x10000)\r
- uselen = 0x10000 - dataofs;\r
-\r
- uselen--;\r
-\r
- // Program the DMA controller\r
-asm pushf\r
-asm cli\r
- outportb(0x0a,sbDMA | 4); // Mask off DMA on channel sbDMA\r
- outportb(0x0c,0); // Clear byte ptr flip-flop to lower byte\r
- outportb(0x0b,0x49); // Set transfer mode for D/A conv\r
- outportb(sbDMAa2,(byte)dataofs); // Give LSB of address\r
- outportb(sbDMAa2,(byte)(dataofs >> 8)); // Give MSB of address\r
- outportb(sbDMAa1,(byte)datapage); // Give page of address\r
- outportb(sbDMAa3,(byte)uselen); // Give LSB of length\r
- outportb(sbDMAa3,(byte)(uselen >> 8)); // Give MSB of length\r
- outportb(0x0a,sbDMA); // Re-enable DMA on channel sbDMA\r
-\r
- // Start playing the thing\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0x14);\r
- sbWriteDelay();\r
- sbOut(sbWriteData,(byte)uselen);\r
- sbWriteDelay();\r
- sbOut(sbWriteData,(byte)(uselen >> 8));\r
-asm popf\r
-\r
- return(uselen + 1);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBService() - Services the SoundBlaster DMA interrupt\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-/*static*/ void interrupt\r
-SDL_SBService(void)\r
-{\r
- dword used;\r
-\r
- sbIn(sbDataAvail); // Ack interrupt to SB\r
-\r
- if (sbNextSegPtr)\r
- {\r
- used = SDL_SBPlaySeg(sbNextSegPtr,sbNextSegLen);\r
- if (sbNextSegLen <= used)\r
- sbNextSegPtr = nil;\r
- else\r
- {\r
- sbNextSegPtr += used;\r
- sbNextSegLen -= used;\r
- }\r
- }\r
- else\r
- {\r
- SDL_SBStopSample();\r
- SDL_DigitizedDone();\r
- }\r
-\r
- outportb(0x20,0x20); // Ack interrupt\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBPlaySample() - Plays a sampled sound on the SoundBlaster. Sets up\r
-// DMA to play the sound\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_SBPlaySample(byte huge *data,dword len)\r
-{\r
- dword used;\r
-\r
- SDL_SBStopSample();\r
-\r
-asm pushf\r
-asm cli\r
-\r
- used = SDL_SBPlaySeg(data,len);\r
- if (len <= used)\r
- sbNextSegPtr = nil;\r
- else\r
- {\r
- sbNextSegPtr = data + used;\r
- sbNextSegLen = len - used;\r
- }\r
-\r
- // Save old interrupt status and unmask ours\r
- sbOldIntMask = inportb(0x21);\r
- outportb(0x21,sbOldIntMask & ~(1 << sbInterrupt));\r
-\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0xd4); // Make sure DSP DMA is enabled\r
-\r
- sbSamplePlaying = true;\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_PositionSBP() - Sets the attenuation levels for the left and right\r
-// channels by using the mixer chip on the SB Pro. This hits a hole in\r
-// the address map for normal SBs.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_PositionSBP(int leftpos,int rightpos)\r
-{\r
- byte v;\r
-\r
- if (!SBProPresent)\r
- return;\r
-\r
- leftpos = 15 - leftpos;\r
- rightpos = 15 - rightpos;\r
- v = ((leftpos & 0x0f) << 4) | (rightpos & 0x0f);\r
-\r
-asm pushf\r
-asm cli\r
-\r
- sbOut(sbpMixerAddr,sbpmVoiceVol);\r
- sbOut(sbpMixerData,v);\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_CheckSB() - Checks to see if a SoundBlaster resides at a\r
-// particular I/O location\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-SDL_CheckSB(int port)\r
-{\r
- int i;\r
-\r
- sbLocation = port << 4; // Initialize stuff for later use\r
-\r
- sbOut(sbReset,true); // Reset the SoundBlaster DSP\r
-asm mov dx,0x388 // Wait >4usec\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-\r
- sbOut(sbReset,false); // Turn off sb DSP reset\r
-asm mov dx,0x388 // Wait >100usec\r
-asm mov cx,100\r
-#ifdef __WATCOMC__\r
- __asm {\r
-#endif\r
-usecloop:\r
-asm in al,dx\r
-asm loop usecloop\r
-#ifdef __WATCOMC__\r
- }\r
-#endif\r
-\r
- for (i = 0;i < 100;i++)\r
- {\r
- if (sbIn(sbDataAvail) & 0x80) // If data is available...\r
- {\r
- if (sbIn(sbReadData) == 0xaa) // If it matches correct value\r
- return(true);\r
- else\r
- {\r
- sbLocation = -1; // Otherwise not a SoundBlaster\r
- return(false);\r
- }\r
- }\r
- }\r
- sbLocation = -1; // Retry count exceeded - fail\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// Checks to see if a SoundBlaster is in the system. If the port passed is\r
-// -1, then it scans through all possible I/O locations. If the port\r
-// passed is 0, then it uses the default (2). If the port is >0, then\r
-// it just passes it directly to SDL_CheckSB()\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-SDL_DetectSoundBlaster(int port)\r
-{\r
- int i;\r
-\r
- if (port == 0) // If user specifies default, use 2\r
- port = 2;\r
- if (port == -1)\r
- {\r
- if (SDL_CheckSB(2)) // Check default before scanning\r
- return(true);\r
-\r
- if (SDL_CheckSB(4)) // Check other SB Pro location before scan\r
- return(true);\r
-\r
- for (i = 1;i <= 6;i++) // Scan through possible SB locations\r
- {\r
- if ((i == 2) || (i == 4))\r
- continue;\r
-\r
- if (SDL_CheckSB(i)) // If found at this address,\r
- return(true); // return success\r
- }\r
- return(false); // All addresses failed, return failure\r
- }\r
- else\r
- return(SDL_CheckSB(port)); // User specified address or default\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBSetDMA() - Sets the DMA channel to be used by the SoundBlaster\r
-// code. Sets up sbDMA, and sbDMAa1-sbDMAa3 (used by SDL_SBPlaySeg()).\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SDL_SBSetDMA(byte channel)\r
-{\r
- if (channel > 3)\r
- Quit("SDL_SBSetDMA() - invalid SoundBlaster DMA channel");\r
-\r
- sbDMA = channel;\r
- sbDMAa1 = sba1Vals[channel];\r
- sbDMAa2 = sba2Vals[channel];\r
- sbDMAa3 = sba3Vals[channel];\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_StartSB() - Turns on the SoundBlaster\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_StartSB(void)\r
-{\r
- byte timevalue,test;\r
-\r
- sbIntVec = sbIntVectors[sbInterrupt];\r
- if (sbIntVec < 0)\r
- Quit("SDL_StartSB: Illegal or unsupported interrupt number for SoundBlaster");\r
-\r
- sbOldIntHand = getvect(sbIntVec); // Get old interrupt handler\r
- setvect(sbIntVec,SDL_SBService); // Set mine\r