12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925 |
- /*
- Copyright (C) 1994-1995 Apogee Software, Ltd.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /**********************************************************************
- module: PAS16.C
- author: James R. Dose
- date: March 27, 1994
- Low level routines to support Pro AudioSpectrum and compatible
- sound cards.
- (c) Copyright 1994 James R. Dose. All Rights Reserved.
- **********************************************************************/
- #include <dos.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "dpmi.h"
- #include "dma.h"
- #include "interrup.h"
- #include "irq.h"
- #include "pas16.h"
- #include "_pas16.h"
- #define USESTACK
- static const int PAS_Interrupts[ PAS_MaxIrq + 1 ] =
- {
- INVALID, INVALID, 0xa, 0xb,
- INVALID, 0xd, INVALID, 0xf,
- INVALID, INVALID, 0x72, 0x73,
- 0x74, INVALID, INVALID, 0x77
- };
- static void ( interrupt far *PAS_OldInt )( void );
- static int PAS_IntController1Mask;
- static int PAS_IntController2Mask;
- static int PAS_Installed = FALSE;
- static int PAS_TranslateCode = DEFAULT_BASE;
- static int PAS_OriginalPCMLeftVolume = 75;
- static int PAS_OriginalPCMRightVolume = 75;
- static int PAS_OriginalFMLeftVolume = 75;
- static int PAS_OriginalFMRightVolume = 75;
- unsigned int PAS_DMAChannel;
- static int PAS_Irq;
- static MVState *PAS_State = NULL;
- static MVFunc *PAS_Func = NULL;
- static MVState PAS_OriginalState;
- static int PAS_SampleSizeConfig;
- static char *PAS_DMABuffer;
- static char *PAS_DMABufferEnd;
- static char *PAS_CurrentDMABuffer;
- static int PAS_TotalDMABufferSize;
- static int PAS_TransferLength = 0;
- static int PAS_MixMode = PAS_DefaultMixMode;
- static unsigned PAS_SampleRate = PAS_DefaultSampleRate;
- static int PAS_TimeInterval = 0;
- volatile int PAS_SoundPlaying;
- void ( *PAS_CallBack )( void );
- // adequate stack size
- #define kStackSize 2048
- static unsigned short StackSelector = NULL;
- static unsigned long StackPointer;
- static unsigned short oldStackSelector;
- static unsigned long oldStackPointer;
- // This is defined because we can't create local variables in a
- // function that switches stacks.
- static int irqstatus;
- // These declarations are necessary to use the inline assembly pragmas.
- extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
- extern void SetStack(unsigned short selector,unsigned long stackptr);
- // This function will get the current stack selector and pointer and save
- // them off.
- #pragma aux GetStack = \
- "mov [edi],esp" \
- "mov ax,ss" \
- "mov [esi],ax" \
- parm [esi] [edi] \
- modify [eax esi edi];
- // This function will set the stack selector and pointer to the specified
- // values.
- #pragma aux SetStack = \
- "mov ss,ax" \
- "mov esp,edx" \
- parm [ax] [edx] \
- modify [eax edx];
- int PAS_ErrorCode = PAS_Ok;
- #define PAS_SetErrorCode( status ) \
- PAS_ErrorCode = ( status );
- /*---------------------------------------------------------------------
- Function: PAS_ErrorString
- Returns a pointer to the error message associated with an error
- number. A -1 returns a pointer the current error.
- ---------------------------------------------------------------------*/
- char *PAS_ErrorString
- (
- int ErrorNumber
- )
- {
- char *ErrorString;
- switch( ErrorNumber )
- {
- case PAS_Warning :
- case PAS_Error :
- ErrorString = PAS_ErrorString( PAS_ErrorCode );
- break;
- case PAS_Ok :
- ErrorString = "Pro AudioSpectrum ok.";
- break;
- case PAS_DriverNotFound :
- ErrorString = "MVSOUND.SYS not loaded.";
- break;
- case PAS_DmaError :
- ErrorString = DMA_ErrorString( DMA_Error );
- break;
- case PAS_InvalidIrq :
- ErrorString = "Invalid Pro AudioSpectrum Irq.";
- break;
- case PAS_UnableToSetIrq :
- ErrorString = "Unable to set Pro AudioSpectrum IRQ. Try selecting an IRQ of 7 or below.";
- break;
- case PAS_Dos4gwIrqError :
- ErrorString = "Unsupported Pro AudioSpectrum Irq.";
- break;
- case PAS_NoSoundPlaying :
- ErrorString = "No sound playing on Pro AudioSpectrum.";
- break;
- case PAS_CardNotFound :
- ErrorString = "Could not find Pro AudioSpectrum.";
- break;
- case PAS_DPMI_Error :
- ErrorString = "DPMI Error in PAS16.";
- break;
- case PAS_OutOfMemory :
- ErrorString = "Out of conventional memory in PAS16.";
- break;
- default :
- ErrorString = "Unknown Pro AudioSpectrum error code.";
- break;
- }
- return( ErrorString );
- }
- /**********************************************************************
- Memory locked functions:
- **********************************************************************/
- #define PAS_LockStart PAS_CheckForDriver
- /*---------------------------------------------------------------------
- Function: PAS_CheckForDriver
- Checks to see if MVSOUND.SYS is installed.
- ---------------------------------------------------------------------*/
- int PAS_CheckForDriver
- (
- void
- )
- {
- union REGS regs;
- unsigned result;
- regs.w.ax = MV_CheckForDriver;
- regs.w.bx = 0x3f3f;
- #ifdef __386__
- int386( MV_SoundInt, ®s, ®s );
- #else
- int86( MV_SoundInt, ®s, ®s );
- #endif
- if ( regs.w.ax != MV_CheckForDriver )
- {
- PAS_SetErrorCode( PAS_DriverNotFound );
- return( PAS_Error );
- }
- result = regs.w.bx ^ regs.w.cx ^ regs.w.dx;
- if ( result != MV_Signature )
- {
- PAS_SetErrorCode( PAS_DriverNotFound );
- return( PAS_Error );
- }
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetStateTable
- Returns a pointer to the state table containing hardware state
- information. The state table is necessary because the Pro Audio-
- Spectrum contains only write-only registers.
- ---------------------------------------------------------------------*/
- MVState *PAS_GetStateTable
- (
- void
- )
- {
- union REGS regs;
- MVState *ptr;
- regs.w.ax = MV_GetPointerToStateTable;
- #ifdef __386__
- int386( MV_SoundInt, ®s, ®s );
- #else
- int86( MV_SoundInt, ®s, ®s );
- #endif
- if ( regs.w.ax != MV_Signature )
- {
- PAS_SetErrorCode( PAS_DriverNotFound );
- return( NULL );
- }
- #if defined(__WATCOMC__) && defined(__FLAT__)
- ptr = ( MVState * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
- ( ( unsigned )regs.w.bx ) );
- #else
- ptr = MK_FP( regs.w.dx, regs.w.bx );
- #endif
- return( ptr );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetFunctionTable
- Returns a pointer to the function table containing addresses of
- driver functions.
- ---------------------------------------------------------------------*/
- MVFunc *PAS_GetFunctionTable
- (
- void
- )
- {
- union REGS regs;
- MVFunc *ptr;
- regs.w.ax = MV_GetPointerToFunctionTable;
- #ifdef __386__
- int386( MV_SoundInt, ®s, ®s );
- #else
- int86( MV_SoundInt, ®s, ®s );
- #endif
- if ( regs.w.ax != MV_Signature )
- {
- PAS_SetErrorCode( PAS_DriverNotFound );
- return( NULL );
- }
- #if defined(__WATCOMC__) && defined(__FLAT__)
- ptr = ( MVFunc * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
- ( ( unsigned )regs.w.bx ) );
- #else
- ptr = MK_FP( regs.w.dx, regs.w.bx );
- #endif
- return( ptr );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetCardSettings
- Returns the DMA and the IRQ channels of the sound card.
- ---------------------------------------------------------------------*/
- int PAS_GetCardSettings
- (
- void
- )
- {
- union REGS regs;
- int status;
- regs.w.ax = MV_GetDmaIrqInt;
- #ifdef __386__
- int386( MV_SoundInt, ®s, ®s );
- #else
- int86( MV_SoundInt, ®s, ®s );
- #endif
- if ( regs.w.ax != MV_Signature )
- {
- PAS_SetErrorCode( PAS_DriverNotFound );
- return( PAS_Error );
- }
- PAS_DMAChannel = regs.w.bx;
- PAS_Irq = regs.w.cx;
- if ( PAS_Irq > PAS_MaxIrq )
- {
- PAS_SetErrorCode( PAS_Dos4gwIrqError );
- return( PAS_Error );
- }
- if ( !VALID_IRQ( PAS_Irq ) )
- {
- PAS_SetErrorCode( PAS_InvalidIrq );
- return( PAS_Error );
- }
- if ( PAS_Interrupts[ PAS_Irq ] == INVALID )
- {
- PAS_SetErrorCode( PAS_InvalidIrq );
- return( PAS_Error );
- }
- status = DMA_VerifyChannel( PAS_DMAChannel );
- if ( status == DMA_Error )
- {
- PAS_SetErrorCode( PAS_DmaError );
- return( PAS_Error );
- }
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_EnableInterrupt
- Enables the triggering of the sound card interrupt.
- ---------------------------------------------------------------------*/
- void PAS_EnableInterrupt
- (
- void
- )
- {
- int mask;
- int data;
- unsigned flags;
- flags = DisableInterrupts();
- if ( PAS_Irq < 8 )
- {
- mask = inp( 0x21 ) & ~( 1 << PAS_Irq );
- outp( 0x21, mask );
- }
- else
- {
- mask = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
- outp( 0xA1, mask );
- mask = inp( 0x21 ) & ~( 1 << 2 );
- outp( 0x21, mask );
- }
- // Flush any pending interrupts
- PAS_Write( InterruptStatus, PAS_Read( InterruptStatus ) & 0x40 );
- // Enable the interrupt on the PAS
- data = PAS_State->intrctlr;
- data |= SampleBufferInterruptFlag;
- PAS_Write( InterruptControl, data );
- PAS_State->intrctlr = data;
- RestoreInterrupts( flags );
- }
- /*---------------------------------------------------------------------
- Function: PAS_DisableInterrupt
- Disables the triggering of the sound card interrupt.
- ---------------------------------------------------------------------*/
- void PAS_DisableInterrupt
- (
- void
- )
- {
- int mask;
- int data;
- unsigned flags;
- flags = DisableInterrupts();
- // Disable the interrupt on the PAS
- data = PAS_State->intrctlr;
- data &= ~( SampleRateInterruptFlag | SampleBufferInterruptFlag );
- PAS_Write( InterruptControl, data );
- PAS_State->intrctlr = data;
- // Restore interrupt mask
- if ( PAS_Irq < 8 )
- {
- mask = inp( 0x21 ) & ~( 1 << PAS_Irq );
- mask |= PAS_IntController1Mask & ( 1 << PAS_Irq );
- outp( 0x21, mask );
- }
- else
- {
- mask = inp( 0x21 ) & ~( 1 << 2 );
- mask |= PAS_IntController1Mask & ( 1 << 2 );
- outp( 0x21, mask );
- mask = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
- mask |= PAS_IntController2Mask & ( 1 << ( PAS_Irq - 8 ) );
- outp( 0xA1, mask );
- }
- RestoreInterrupts( flags );
- }
- /*---------------------------------------------------------------------
- Function: PAS_ServiceInterrupt
- Handles interrupt generated by sound card at the end of a voice
- transfer. Calls the user supplied callback function.
- ---------------------------------------------------------------------*/
- void interrupt far PAS_ServiceInterrupt
- (
- void
- )
- {
- #ifdef USESTACK
- // save stack
- GetStack( &oldStackSelector, &oldStackPointer );
- // set our stack
- SetStack( StackSelector, StackPointer );
- #endif
- irqstatus = PAS_Read( InterruptStatus );
- if ( ( irqstatus & SampleBufferInterruptFlag ) == 0 )
- {
- #ifdef USESTACK
- // restore stack
- SetStack( oldStackSelector, oldStackPointer );
- #endif
- _chain_intr( PAS_OldInt );
- }
- // Clear the interrupt
- irqstatus &= ~SampleBufferInterruptFlag;
- PAS_Write( InterruptStatus, irqstatus );
- // send EOI to Interrupt Controller
- if ( PAS_Irq > 7 )
- {
- outp( 0xA0, 0x20 );
- }
- outp( 0x20, 0x20 );
- // Keep track of current buffer
- PAS_CurrentDMABuffer += PAS_TransferLength;
- if ( PAS_CurrentDMABuffer >= PAS_DMABufferEnd )
- {
- PAS_CurrentDMABuffer = PAS_DMABuffer;
- }
- // Call the caller's callback function
- if ( PAS_CallBack != NULL )
- {
- PAS_CallBack();
- }
- #ifdef USESTACK
- // restore stack
- SetStack( oldStackSelector, oldStackPointer );
- #endif
- }
- /*---------------------------------------------------------------------
- Function: PAS_Write
- Writes a byte of data to the sound card.
- ---------------------------------------------------------------------*/
- void PAS_Write
- (
- int Register,
- int Data
- )
- {
- int port;
- port = Register ^ PAS_TranslateCode;
- outp( port, Data );
- }
- /*---------------------------------------------------------------------
- Function: PAS_Read
- Reads a byte of data from the sound card.
- ---------------------------------------------------------------------*/
- int PAS_Read
- (
- int Register
- )
- {
- int port;
- int data;
- port = Register ^ PAS_TranslateCode;
- data = inp( port );
- return( data );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetSampleRateTimer
- Programs the Sample Rate Timer.
- ---------------------------------------------------------------------*/
- void PAS_SetSampleRateTimer
- (
- void
- )
- {
- int LoByte;
- int HiByte;
- int data;
- unsigned flags;
- flags = DisableInterrupts();
- // Disable the Sample Rate Timer
- data = PAS_State->audiofilt;
- data &= ~SampleRateTimerGateFlag;
- PAS_Write( AudioFilterControl, data );
- PAS_State->audiofilt = data;
- // Select the Sample Rate Timer
- data = SelectSampleRateTimer;
- PAS_Write( LocalTimerControl, data );
- PAS_State->tmrctlr = data;
- LoByte = lobyte( PAS_TimeInterval );
- HiByte = hibyte( PAS_TimeInterval );
- // Program the Sample Rate Timer
- PAS_Write( SampleRateTimer, LoByte );
- PAS_Write( SampleRateTimer, HiByte );
- PAS_State->samplerate = PAS_TimeInterval;
- RestoreInterrupts( flags );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetSampleBufferCount
- Programs the Sample Buffer Count.
- ---------------------------------------------------------------------*/
- void PAS_SetSampleBufferCount
- (
- void
- )
- {
- int LoByte;
- int HiByte;
- int count;
- int data;
- unsigned flags;
- flags = DisableInterrupts();
- // Disable the Sample Buffer Count
- data = PAS_State->audiofilt;
- data &= ~SampleBufferCountGateFlag;
- PAS_Write( AudioFilterControl, data );
- PAS_State->audiofilt = data;
- // Select the Sample Buffer Count
- data = SelectSampleBufferCount;
- PAS_Write( LocalTimerControl, data );
- PAS_State->tmrctlr = data;
- count = PAS_TransferLength;
- // Check if we're using a 16-bit DMA channel
- if ( PAS_DMAChannel > 3 )
- {
- count >>= 1;
- }
- LoByte = lobyte( count );
- HiByte = hibyte( count );
- // Program the Sample Buffer Count
- PAS_Write( SampleBufferCount, LoByte );
- PAS_Write( SampleBufferCount, HiByte );
- PAS_State->samplecnt = count;
- RestoreInterrupts( flags );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetPlaybackRate
- Sets the rate at which the digitized sound will be played in
- hertz.
- ---------------------------------------------------------------------*/
- void PAS_SetPlaybackRate
- (
- unsigned rate
- )
- {
- if ( rate < PAS_MinSamplingRate )
- {
- rate = PAS_MinSamplingRate;
- }
- if ( rate > PAS_MaxSamplingRate )
- {
- rate = PAS_MaxSamplingRate;
- }
- PAS_TimeInterval = ( unsigned )CalcTimeInterval( rate );
- if ( PAS_MixMode & STEREO )
- {
- PAS_TimeInterval /= 2;
- }
- // Keep track of what the actual rate is
- PAS_SampleRate = CalcSamplingRate( PAS_TimeInterval );
- if ( PAS_MixMode & STEREO )
- {
- PAS_SampleRate /= 2;
- }
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetPlaybackRate
- Returns the rate at which the digitized sound will be played in
- hertz.
- ---------------------------------------------------------------------*/
- unsigned PAS_GetPlaybackRate
- (
- void
- )
- {
- return( PAS_SampleRate );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetMixMode
- Sets the sound card to play samples in mono or stereo.
- ---------------------------------------------------------------------*/
- int PAS_SetMixMode
- (
- int mode
- )
- {
- mode &= PAS_MaxMixMode;
- // Check board revision. Revision # 0 can't play 16-bit data.
- if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
- {
- // Force the mode to 8-bit data.
- mode &= ~SIXTEEN_BIT;
- }
- PAS_MixMode = mode;
- PAS_SetPlaybackRate( PAS_SampleRate );
- return( mode );
- }
- /*---------------------------------------------------------------------
- Function: PAS_StopPlayback
- Ends the DMA transfer of digitized sound to the sound card.
- ---------------------------------------------------------------------*/
- void PAS_StopPlayback
- (
- void
- )
- {
- int data;
- // Don't allow anymore interrupts
- PAS_DisableInterrupt();
- // Stop the transfer of digital data
- data = PAS_State->crosschannel;
- data &= PAS_PCMStopMask;
- PAS_Write( CrossChannelControl, data );
- PAS_State->crosschannel = data;
- // Turn off 16-bit unsigned data
- data = PAS_Read( SampleSizeConfiguration );
- data &= PAS_SampleSizeMask;
- PAS_Write( SampleSizeConfiguration, data );
- // Disable the DMA channel
- DMA_EndTransfer( PAS_DMAChannel );
- PAS_SoundPlaying = FALSE;
- PAS_DMABuffer = NULL;
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetupDMABuffer
- Programs the DMAC for sound transfer.
- ---------------------------------------------------------------------*/
- int PAS_SetupDMABuffer
- (
- char *BufferPtr,
- int BufferSize,
- int mode
- )
- {
- int DmaStatus;
- int data;
- // Enable PAS Dma
- data = PAS_State->crosschannel;
- data |= PAS_DMAEnable;
- PAS_Write( CrossChannelControl, data );
- PAS_State->crosschannel = data;
- DmaStatus = DMA_SetupTransfer( PAS_DMAChannel, BufferPtr, BufferSize, mode );
- if ( DmaStatus == DMA_Error )
- {
- PAS_SetErrorCode( PAS_DmaError );
- return( PAS_Error );
- }
- PAS_DMABuffer = BufferPtr;
- PAS_CurrentDMABuffer = BufferPtr;
- PAS_TotalDMABufferSize = BufferSize;
- PAS_DMABufferEnd = BufferPtr + BufferSize;
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetCurrentPos
- Returns the offset within the current sound being played.
- ---------------------------------------------------------------------*/
- int PAS_GetCurrentPos
- (
- void
- )
- {
- char *CurrentAddr;
- int offset;
- if ( !PAS_SoundPlaying )
- {
- PAS_SetErrorCode( PAS_NoSoundPlaying );
- return( PAS_Error );
- }
- CurrentAddr = DMA_GetCurrentPos( PAS_DMAChannel );
- if ( CurrentAddr == NULL )
- {
- PAS_SetErrorCode( PAS_DmaError );
- return( PAS_Error );
- }
- offset = ( int )( ( ( unsigned long )CurrentAddr ) -
- ( ( unsigned long )PAS_CurrentDMABuffer ) );
- if ( PAS_MixMode & SIXTEEN_BIT )
- {
- offset >>= 1;
- }
- if ( PAS_MixMode & STEREO )
- {
- offset >>= 1;
- }
- return( offset );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetFilterSetting
- Returns the bit settings for the appropriate filter level.
- ---------------------------------------------------------------------*/
- int PAS_GetFilterSetting
- (
- int rate
- )
- {
- /* CD Quality 17897hz */
- if ( ( unsigned long )rate > ( unsigned long )17897L * 2 )
- {
- /* 00001b 20hz to 17.8khz */
- return( 0x01 );
- }
- /* Cassette Quality 15090hz */
- if ( ( unsigned long )rate > ( unsigned long )15909L * 2 )
- {
- /* 00010b 20hz to 15.9khz */
- return( 0x02 );
- }
- /* FM Radio Quality 11931hz */
- if ( ( unsigned long )rate > ( unsigned long )11931L * 2 )
- {
- /* 01001b 20hz to 11.9khz */
- return( 0x09 );
- }
- /* AM Radio Quality 8948hz */
- if ( ( unsigned long )rate > ( unsigned long )8948L * 2 )
- {
- /* 10001b 20hz to 8.9khz */
- return( 0x11 );
- }
- /* Telphone Quality 5965hz */
- if ( ( unsigned long )rate > ( unsigned long )5965L * 2 )
- {
- /* 00100b 20hz to 5.9khz */
- return( 0x19 );
- }
- /* Male voice quality 2982hz */
- /* 111001b 20hz to 2.9khz */
- return( 0x04 );
- }
- /*---------------------------------------------------------------------
- Function: PAS_BeginTransfer
- Starts playback of digitized sound on the sound card.
- ---------------------------------------------------------------------*/
- void PAS_BeginTransfer
- (
- int mode
- )
- {
- int data;
- PAS_SetSampleRateTimer();
- PAS_SetSampleBufferCount();
- PAS_EnableInterrupt();
- // Get sample size configuration
- data = PAS_Read( SampleSizeConfiguration );
- // Check board revision. Revision # 0 can't play 16-bit data.
- if ( PAS_State->intrctlr & 0xe0 )
- {
- data &= PAS_SampleSizeMask;
- // set sample size bit
- if ( PAS_MixMode & SIXTEEN_BIT )
- {
- data |= PAS_16BitSampleFlag;
- }
- }
- // set oversampling rate
- data &= PAS_OverSamplingMask;
- data |= PAS_4xOverSampling;
- // Set sample size configuration
- PAS_Write( SampleSizeConfiguration, data );
- // Get Cross channel setting
- data = PAS_State->crosschannel;
- data &= PAS_ChannelConnectMask;
- if ( mode == RECORD )
- {
- data |= PAS_PCMStartADC;
- }
- else
- {
- data |= PAS_PCMStartDAC;
- }
- // set stereo mode bit
- if ( !( PAS_MixMode & STEREO ) )
- {
- data |= PAS_StereoFlag;
- }
- PAS_Write( CrossChannelControl, data );
- PAS_State->crosschannel = data;
- // Get the filter appropriate filter setting
- data = PAS_GetFilterSetting( PAS_SampleRate );
- // Enable the Sample Rate Timer and Sample Buffer Count
- data |= SampleRateTimerGateFlag | SampleBufferCountGateFlag;
- if ( mode != RECORD )
- {
- // Enable audio (not Audio Mute)
- data |= PAS_AudioMuteFlag;
- }
- PAS_Write( AudioFilterControl, data );
- PAS_State->audiofilt = data;
- PAS_SoundPlaying = TRUE;
- }
- /*---------------------------------------------------------------------
- Function: PAS_BeginBufferedPlayback
- Begins multibuffered playback of digitized sound on the sound card.
- ---------------------------------------------------------------------*/
- int PAS_BeginBufferedPlayback
- (
- char *BufferStart,
- int BufferSize,
- int NumDivisions,
- unsigned SampleRate,
- int MixMode,
- void ( *CallBackFunc )( void )
- )
- {
- int DmaStatus;
- PAS_StopPlayback();
- PAS_SetMixMode( MixMode );
- PAS_SetPlaybackRate( SampleRate );
- PAS_TransferLength = BufferSize / NumDivisions;
- PAS_SetCallBack( CallBackFunc );
- DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
- if ( DmaStatus == PAS_Error )
- {
- return( PAS_Error );
- }
- PAS_BeginTransfer( PLAYBACK );
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_BeginBufferedRecord
- Begins multibuffered recording of digitized sound on the sound card.
- ---------------------------------------------------------------------*/
- int PAS_BeginBufferedRecord
- (
- char *BufferStart,
- int BufferSize,
- int NumDivisions,
- unsigned SampleRate,
- int MixMode,
- void ( *CallBackFunc )( void )
- )
- {
- int DmaStatus;
- PAS_StopPlayback();
- PAS_SetMixMode( MixMode );
- PAS_SetPlaybackRate( SampleRate );
- PAS_TransferLength = BufferSize / NumDivisions;
- PAS_SetCallBack( CallBackFunc );
- DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
- if ( DmaStatus == PAS_Error )
- {
- return( PAS_Error );
- }
- PAS_BeginTransfer( RECORD );
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_CallInt
- Calls interrupt 2fh.
- ---------------------------------------------------------------------*/
- int PAS_CallInt( int ebx, int ecx, int edx );
- #pragma aux PAS_CallInt = \
- "int 2fh", \
- parm [ ebx ] [ ecx ] [ edx ] modify exact [ eax ebx ecx edx esi edi ] value [ ebx ];
- /*---------------------------------------------------------------------
- Function: PAS_CallMVFunction
- Performs a call to a real mode function.
- ---------------------------------------------------------------------*/
- int PAS_CallMVFunction
- (
- unsigned long function,
- int ebx,
- int ecx,
- int edx
- )
- {
- dpmi_regs callregs;
- int status;
- callregs.EBX = ebx;
- callregs.ECX = ecx;
- callregs.EDX = edx;
- callregs.SS = 0;
- callregs.SP = 0;
- callregs.DS = 0;
- callregs.ES = 0;
- callregs.FS = 0;
- callregs.GS = 0;
- callregs.IP = function;
- callregs.CS = function >> 16;
- status = DPMI_CallRealModeFunction( &callregs );
- if ( status != DPMI_Ok )
- {
- return( PAS_Error );
- }
- return( callregs.EBX & 0xff );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetPCMVolume
- Sets the volume of digitized sound playback.
- ---------------------------------------------------------------------*/
- int PAS_SetPCMVolume
- (
- int volume
- )
- {
- int status;
- volume = max( 0, volume );
- volume = min( volume, 255 );
- volume *= 100;
- volume /= 255;
- status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
- OUTPUTMIXER, L_PCM );
- if ( status == PAS_Error )
- {
- return( status );
- }
- status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
- OUTPUTMIXER, R_PCM );
- if ( status == PAS_Error )
- {
- return( status );
- }
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetPCMVolume
- Returns the current volume of digitized sound playback.
- ---------------------------------------------------------------------*/
- int PAS_GetPCMVolume
- (
- void
- )
- {
- int leftvolume;
- int rightvolume;
- int totalvolume;
- if ( PAS_Func == NULL )
- {
- return( PAS_Error );
- }
- leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, L_PCM );
- rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, R_PCM );
- if ( ( leftvolume == PAS_Error ) || ( rightvolume == PAS_Error ) )
- {
- return( PAS_Error );
- }
- leftvolume &= 0xff;
- rightvolume &= 0xff;
- totalvolume = ( rightvolume + leftvolume ) / 2;
- totalvolume *= 255;
- totalvolume /= 100;
- return( totalvolume );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetFMVolume
- Sets the volume of FM sound playback.
- ---------------------------------------------------------------------*/
- void PAS_SetFMVolume
- (
- int volume
- )
- {
- volume = max( 0, volume );
- volume = min( volume, 255 );
- volume *= 100;
- volume /= 255;
- if ( PAS_Func )
- {
- PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, L_FM );
- PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, R_FM );
- }
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetFMVolume
- Returns the current volume of FM sound playback.
- ---------------------------------------------------------------------*/
- int PAS_GetFMVolume
- (
- void
- )
- {
- int leftvolume;
- int rightvolume;
- int totalvolume;
- if ( PAS_Func == NULL )
- {
- return( 255 );
- }
- leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, L_FM ) & 0xff;
- rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, R_FM ) & 0xff;
- totalvolume = ( rightvolume + leftvolume ) / 2;
- totalvolume *= 255;
- totalvolume /= 100;
- totalvolume = min( 255, totalvolume );
- return( totalvolume );
- }
- /*---------------------------------------------------------------------
- Function: PAS_GetCardInfo
- Returns the maximum number of bits that can represent a sample
- (8 or 16) and the number of channels (1 for mono, 2 for stereo).
- ---------------------------------------------------------------------*/
- int PAS_GetCardInfo
- (
- int *MaxSampleBits,
- int *MaxChannels
- )
- {
- int status;
- if ( PAS_State == NULL )
- {
- status = PAS_CheckForDriver();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- PAS_State = PAS_GetStateTable();
- if ( PAS_State == NULL )
- {
- return( PAS_Error );
- }
- }
- *MaxChannels = 2;
- // Check board revision. Revision # 0 can't play 16-bit data.
- if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
- {
- *MaxSampleBits = 8;
- }
- else
- {
- *MaxSampleBits = 16;
- }
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SetCallBack
- Specifies the user function to call at the end of a sound transfer.
- ---------------------------------------------------------------------*/
- void PAS_SetCallBack
- (
- void ( *func )( void )
- )
- {
- PAS_CallBack = func;
- }
- /*---------------------------------------------------------------------
- Function: PAS_FindCard
- Auto-detects the port the Pro AudioSpectrum is set for.
- ---------------------------------------------------------------------*/
- int PAS_FindCard
- (
- void
- )
- {
- int status;
- status = PAS_TestAddress( DEFAULT_BASE );
- if ( status == 0 )
- {
- PAS_TranslateCode = DEFAULT_BASE;
- return( PAS_Ok );
- }
- status = PAS_TestAddress( ALT_BASE_1 );
- if ( status == 0 )
- {
- PAS_TranslateCode = ALT_BASE_1;
- return( PAS_Ok );
- }
- status = PAS_TestAddress( ALT_BASE_2 );
- if ( status == 0 )
- {
- PAS_TranslateCode = ALT_BASE_2;
- return( PAS_Ok );
- }
- status = PAS_TestAddress( ALT_BASE_3 );
- if ( status == 0 )
- {
- PAS_TranslateCode = ALT_BASE_3;
- return( PAS_Ok );
- }
- PAS_SetErrorCode( PAS_CardNotFound );
- return( PAS_Error );
- }
- /*---------------------------------------------------------------------
- Function: PAS_SaveMusicVolume
- Saves the user's FM mixer settings.
- ---------------------------------------------------------------------*/
- int PAS_SaveMusicVolume
- (
- void
- )
- {
- int status;
- int data;
- if ( !PAS_Installed )
- {
- status = PAS_CheckForDriver();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- PAS_State = PAS_GetStateTable();
- if ( PAS_State == NULL )
- {
- return( PAS_Error );
- }
- PAS_Func = PAS_GetFunctionTable();
- if ( PAS_Func == NULL )
- {
- return( PAS_Error );
- }
- status = PAS_GetCardSettings();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- status = PAS_FindCard();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- // Enable PAS Sound
- data = PAS_State->audiofilt;
- data |= PAS_AudioMuteFlag;
- PAS_Write( AudioFilterControl, data );
- PAS_State->audiofilt = data;
- }
- status = PAS_CallMVFunction( PAS_Func->GetMixer, 0, OUTPUTMIXER, L_FM );
- if ( status != PAS_Error )
- {
- PAS_OriginalFMLeftVolume = PAS_CallMVFunction( PAS_Func->GetMixer,
- 0, OUTPUTMIXER, L_FM ) & 0xff;
- PAS_OriginalFMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer,
- 0, OUTPUTMIXER, R_FM ) & 0xff;
- return( PAS_Ok );
- }
- return( PAS_Warning );
- }
- /*---------------------------------------------------------------------
- Function: PAS_RestoreMusicVolume
- Restores the user's FM mixer settings.
- ---------------------------------------------------------------------*/
- void PAS_RestoreMusicVolume
- (
- void
- )
- {
- if ( PAS_Func )
- {
- PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMLeftVolume,
- OUTPUTMIXER, L_FM );
- PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMRightVolume,
- OUTPUTMIXER, R_FM );
- }
- }
- /*---------------------------------------------------------------------
- Function: PAS_SaveState
- Saves the original state of the PAS prior to use.
- ---------------------------------------------------------------------*/
- void PAS_SaveState
- (
- void
- )
- {
- PAS_OriginalState.intrctlr = PAS_State->intrctlr;
- PAS_OriginalState.audiofilt = PAS_State->audiofilt;
- PAS_OriginalState.tmrctlr = PAS_State->tmrctlr;
- PAS_OriginalState.samplerate = PAS_State->samplerate;
- PAS_OriginalState.samplecnt = PAS_State->samplecnt;
- PAS_OriginalState.crosschannel = PAS_State->crosschannel;
- PAS_SampleSizeConfig = PAS_Read( SampleSizeConfiguration );
- }
- /*---------------------------------------------------------------------
- Function: PAS_RestoreState
- Restores the original state of the PAS after use.
- ---------------------------------------------------------------------*/
- void PAS_RestoreState
- (
- void
- )
- {
- int LoByte;
- int HiByte;
- // Select the Sample Rate Timer
- PAS_Write( LocalTimerControl, SelectSampleRateTimer );
- PAS_State->tmrctlr = SelectSampleRateTimer;
- PAS_Write( SampleRateTimer, PAS_OriginalState.samplerate );
- PAS_State->samplerate = PAS_OriginalState.samplerate;
- // Select the Sample Buffer Count
- PAS_Write( LocalTimerControl, SelectSampleBufferCount );
- PAS_State->tmrctlr = SelectSampleBufferCount;
- LoByte = lobyte( PAS_OriginalState.samplecnt );
- HiByte = hibyte( PAS_OriginalState.samplecnt );
- PAS_Write( SampleRateTimer, LoByte );
- PAS_Write( SampleRateTimer, HiByte );
- PAS_State->samplecnt = PAS_OriginalState.samplecnt;
- PAS_Write( CrossChannelControl, PAS_OriginalState.crosschannel );
- PAS_State->crosschannel = PAS_OriginalState.crosschannel;
- PAS_Write( SampleSizeConfiguration, PAS_SampleSizeConfig );
- PAS_Write( InterruptControl, PAS_OriginalState.intrctlr );
- PAS_State->intrctlr = PAS_OriginalState.intrctlr;
- PAS_Write( AudioFilterControl, PAS_OriginalState.audiofilt );
- PAS_State->audiofilt = PAS_OriginalState.audiofilt;
- PAS_Write( LocalTimerControl, PAS_OriginalState.tmrctlr );
- PAS_State->tmrctlr = PAS_OriginalState.tmrctlr;
- }
- /*---------------------------------------------------------------------
- Function: PAS_LockEnd
- Used for determining the length of the functions to lock in memory.
- ---------------------------------------------------------------------*/
- static void PAS_LockEnd
- (
- void
- )
- {
- }
- /*---------------------------------------------------------------------
- Function: allocateTimerStack
- Allocate a block of memory from conventional (low) memory and return
- the selector (which can go directly into a segment register) of the
- memory block or 0 if an error occured.
- ---------------------------------------------------------------------*/
- static unsigned short allocateTimerStack
- (
- unsigned short size
- )
- {
- union REGS regs;
- // clear all registers
- memset( ®s, 0, sizeof( regs ) );
- // DPMI allocate conventional memory
- regs.w.ax = 0x100;
- // size in paragraphs
- regs.w.bx = ( size + 15 ) / 16;
- int386( 0x31, ®s, ®s );
- if (!regs.w.cflag)
- {
- // DPMI call returns selector in dx
- // (ax contains real mode segment
- // which is ignored here)
- return( regs.w.dx );
- }
- // Couldn't allocate memory.
- return( NULL );
- }
- /*---------------------------------------------------------------------
- Function: deallocateTimerStack
- Deallocate a block of conventional (low) memory given a selector to
- it. Assumes the block was allocated with DPMI function 0x100.
- ---------------------------------------------------------------------*/
- static void deallocateTimerStack
- (
- unsigned short selector
- )
- {
- union REGS regs;
- if ( selector != NULL )
- {
- // clear all registers
- memset( ®s, 0, sizeof( regs ) );
- regs.w.ax = 0x101;
- regs.w.dx = selector;
- int386( 0x31, ®s, ®s );
- }
- }
- /*---------------------------------------------------------------------
- Function: PAS_Init
- Initializes the sound card and prepares the module to play
- digitized sounds.
- ---------------------------------------------------------------------*/
- int PAS_Init
- (
- void
- )
- {
- int Interrupt;
- int status;
- int data;
- if ( PAS_Installed )
- {
- return( PAS_Ok );
- }
- PAS_IntController1Mask = inp( 0x21 );
- PAS_IntController2Mask = inp( 0xA1 );
- status = PAS_CheckForDriver();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- PAS_State = PAS_GetStateTable();
- if ( PAS_State == NULL )
- {
- return( PAS_Error );
- }
- PAS_Func = PAS_GetFunctionTable();
- if ( PAS_Func == NULL )
- {
- return( PAS_Error );
- }
- status = PAS_GetCardSettings();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- status = PAS_FindCard();
- if ( status != PAS_Ok )
- {
- return( status );
- }
- PAS_SaveState();
- PAS_OriginalPCMLeftVolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, L_PCM ) & 0xff;
- PAS_OriginalPCMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
- OUTPUTMIXER, R_PCM ) & 0xff;
- PAS_SoundPlaying = FALSE;
- PAS_SetCallBack( NULL );
- PAS_DMABuffer = NULL;
- status = PAS_LockMemory();
- if ( status != PAS_Ok )
- {
- PAS_UnlockMemory();
- return( status );
- }
- StackSelector = allocateTimerStack( kStackSize );
- if ( StackSelector == NULL )
- {
- PAS_UnlockMemory();
- PAS_SetErrorCode( PAS_OutOfMemory );
- return( PAS_Error );
- }
- // Leave a little room at top of stack just for the hell of it...
- StackPointer = kStackSize - sizeof( long );
- // Install our interrupt handler
- Interrupt = PAS_Interrupts[ PAS_Irq ];
- PAS_OldInt = _dos_getvect( Interrupt );
- if ( PAS_Irq < 8 )
- {
- _dos_setvect( Interrupt, PAS_ServiceInterrupt );
- }
- else
- {
- status = IRQ_SetVector( Interrupt, PAS_ServiceInterrupt );
- if ( status != IRQ_Ok )
- {
- PAS_UnlockMemory();
- deallocateTimerStack( StackSelector );
- StackSelector = NULL;
- PAS_SetErrorCode( PAS_UnableToSetIrq );
- return( PAS_Error );
- }
- }
- // Enable PAS Sound
- data = PAS_State->audiofilt;
- data |= PAS_AudioMuteFlag;
- PAS_Write( AudioFilterControl, data );
- PAS_State->audiofilt = data;
- PAS_SetPlaybackRate( PAS_DefaultSampleRate );
- PAS_SetMixMode( PAS_DefaultMixMode );
- PAS_Installed = TRUE;
- PAS_SetErrorCode( PAS_Ok );
- return( PAS_Ok );
- }
- /*---------------------------------------------------------------------
- Function: PAS_Shutdown
- Ends transfer of sound data to the sound card and restores the
- system resources used by the card.
- ---------------------------------------------------------------------*/
- void PAS_Shutdown
- (
- void
- )
- {
- int Interrupt;
- if ( PAS_Installed )
- {
- // Halt the DMA transfer
- PAS_StopPlayback();
- // Restore the original interrupt
- Interrupt = PAS_Interrupts[ PAS_Irq ];
- if ( PAS_Irq >= 8 )
- {
- IRQ_RestoreVector( Interrupt );
- }
- _dos_setvect( Interrupt, PAS_OldInt );
- PAS_SoundPlaying = FALSE;
- PAS_DMABuffer = NULL;
- PAS_SetCallBack( NULL );
- PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMLeftVolume,
- OUTPUTMIXER, L_PCM );
- PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMRightVolume,
- OUTPUTMIXER, R_PCM );
- // DEBUG
- // PAS_RestoreState();
- PAS_UnlockMemory();
- deallocateTimerStack( StackSelector );
- StackSelector = NULL;
- PAS_Installed = FALSE;
- }
- }
- /*---------------------------------------------------------------------
- Function: PAS_UnlockMemory
- Unlocks all neccessary data.
- ---------------------------------------------------------------------*/
- void PAS_UnlockMemory
- (
- void
- )
- {
- DPMI_UnlockMemoryRegion( PAS_LockStart, PAS_LockEnd );
- DPMI_Unlock( PAS_Interrupts );
- DPMI_Unlock( PAS_OldInt );
- DPMI_Unlock( PAS_IntController1Mask );
- DPMI_Unlock( PAS_IntController2Mask );
- DPMI_Unlock( PAS_Installed );
- DPMI_Unlock( PAS_TranslateCode );
- DPMI_Unlock( PAS_OriginalPCMLeftVolume );
- DPMI_Unlock( PAS_OriginalPCMRightVolume );
- DPMI_Unlock( PAS_OriginalFMLeftVolume );
- DPMI_Unlock( PAS_OriginalFMRightVolume );
- DPMI_Unlock( PAS_DMAChannel );
- DPMI_Unlock( PAS_Irq );
- DPMI_Unlock( PAS_State );
- DPMI_Unlock( PAS_Func );
- DPMI_Unlock( PAS_OriginalState );
- DPMI_Unlock( PAS_SampleSizeConfig );
- DPMI_Unlock( PAS_DMABuffer );
- DPMI_Unlock( PAS_DMABufferEnd );
- DPMI_Unlock( PAS_CurrentDMABuffer );
- DPMI_Unlock( PAS_TotalDMABufferSize );
- DPMI_Unlock( PAS_TransferLength );
- DPMI_Unlock( PAS_MixMode );
- DPMI_Unlock( PAS_SampleRate );
- DPMI_Unlock( PAS_TimeInterval );
- DPMI_Unlock( PAS_SoundPlaying );
- DPMI_Unlock( PAS_CallBack );
- DPMI_Unlock( PAS_ErrorCode );
- DPMI_Unlock( irqstatus );
- }
- /*---------------------------------------------------------------------
- Function: PAS_LockMemory
- Locks all neccessary data.
- ---------------------------------------------------------------------*/
- int PAS_LockMemory
- (
- void
- )
- {
- int status;
- status = DPMI_LockMemoryRegion( PAS_LockStart, PAS_LockEnd );
- status |= DPMI_Lock( PAS_Interrupts );
- status |= DPMI_Lock( PAS_OldInt );
- status |= DPMI_Lock( PAS_IntController1Mask );
- status |= DPMI_Lock( PAS_IntController2Mask );
- status |= DPMI_Lock( PAS_Installed );
- status |= DPMI_Lock( PAS_TranslateCode );
- status |= DPMI_Lock( PAS_OriginalPCMLeftVolume );
- status |= DPMI_Lock( PAS_OriginalPCMRightVolume );
- status |= DPMI_Lock( PAS_OriginalFMLeftVolume );
- status |= DPMI_Lock( PAS_OriginalFMRightVolume );
- status |= DPMI_Lock( PAS_DMAChannel );
- status |= DPMI_Lock( PAS_Irq );
- status |= DPMI_Lock( PAS_State );
- status |= DPMI_Lock( PAS_Func );
- status |= DPMI_Lock( PAS_OriginalState );
- status |= DPMI_Lock( PAS_SampleSizeConfig );
- status |= DPMI_Lock( PAS_DMABuffer );
- status |= DPMI_Lock( PAS_DMABufferEnd );
- status |= DPMI_Lock( PAS_CurrentDMABuffer );
- status |= DPMI_Lock( PAS_TotalDMABufferSize );
- status |= DPMI_Lock( PAS_TransferLength );
- status |= DPMI_Lock( PAS_MixMode );
- status |= DPMI_Lock( PAS_SampleRate );
- status |= DPMI_Lock( PAS_TimeInterval );
- status |= DPMI_Lock( PAS_SoundPlaying );
- status |= DPMI_Lock( PAS_CallBack );
- status |= DPMI_Lock( PAS_ErrorCode );
- status |= DPMI_Lock( irqstatus );
- if ( status != DPMI_Ok )
- {
- PAS_UnlockMemory();
- PAS_SetErrorCode( PAS_DPMI_Error );
- return( PAS_Error );
- }
- return( PAS_Ok );
- }
|