541 lines
12 KiB
C
541 lines
12 KiB
C
|
/*
|
|||
|
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: AWE32.C
|
|||
|
|
|||
|
author: James R. Dose
|
|||
|
date: August 23, 1994
|
|||
|
|
|||
|
Cover functions for calling the AWE32 low-level library.
|
|||
|
|
|||
|
(c) Copyright 1994 James R. Dose. All Rights Reserved.
|
|||
|
**********************************************************************/
|
|||
|
|
|||
|
#include <conio.h>
|
|||
|
#include <string.h>
|
|||
|
#include "dpmi.h"
|
|||
|
#include "blaster.h"
|
|||
|
#include "ctaweapi.h"
|
|||
|
#include "awe32.h"
|
|||
|
|
|||
|
#define _inp inp
|
|||
|
#define _outp outp
|
|||
|
|
|||
|
/* DSP defines */
|
|||
|
#define MPU_ACK_OK 0xfe
|
|||
|
#define MPU_RESET_CMD 0xff
|
|||
|
#define MPU_ENTER_UART 0x3f
|
|||
|
|
|||
|
static WORD wSBCBaseAddx; /* Sound Blaster base address */
|
|||
|
static WORD wEMUBaseAddx; /* EMU8000 subsystem base address */
|
|||
|
static WORD wMpuBaseAddx; /* MPU401 base address */
|
|||
|
|
|||
|
static unsigned short NoteFlags[ 128 ];
|
|||
|
|
|||
|
/* macros */
|
|||
|
#define SBCPort( x ) ( ( x ) + wSBCBaseAddx )
|
|||
|
#define MPUPort( x ) ( ( x ) + wMpuBaseAddx )
|
|||
|
|
|||
|
static SOUND_PACKET spSound =
|
|||
|
{
|
|||
|
0
|
|||
|
};
|
|||
|
|
|||
|
static LONG lBankSizes[ MAXBANKS ] =
|
|||
|
{
|
|||
|
0
|
|||
|
};
|
|||
|
|
|||
|
unsigned SetES( void );
|
|||
|
#pragma aux SetES = \
|
|||
|
"xor eax, eax" \
|
|||
|
"mov ax, es" \
|
|||
|
"mov bx, ds" \
|
|||
|
"mov es, bx" \
|
|||
|
modify [ eax ebx ];
|
|||
|
|
|||
|
void RestoreES( unsigned num );
|
|||
|
#pragma aux RestoreES = \
|
|||
|
"mov es, ax" \
|
|||
|
parm [ eax ];
|
|||
|
|
|||
|
int AWE32_ErrorCode = AWE32_Ok;
|
|||
|
|
|||
|
#define AWE32_SetErrorCode( status ) \
|
|||
|
AWE32_ErrorCode = ( status );
|
|||
|
|
|||
|
|
|||
|
/*---------------------------------------------------------------------
|
|||
|
Function: AWE32_ErrorString
|
|||
|
|
|||
|
Returns a pointer to the error message associated with an error
|
|||
|
number. A -1 returns a pointer the current error.
|
|||
|
---------------------------------------------------------------------*/
|
|||
|
|
|||
|
char *AWE32_ErrorString
|
|||
|
(
|
|||
|
int ErrorNumber
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
char *ErrorString;
|
|||
|
|
|||
|
switch( ErrorNumber )
|
|||
|
{
|
|||
|
case AWE32_Warning :
|
|||
|
case AWE32_Error :
|
|||
|
ErrorString = AWE32_ErrorString( AWE32_ErrorCode );
|
|||
|
break;
|
|||
|
|
|||
|
case AWE32_Ok :
|
|||
|
ErrorString = "AWE32 ok.";
|
|||
|
break;
|
|||
|
|
|||
|
case AWE32_SoundBlasterError :
|
|||
|
ErrorString = BLASTER_ErrorString( BLASTER_Error );
|
|||
|
break;
|
|||
|
|
|||
|
case AWE32_NotDetected :
|
|||
|
ErrorString = "Could not detect AWE32.";
|
|||
|
break;
|
|||
|
|
|||
|
case AWE32_UnableToInitialize :
|
|||
|
ErrorString = "Unable to initialize AWE32.";
|
|||
|
|
|||
|
case AWE32_MPU401Error :
|
|||
|
ErrorString = "MPU-401 initialization failed in AWE32.";
|
|||
|
break;
|
|||
|
|
|||
|
case AWE32_DPMI_Error :
|
|||
|
ErrorString = "DPMI Error in AWE32.";
|
|||
|
break;
|
|||
|
|
|||
|
default :
|
|||
|
ErrorString = "Unknown AWE32 error code.";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return( ErrorString );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**********************************************************************
|
|||
|
|
|||
|
Memory locked functions:
|
|||
|
|
|||
|
**********************************************************************/
|
|||
|
|
|||
|
|
|||
|
#define AWE32_LockStart AWE32_NoteOff
|
|||
|
|
|||
|
|
|||
|
void AWE32_NoteOff
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int key,
|
|||
|
int velocity
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32NoteOff( channel, key, velocity );
|
|||
|
RestoreES( temp );
|
|||
|
NoteFlags[ key ] ^= ( 1 << channel );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_NoteOn
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int key,
|
|||
|
int velocity
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32NoteOn( channel, key, velocity );
|
|||
|
RestoreES( temp );
|
|||
|
NoteFlags[ key ] |= ( 1 << channel );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_PolyAftertouch
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int key,
|
|||
|
int pressure
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32PolyKeyPressure( channel, key, pressure );
|
|||
|
RestoreES( temp );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_ChannelAftertouch
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int pressure
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32ChannelPressure( channel, pressure );
|
|||
|
RestoreES( temp );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_ControlChange
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int number,
|
|||
|
int value
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
int i;
|
|||
|
unsigned channelmask;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
|
|||
|
if ( number == 0x7b )
|
|||
|
{
|
|||
|
channelmask = 1 << channel;
|
|||
|
for( i = 0; i < 128; i++ )
|
|||
|
{
|
|||
|
if ( NoteFlags[ i ] & channelmask )
|
|||
|
{
|
|||
|
awe32NoteOff( channel, i, 0 );
|
|||
|
NoteFlags[ i ] ^= channelmask;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
awe32Controller( channel, number, value );
|
|||
|
}
|
|||
|
RestoreES( temp );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_ProgramChange
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int program
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32ProgramChange( channel, program );
|
|||
|
RestoreES( temp );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_PitchBend
|
|||
|
(
|
|||
|
int channel,
|
|||
|
int lsb,
|
|||
|
int msb
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
unsigned temp;
|
|||
|
|
|||
|
temp = SetES();
|
|||
|
awe32PitchBend( channel, lsb, msb );
|
|||
|
RestoreES( temp );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*---------------------------------------------------------------------
|
|||
|
Function: AWE32_LockEnd
|
|||
|
|
|||
|
Used for determining the length of the functions to lock in memory.
|
|||
|
---------------------------------------------------------------------*/
|
|||
|
|
|||
|
static void AWE32_LockEnd
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
static int InitMPU
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
volatile DWORD dwCount;
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
|||
|
_outp(MPUPort(1), MPU_RESET_CMD);
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
|||
|
_inp(MPUPort(0));
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
|||
|
_outp(MPUPort(1), MPU_RESET_CMD);
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
|||
|
_inp(MPUPort(0));
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
|||
|
_outp(MPUPort(1), MPU_ENTER_UART);
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
|||
|
if (!dwCount) return TRUE;
|
|||
|
if (_inp(MPUPort(0)) != MPU_ACK_OK) return TRUE;
|
|||
|
|
|||
|
// mask MPU-401 interrupt
|
|||
|
_outp(SBCPort(0x4), 0x83);
|
|||
|
_outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸*/
|
|||
|
/*<2A> ShutdownMPU <20>*/
|
|||
|
/*<2A> Cleans up Sound Blaster to normal state. <20>*/
|
|||
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;*/
|
|||
|
|
|||
|
static void ShutdownMPU
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
volatile DWORD dwCount;
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
|||
|
_outp(MPUPort(1), MPU_RESET_CMD);
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
_inp(MPUPort(0));
|
|||
|
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
dwCount = 0x2000;
|
|||
|
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
|||
|
_outp(MPUPort(1), MPU_RESET_CMD);
|
|||
|
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
|||
|
_inp(MPUPort(0));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸*/
|
|||
|
/*<2A> LoadSBK <20>*/
|
|||
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;*/
|
|||
|
|
|||
|
static void LoadSBK
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
/* use embeded preset objects */
|
|||
|
spSound.bank_no = 0; /* load as Bank 0 */
|
|||
|
spSound.total_banks = 1; /* use 1 bank first */
|
|||
|
lBankSizes[ 0 ] = 0; /* ram is not needed */
|
|||
|
|
|||
|
spSound.banksizes = lBankSizes;
|
|||
|
awe32DefineBankSizes( &spSound );
|
|||
|
awe32SoundPad.SPad1 = awe32SPad1Obj;
|
|||
|
awe32SoundPad.SPad2 = awe32SPad2Obj;
|
|||
|
awe32SoundPad.SPad3 = awe32SPad3Obj;
|
|||
|
awe32SoundPad.SPad4 = awe32SPad4Obj;
|
|||
|
awe32SoundPad.SPad5 = awe32SPad5Obj;
|
|||
|
awe32SoundPad.SPad6 = awe32SPad6Obj;
|
|||
|
awe32SoundPad.SPad7 = awe32SPad7Obj;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int AWE32_Init
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
int status;
|
|||
|
BLASTER_CONFIG Blaster;
|
|||
|
|
|||
|
wSBCBaseAddx = 0x220;
|
|||
|
wEMUBaseAddx = 0x620;
|
|||
|
wMpuBaseAddx = 0x330;
|
|||
|
|
|||
|
status = BLASTER_GetCardSettings( &Blaster );
|
|||
|
if ( status != BLASTER_Ok )
|
|||
|
{
|
|||
|
status = BLASTER_GetEnv( &Blaster );
|
|||
|
if ( status != BLASTER_Ok )
|
|||
|
{
|
|||
|
AWE32_SetErrorCode( AWE32_SoundBlasterError );
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
wSBCBaseAddx = Blaster.Address;
|
|||
|
if ( wSBCBaseAddx == UNDEFINED )
|
|||
|
{
|
|||
|
wSBCBaseAddx = 0x220;
|
|||
|
}
|
|||
|
|
|||
|
wMpuBaseAddx = Blaster.Midi;
|
|||
|
if ( wMpuBaseAddx == UNDEFINED )
|
|||
|
{
|
|||
|
wMpuBaseAddx = 0x330;
|
|||
|
}
|
|||
|
|
|||
|
wEMUBaseAddx = Blaster.Emu;
|
|||
|
if ( wEMUBaseAddx <= 0 )
|
|||
|
{
|
|||
|
wEMUBaseAddx = wSBCBaseAddx + 0x400;
|
|||
|
}
|
|||
|
|
|||
|
status = awe32Detect( wEMUBaseAddx );
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
AWE32_SetErrorCode( AWE32_NotDetected );
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
|
|||
|
status = awe32InitHardware();
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
AWE32_SetErrorCode( AWE32_UnableToInitialize );
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
status = awe32InitMIDI();
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
AWE32_Shutdown();
|
|||
|
AWE32_SetErrorCode( AWE32_MPU401Error )
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
status = InitMPU();
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
ShutdownMPU();
|
|||
|
status = InitMPU();
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
ShutdownMPU();
|
|||
|
status = InitMPU();
|
|||
|
if ( status )
|
|||
|
{
|
|||
|
AWE32_Shutdown();
|
|||
|
AWE32_SetErrorCode( AWE32_MPU401Error )
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
*/
|
|||
|
status = DPMI_LockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
|
|||
|
status |= DPMI_Lock( wSBCBaseAddx );
|
|||
|
status |= DPMI_Lock( wEMUBaseAddx );
|
|||
|
status |= DPMI_Lock( wMpuBaseAddx );
|
|||
|
status |= DPMI_Lock( spSound );
|
|||
|
status |= DPMI_Lock( lBankSizes );
|
|||
|
status |= DPMI_LockMemory( NoteFlags, sizeof( NoteFlags ) );
|
|||
|
|
|||
|
// Lock awe32 library
|
|||
|
status = DPMI_LockMemoryRegion( __midieng_code, __midieng_ecode );
|
|||
|
status = DPMI_LockMemoryRegion( __midieng_code(), __midieng_ecode() );
|
|||
|
status = DPMI_LockMemoryRegion( __nrpn_code, __nrpn_ecode );
|
|||
|
status = DPMI_LockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
|
|||
|
status = DPMI_LockMemoryRegion( &__midivar_data, &__midivar_edata );
|
|||
|
status = DPMI_LockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
|
|||
|
status = DPMI_LockMemoryRegion( &__embed_data, &__embed_edata );
|
|||
|
|
|||
|
if ( status != DPMI_Ok )
|
|||
|
{
|
|||
|
ShutdownMPU();
|
|||
|
awe32Terminate();
|
|||
|
AWE32_SetErrorCode( AWE32_DPMI_Error );
|
|||
|
return( AWE32_Error );
|
|||
|
}
|
|||
|
|
|||
|
// Set the number of voices to use to 32
|
|||
|
awe32NumG = 32;
|
|||
|
|
|||
|
awe32TotalPatchRam(&spSound);
|
|||
|
|
|||
|
LoadSBK();
|
|||
|
awe32InitMIDI();
|
|||
|
awe32InitNRPN();
|
|||
|
|
|||
|
memset( NoteFlags, 0, sizeof( NoteFlags ) );
|
|||
|
|
|||
|
return( AWE32_Ok );
|
|||
|
}
|
|||
|
|
|||
|
void AWE32_Shutdown
|
|||
|
(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
ShutdownMPU();
|
|||
|
awe32Terminate();
|
|||
|
|
|||
|
DPMI_UnlockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
|
|||
|
DPMI_Unlock( wSBCBaseAddx );
|
|||
|
DPMI_Unlock( wEMUBaseAddx );
|
|||
|
DPMI_Unlock( wMpuBaseAddx );
|
|||
|
DPMI_Unlock( spSound );
|
|||
|
DPMI_Unlock( lBankSizes );
|
|||
|
DPMI_UnlockMemory( NoteFlags, sizeof( NoteFlags ) );
|
|||
|
|
|||
|
// Unlock awe32 library
|
|||
|
DPMI_UnlockMemoryRegion( __midieng_code, __midieng_ecode );
|
|||
|
DPMI_UnlockMemoryRegion( __midieng_code(), __midieng_ecode() );
|
|||
|
DPMI_UnlockMemoryRegion( __nrpn_code, __nrpn_ecode );
|
|||
|
DPMI_UnlockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
|
|||
|
DPMI_UnlockMemoryRegion( &__midivar_data, &__midivar_edata );
|
|||
|
DPMI_UnlockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
|
|||
|
DPMI_UnlockMemoryRegion( &__embed_data, &__embed_edata );
|
|||
|
}
|