home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FMI Superhry 1
/
Superhry-I.bin
/
bonus
/
doom
/
programs
/
ktsdht10
/
ems.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-05-02
|
13KB
|
251 lines
{***************************************************************************
* E M S : a unit that can be used as an interface between a program and *
* the Expanded Memory Manager (EMM) - this allows access to EMS *
* memory *
**------------------------------------------------------------------------**
* Author : MICHAEL TISCHER *
* developed on : 06/09/1989 *
* last update on : 06/09/1989 *
***************************************************************************}
unit Ems;
interface
uses Dos;
{-- declaration of functions and procedures that can be called from ------}
{-- other programs ------}
function EmsGetFreePage : integer;
function EmsGetPtr ( PhysPage : byte ) : pointer;
function EmsAlloc ( Amount : integer ) : integer;
procedure EmsMap ( Handle, LogPage : integer; PhysPage : byte );
procedure EmsFree ( Handle : integer );
procedure EmsRestoreMapping( Handle : integer );
procedure EmsSaveMapping ( Handle : integer );
{-- constants, public -----------------------------------------------------}
const {--------------------------------------------- EMS error codes ------}
EmsErrOk = $00; { everything o.k., no error }
EmsErrSw = $80; { error in EMM (software) }
EmsErrHw = $81; { EMS hardware error }
EmsErrInvHandle = $83; { invalid EMS handle }
EmsErrFkt = $84; { invalid function called }
EmsErrNoHandles = $85; { no more handles free }
EmsErrSaResMap = $86; { error while saving or restoring Mapping }
EmsErrToMany = $87; { more pages were requested than are }
{ physically available }
EmsErrNoPages = $88; { more pages requested than are free }
EmsErrNullPages = $89; { null page requested }
EmsErrLogPInv = $8A; { logical page does not belong to handle }
EmsErrPhyPInv = $8B; { invalid physical page number }
EmsErrMapFull = $8C; { Mapping memory region is full }
EmsErrMapSaved = $8D; { Mapping already saved }
EmsErrMapRes = $8E; { attempt to restore Mapping without }
{ previously saving it }
{-- global variables accessible to other programs -------------------------}
var EmsInst : boolean; { contains TRUE if EMS memory is available }
EmsPages : integer; { total number of EMS pages }
EmsVersion, { EMS version number (32 = 3.2, 40 = 4.0) }
EmsError : byte; { stores EMM error number }
implementation
{-- constants internal to this program ------------------------------------}
const EMS_INT = $67; { interrupt vector for accessing the EMM }
{-- global variables internal to this module ------------------------------}
var EmsFrameSeg : word; { segment address of the EMS page frames }
{***************************************************************************
* EmsInit : Initialializes the unit *
***************************************************************************}
procedure EmsInit;
type EmmName = array [1..8] of char; { name of the EMM from driver header }
EmmNaPtr = ^EmmName; { pointer to name in driver header }
const Name : EmmName = 'EMMXXXX0'; { name of EMS driver }
var Regs : Registers; { processor registers for interrupt call }
begin
{-- start by determining if EMS memory and the proper EMM are installed -}
Regs.ax := $35 shl 8 + EMS_INT; { get interrupt vector with }
msdos( Regs ); { DOS function $35 }
EmsInst := ( EmmNaPtr(Ptr(Regs.ES,10))^ = Name ); { compare driver name }
if ( EmsInst ) then { is an EMM installed? }
begin { yes }
{-- get total number of EMS pages -----------------------------------}
Regs.AH := $42; { function no. for "get number of pages" }
intr( EMS_INT, Regs ); { call EMM }
EmsPages := Regs.DX; { store total number of pages }
{-- get segment address of EMS page frame ---------------------------}
Regs.AH := $41; { Function no. for "get segment add. of page frame" }
intr( EMS_INT, Regs ); { call EMM }
EmsFrameSeg := Regs.BX; { store segment address }
{-- get version number of EMM ---------------------------------------}
Regs.AH := $46; { function no. for "get EMM version number" }
intr( EMS_INT, Regs ); { call EMM }
EmsVersion := ( Regs.AL and 15 ) + ( Regs.AL shr 4 ) * 10;
EmsError := EmsErrOk; { no errors yet }
end;
end;
{***************************************************************************
* EmsGetPtr : returns a pointer to one of the four physical pages of the *
* EMS page frame *
**------------------------------------------------------------------------**
* Input : PhysPage = number of the physical page *
* Output : pointer to this page *
***************************************************************************}
function EmsGetPtr( PhysPage : byte ) : pointer;
begin
EmsGetPtr := ptr( EmsFrameSeg, PhysPage shl 14 );
end;
{***************************************************************************
* EmsGetFreePage : gets the number of free EMS pages (1 page = 16K) *
**------------------------------------------------------------------------**
* Output : the number of free pages *
***************************************************************************}
function EmsGetFreePage : integer;
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $42; { function no. for "get number of pages" }
intr( EMS_INT, Regs ); { call EMM }
EmsGetFreePage := Regs.BX; { return number of free pages }
end;
{***************************************************************************
* EmsAlloc : allocates a given number of EMS pages *
**------------------------------------------------------------------------**
* Input : Amount = number of pages to allocate *
* Output : handle for later access to the allocated pages *
* Info : if an error occurs, the variable EmsError will contain a *
* value not equal to 0 (an error code) after the function call *
***************************************************************************}
function EmsAlloc( Amount : integer ) : integer;
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $43; { function no. for "allocate pages" }
Regs.BX := Amount; { number of pages is passed to BX }
intr( EMS_INT, Regs ); { call EMM }
EmsAlloc := Regs.DX; { the handle is passed to DX }
EmsError := Regs.AH; { error? }
end;
{***************************************************************************
* EmsMap : loads one of the allocated logical pages into one of the 4 *
* physical pages of the EMS page frame *
*-------------------------------------------------------------------------**
* Input : Handle = handle that identifies the allocated page *
* LogPage = number of the logical page to be loaded *
* PhysPage = the physical page number *
* Info : if an error occurs, the variable EmsError will contain a *
* value other than 0 (error code) after the function call *
***************************************************************************}
procedure EmsMap( Handle, LogPage : integer; PhysPage : byte );
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $44; { function no. for "map expanded memory page" }
Regs.DX := Handle; { load the parameters in the registers }
Regs.BX := LogPage;
Regs.Al := PhysPage;
intr( EMS_INT, Regs ); { call EMM }
EmsError := Regs.AH; { error? }
end;
{***************************************************************************
* EmsFree : frees EMS pages previously allocated with EmsAlloc *
**------------------------------------------------------------------------**
* Input : Handle = the handle under which the pages were allocated *
* Info : if an error occurs, the variable EmsError will contain a *
* value other than 0 (error code) after the function call *
***************************************************************************}
procedure EmsFree( Handle : integer );
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $45; { function number for "release handle & EMS" }
Regs.DX := Handle; { load parameter in the register }
intr( EMS_INT, Regs ); { call EMM }
EmsError := Regs.AH; { error? }
end;
{***************************************************************************
* EmsSaveMapping : saves a mapping of the current logical EMS pages in *
* the four physical pages of the EMS page frame *
**------------------------------------------------------------------------**
* Input : Handle = the handle under which the pages were allocated *
* Info : if an error occurs, the variable EmsError will contain a *
* value other than 0 (error code) after the function call *
***************************************************************************}
procedure EmsSaveMapping( Handle : integer );
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $47; { function number for "save mapping" }
Regs.DX := Handle; { load the parameter in the register }
intr( EMS_INT, Regs ); { call EMM }
EmsError := Regs.AH; { error? }
end;
{***************************************************************************
* EmsRestoreMapping : retrieves a mapping previously saved with the *
* procedure EmsSaveMapping *
**------------------------------------------------------------------------**
* Input : Handle = the handle under which the pages were allocated *
* Info : if an error occurs, the variable EmsError will contain a *
* value other than 0 (error code) after the function call *
***************************************************************************}
procedure EmsRestoreMapping( Handle : integer );
var Regs : Registers; { processor registers for interrupt call }
begin
Regs.AH := $48; { function number for "restore mapping" }
Regs.DX := Handle; { load parameter in the register }
intr( EMS_INT, Regs ); { call EMM }
EmsError := Regs.AH; { error? }
end;
{**----------------------------------------------------------------------**}
{** Starting code of the unit **}
{**----------------------------------------------------------------------**}
begin
EmsInit; { initialize the unit }
end.