/*$Author: DCODY $*/ /*$Date: 12 Nov 1992 10:00:48 $*/ /*$Header: X:/sccs/mixers/mixerc.c_v 1.4 12 Nov 1992 10:00:48 DCODY $*/ /*$Log: X:/sccs/mixers/mixerc.c_v $ * * Rev 1.4 12 Nov 1992 10:00:48 DCODY * fixed a bug with not initializing mvver. Changes were made for * Borland 'C' compatibility. * * Rev 1.3 27 Jul 1992 12:02:46 DCODY * initialized the 32 bit vectors to 0 so they are placed in the initialized * static data segment. * * Rev 1.2 25 Jun 1992 23:49:44 DCODY * Simplified the routine by eliminating the static linked and disk * resident driver loading. * * Rev 1.1 23 Jun 1992 16:45:12 DCODY * PAS2 update * * Rev 1.0 15 Jun 1992 09:41:34 BCRANE * Initial revision. */ /*$Logfile: X:/sccs/mixers/mixerc.c_v $*/ /*$Modtimes$*/ ; /*\ ;---|*|----====< MIXERC.C >====---- ;---|*| ;---|*| Initialize and setup the access to the mixers, volume, filter, etc ;---|*| ;---|*| Copyright (c) 1991, Media Vision, Inc. All rights reserved ;---|*| ; \*/ #include #include // #include "mixbin.h" // the actual mixer code #include "state.h" // the state structure int ThePASDMAChannel = 0; // DMA channel int ThePASIRQChannel = 0; // IRQ channel static int dummyroutine (); int (far *MVSetMixerFunction) () = 0; int (far *MVSetVolumeFunction) () = 0; int (far *MVSetFilterFunction) () = 0; int (far *MVSetCrossChannel) () = 0; int (far *MVGetMixerFunction) () = 0; int (far *MVGetVolumeFunction) () = 0; int (far *MVGetFilterFunction) () = 0; int (far *MVGetCrossChannel) () = 0; int (far *MVRealSoundSwitch) () = 0; int (far *MVFMSplitSwitch) () = 0; #define STATICDRIVER 0x0000 // The static driver is loaded. #define DOSDRIVER 0x0001 // The DOS driver is loaded. // #define DISKDRIVER 0x0002 // The Disk resident driver is loaded. // shadow pointer has the active state table pointer extern struct MVState far *mvhwShadowPointer; // MVMixerHWState allows the pointer to be changed struct MVState far *MVMixerHWState(struct MVState far *); //// //// /*\ //// |*|----====< test code >====---- //// |*| //// |*| this is test code to be removed //// |*| //// \*/ //// int main() //// { //// //// // In each of the following calls, MVInitMixerCode will search for //// // the DOS driver, "MVSOUND.SYS". If found, all succeeding calls to //// // the mixers will be routed through MVSOUND.SYS. If the DOS driver //// // is not found, then either the DISK based version, or the static //// // version will be used. To select the DISK based version, pass a //// // path to MVInitMixerCode. Any pointer (other than a NULL) will tell //// // the routine to load the driver from the disk. NOTE: If loading from //// // the disk fails, then the static driver will be used. //// //// // //// // EXAMPLE #1 - The following will attempt to //// // load the driver from the disk. //// //// MVInitMixerCode ( "." ); //// //// // //// // EXAMPLE #2 - the following will use the //// // static built-in driver. //// //// MVInitMixerCode ( 0 ); //// } //// ; /*\ ;---|*|----====< MVInitMixerCode >====---- ;---|*| ;---|*| Load link to the DOS driver, or load the mixer code ;---|*| ;---|*| Entry Conditions: ;---|*| char *path is the path to the disk resident driver. ;---|*| ;---|*| Return Value: ;---|*| 0, the mixer code is using the static driver. ;---|*| 1, the mixer code is using DOS driver. ;---|*| ; \*/ int MVInitMixerCode() { char *p,*p1; int n,mx,tablelen; long far *bfp; // buffer far pointer long far *tfp; // table far pointer long mvver = 0; // MVSOUND.SYS version # static int retry = 0; // reentry flag. We will only execute once static int retcode = 0; // exit if this code has already been executed if (retry++) return(retcode); // flush some variables mx = 0; _asm { // fill in the functions in case MVSOUND.SYS is not loaded mov bx, offset dummyroutine mov word ptr [MVSetMixerFunction+0],bx mov word ptr [MVSetMixerFunction+2],cs mov word ptr [MVSetVolumeFunction+0],bx mov word ptr [MVSetVolumeFunction+2],cs mov word ptr [MVSetFilterFunction+0],bx mov word ptr [MVSetFilterFunction+2],cs mov word ptr [MVSetCrossChannel+0],bx mov word ptr [MVSetCrossChannel+2],cs mov word ptr [MVGetMixerFunction+0],bx mov word ptr [MVGetMixerFunction+2],cs mov word ptr [MVGetVolumeFunction+0],bx mov word ptr [MVGetVolumeFunction+2],cs mov word ptr [MVGetFilterFunction+0],bx mov word ptr [MVGetFilterFunction+2],cs mov word ptr [MVGetCrossChannel+0],bx mov word ptr [MVGetCrossChannel+2],cs mov word ptr [MVRealSoundSwitch+0],bx mov word ptr [MVRealSoundSwitch+2],cs mov word ptr [MVFMSplitSwitch+0],bx mov word ptr [MVFMSplitSwitch+2],cs // deterine if the DOS driver is loaded mov ax,0xbc00 // function 0 is for ID mov bx,0x3f3f sub cx,cx sub dx,dx int 2fh // go get it... xor bx,cx // combine all registers xor bx,dx cmp bx,0x4d56 // to form 'MV' jnz mvininodosdriver mov ax,0xbc01 // get the version int 2fh mov word ptr [mvver+0],bx // save the version mov word ptr [mvver+2],cx // the DOS driver is loaded, use it's vectors, data, etc sub cx,cx // comes back 0 or the entry length mov ax,0xbc03 // get the vector table int 0x2f // from the DOS driver mov word ptr [tfp+0],bx // save the function pointer offset mov word ptr [tfp+2],dx // and segment mov [tablelen],cx mov ax,0bc04h // get the DMA & IRQ int 0x2f // from the DOS driver mov byte ptr ThePASDMAChannel,bl // DMA channel mov byte ptr ThePASIRQChannel,cl // IRQ channel } mvininodosdriver: // we have the pointer to some table. Now, load each function // pointer into the individual far pointers. if (mvver > 0x30313032) // ASCII version 0102 retcode = DOSDRIVER; // indicate the DOS driver is loaded // set the first 4 (1st rev of MVSOUND just had 4 functions) (long) MVSetMixerFunction = (long) *tfp++; (long) MVSetVolumeFunction = (long) *tfp++; (long) MVSetFilterFunction = (long) *tfp++; (long) MVSetCrossChannel = (long) *tfp++; // set the next entries (later revs of MVSOUND had 10 functions) if (tablelen > 4) { (long) MVGetMixerFunction = (long) *tfp++; (long) MVGetVolumeFunction = (long) *tfp++; (long) MVGetFilterFunction = (long) *tfp++; (long) MVGetCrossChannel = (long) *tfp++; (long) MVRealSoundSwitch = (long) *tfp++; (long) MVFMSplitSwitch = (long) *tfp; } // return the code return retcode; } ; /*\ ;---|*|----====< MVMixerHWState >====---- ;---|*| ;---|*| fetch and/or load a pointer to the state table. ;---|*| ;---|*| Entry Conditions: ;---|*| MVState far * -- pointer to another table. If NULL (0), ;---|*| the current pointer is only returned. Only ;---|*| non-zero table pointers will be loaded. ;---|*| Return Value: ;---|*| Returns the pointer to the table currently ;---|*| used by the mixer code. ;---|*| ; \*/ struct MVState far *MVMixerHWState(tbl) struct MVState far *tbl; { // if the shadow pointer is not initialized, then do it... if (!mvhwShadowPointer) MVInitStatePtr(); // In the first rev of software the static driver could receive // the caller's state table. Now that the static driver is gone, // we don't want to mess with... // if (tbl) // mvhwShadowPointer = tbl; // return the active table return (tbl); } ; /*\ ;---|*|----====< static dummyroutine >====---- ;---|*| ;---|*| This routine no-ops out the function calls in case MVSOUND.SYS ;---|*| is not loaded. ;---|*| ;---|*| Entry Conditions: ;---|*| none ;---|*| ;---|*| Return Value: ;---|*| 0 ;---|*| ; \*/ static int dummyroutine () { return 0; } ; /*\ ;---|*| End of MIXERC.C ; \*/