duke3d/audiolib/dpmi.c

251 lines
5.4 KiB
C
Raw Normal View History

/*
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: DPMI.C
author: James R. Dose
date: April 8, 1994
Functions for performing DPMI calls.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <dos.h>
#include <string.h>
#include "dpmi.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
static union REGS Regs;
static struct SREGS SegRegs;
/*---------------------------------------------------------------------
Function: DPMI_GetRealModeVector
Returns the vector of a real mode interrupt.
---------------------------------------------------------------------*/
unsigned long DPMI_GetRealModeVector
(
int num
)
{
unsigned long vector;
Regs.x.eax = 0x0200;
Regs.h.bl = num;
int386( 0x31, &Regs, &Regs );
vector = Regs.w.cx & 0xffff;
vector <<= 16;
vector |= Regs.w.dx & 0xffff;
return( vector );
}
/*---------------------------------------------------------------------
Function: DPMI_SetRealModeVector
Sets the vector of a real mode interrupt.
---------------------------------------------------------------------*/
void DPMI_SetRealModeVector
(
int num,
unsigned long vector
)
{
Regs.x.eax = 0x0201;
Regs.h.bl = num;
Regs.w.dx = vector & 0xffff;
Regs.w.cx = ( vector >> 16 ) & 0xffff;
int386( 0x31, &Regs, &Regs );
}
/*---------------------------------------------------------------------
Function: DPMI_CallRealModeFunction
Performs a call to a real mode function.
---------------------------------------------------------------------*/
int DPMI_CallRealModeFunction
(
dpmi_regs *callregs
)
{
// Setup our registers to call DPMI
Regs.w.ax = 0x0301;
Regs.h.bl = 0;
Regs.h.bh = 0;
Regs.w.cx = 0;
SegRegs.es = FP_SEG( callregs );
Regs.x.edi = FP_OFF( callregs );
// Call Real-mode procedure with Far Return Frame
int386x( 0x31, &Regs, &Regs, &SegRegs );
if ( Regs.x.cflag )
{
return( DPMI_Error );
}
return( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemory
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemory
(
void *address,
unsigned length
)
{
unsigned linear;
// Thanks to DOS/4GW's zero-based flat memory model, converting
// a pointer of any type to a linear address is trivial.
linear = (unsigned) address;
// DPMI Lock Linear Region
Regs.w.ax = 0x600;
// Linear address in BX:CX
Regs.w.bx = (linear >> 16);
Regs.w.cx = (linear & 0xFFFF);
// Length in SI:DI
Regs.w.si = (length >> 16);
Regs.w.di = (length & 0xFFFF);
int386 (0x31, &Regs, &Regs);
// Return 0 if can't lock
if ( Regs.w.cflag )
{
return( DPMI_Error );
}
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemoryRegion
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
return( status );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemory
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemory
(
void *address,
unsigned length
)
{
unsigned linear;
// Thanks to DOS/4GW's zero-based flat memory model, converting
// a pointer of any type to a linear address is trivial.
linear = (unsigned) address;
// DPMI Unlock Linear Region
Regs.w.ax = 0x601;
// Linear address in BX:CX
Regs.w.bx = (linear >> 16);
Regs.w.cx = (linear & 0xFFFF);
// Length in SI:DI
Regs.w.si = (length >> 16);
Regs.w.di = (length & 0xFFFF);
int386 (0x31, &Regs, &Regs);
// Return 0 if can't unlock
if ( Regs.w.cflag )
{
return( DPMI_Error );
}
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemoryRegion
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
return( status );
}