| /**************************************************************************** |
| * |
| * SciTech Nucleus Audio Architecture |
| * |
| * Copyright (C) 1991-1998 SciTech Software, Inc. |
| * All rights reserved. |
| * |
| * ====================================================================== |
| * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW| |
| * | | |
| * |This copyrighted computer code contains proprietary technology | |
| * |owned by SciTech Software, Inc., located at 505 Wall Street, | |
| * |Chico, CA 95928 USA (http://www.scitechsoft.com). | |
| * | | |
| * |The contents of this file are subject to the SciTech Nucleus | |
| * |License; you may *not* use this file or related software except in | |
| * |compliance with the License. You may obtain a copy of the License | |
| * |at http://www.scitechsoft.com/nucleus-license.txt | |
| * | | |
| * |Software distributed under the License is distributed on an | |
| * |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | |
| * |implied. See the License for the specific language governing | |
| * |rights and limitations under the License. | |
| * | | |
| * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW| |
| * ====================================================================== |
| * |
| * Language: ANSI C |
| * Environment: Any 32-bit protected mode environment |
| * |
| * Description: C module for the Graphics Accelerator Driver API. Uses |
| * the SciTech PM library for interfacing with DOS |
| * extender specific functions. |
| * |
| ****************************************************************************/ |
| |
| #include "nucleus/audio.h" |
| #ifdef __WIN32_VXD__ |
| #include "sdd/sddhelp.h" |
| #else |
| #include <stdio.h> |
| #include <stdlib.h> |
| #endif |
| |
| /*---------------------------- Global Variables ---------------------------*/ |
| |
| #ifdef TEST_HARNESS |
| extern PM_imports _VARAPI _PM_imports; |
| #else |
| AA_exports _VARAPI _AA_exports; |
| static int loaded = false; |
| static PE_MODULE *hModBPD = NULL; |
| |
| #ifdef __DRIVER__ |
| extern PM_imports _PM_imports; |
| #else |
| #include "pmimp.h" |
| #endif |
| |
| static N_imports _N_imports = { |
| sizeof(N_imports), |
| _OS_delay, |
| }; |
| |
| #ifdef __DRIVER__ |
| extern AA_imports _AA_imports; |
| #else |
| static AA_imports _AA_imports = { |
| sizeof(AA_imports), |
| }; |
| #endif |
| #endif |
| |
| /*----------------------------- Implementation ----------------------------*/ |
| |
| #define DLL_NAME "audio.bpd" |
| |
| #ifndef TEST_HARNESS |
| /**************************************************************************** |
| REMARKS: |
| Fatal error handler for non-exported AA_exports. |
| ****************************************************************************/ |
| static void _AA_fatalErrorHandler(void) |
| { |
| PM_fatalError("Unsupported Nucleus export function called! Please upgrade your copy of Nucleus!\n"); |
| } |
| |
| /**************************************************************************** |
| REMARKS: |
| Loads the Nucleus binary portable DLL into memory and initilises it. |
| ****************************************************************************/ |
| static ibool LoadDriver(void) |
| { |
| AA_initLibrary_t AA_initLibrary; |
| AA_exports *aaExp; |
| char filename[PM_MAX_PATH]; |
| char bpdpath[PM_MAX_PATH]; |
| int i,max; |
| ulong *p; |
| |
| /* Check if we have already loaded the driver */ |
| if (loaded) |
| return true; |
| PM_init(); |
| _AA_exports.dwSize = sizeof(_AA_exports); |
| |
| /* Open the BPD file */ |
| if (!PM_findBPD(DLL_NAME,bpdpath)) |
| return false; |
| strcpy(filename,bpdpath); |
| strcat(filename,DLL_NAME); |
| if ((hModBPD = PE_loadLibrary(filename,false)) == NULL) |
| return false; |
| if ((AA_initLibrary = (AA_initLibrary_t)PE_getProcAddress(hModBPD,"_AA_initLibrary")) == NULL) |
| return false; |
| bpdpath[strlen(bpdpath)-1] = 0; |
| if (strcmp(bpdpath,PM_getNucleusPath()) == 0) |
| strcpy(bpdpath,PM_getNucleusConfigPath()); |
| else { |
| PM_backslash(bpdpath); |
| strcat(bpdpath,"config"); |
| } |
| if ((aaExp = AA_initLibrary(bpdpath,filename,&_PM_imports,&_N_imports,&_AA_imports)) == NULL) |
| PM_fatalError("AA_initLibrary failed!\n"); |
| |
| /* Initialize all default imports to point to fatal error handler |
| * for upwards compatibility, and copy the exported functions. |
| */ |
| max = sizeof(_AA_exports)/sizeof(AA_initLibrary_t); |
| for (i = 0,p = (ulong*)&_AA_exports; i < max; i++) |
| *p++ = (ulong)_AA_fatalErrorHandler; |
| memcpy(&_AA_exports,aaExp,MIN(sizeof(_AA_exports),aaExp->dwSize)); |
| loaded = true; |
| return true; |
| } |
| |
| /* The following are stub entry points that the application calls to |
| * initialise the Nucleus loader library, and we use this to load our |
| * driver DLL from disk and initialise the library using it. |
| */ |
| |
| /* {secret} */ |
| int NAPI AA_status(void) |
| { |
| if (!loaded) |
| return nDriverNotFound; |
| return _AA_exports.AA_status(); |
| } |
| |
| /* {secret} */ |
| const char * NAPI AA_errorMsg( |
| N_int32 status) |
| { |
| if (!loaded) |
| return "Unable to load Nucleus device driver!"; |
| return _AA_exports.AA_errorMsg(status); |
| } |
| |
| /* {secret} */ |
| int NAPI AA_getDaysLeft(void) |
| { |
| if (!LoadDriver()) |
| return -1; |
| return _AA_exports.AA_getDaysLeft(); |
| } |
| |
| /* {secret} */ |
| int NAPI AA_registerLicense(uchar *license) |
| { |
| if (!LoadDriver()) |
| return 0; |
| return _AA_exports.AA_registerLicense(license); |
| } |
| |
| /* {secret} */ |
| int NAPI AA_enumerateDevices(void) |
| { |
| if (!LoadDriver()) |
| return 0; |
| return _AA_exports.AA_enumerateDevices(); |
| } |
| |
| /* {secret} */ |
| AA_devCtx * NAPI AA_loadDriver(N_int32 deviceIndex) |
| { |
| if (!LoadDriver()) |
| return NULL; |
| return _AA_exports.AA_loadDriver(deviceIndex); |
| } |
| #endif |
| |
| typedef struct { |
| N_uint32 low; |
| N_uint32 high; |
| } AA_largeInteger; |
| |
| void NAPI _OS_delay8253(N_uint32 microSeconds); |
| ibool NAPI _GA_haveCPUID(void); |
| uint NAPI _GA_getCPUIDFeatures(void); |
| void NAPI _GA_readTimeStamp(AA_largeInteger *time); |
| #define CPU_HaveRDTSC 0x00000010 |
| |
| /**************************************************************************** |
| REMARKS: |
| This function delays for the specified number of microseconds |
| ****************************************************************************/ |
| void NAPI _OS_delay( |
| N_uint32 microSeconds) |
| { |
| static ibool inited = false; |
| LZTimerObject tm; |
| |
| if (_GA_haveCPUID() && (_GA_getCPUIDFeatures() & CPU_HaveRDTSC) != 0) { |
| if (!inited) { |
| ZTimerInit(); |
| inited = true; |
| } |
| LZTimerOnExt(&tm); |
| while (LZTimerLapExt(&tm) < microSeconds) |
| ; |
| LZTimerOnExt(&tm); |
| } |
| else |
| _OS_delay8253(microSeconds); |
| } |