home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Intermedia 1998 January
/
inter1_98.iso
/
www
/
rozi
/
RAW1.ZIP
/
MEM_MGR.PAS
next >
Wrap
Pascal/Delphi Source File
|
1996-06-22
|
10KB
|
342 lines
{****************************************************************************}
{* *}
{* Pascal Memory Manager v.1.0 *}
{* Code by KOT *}
{* Frozen Fire 1996 *}
{* *}
{* Compiled with Turbo Pascal 7.0 *}
{* ( Default Switches ) *}
{************************************************************: Shareware :***}
Unit Mem_mgr;
INTERFACE
Uses DOS;
{****************************************************************************}
type ExtHandle=record
Handle:word;
Size,Offset:Longint;
end;
XMSHandle=record
Handle,Size:word;
end;
{****************************************************************************}
Const
{ Move Operation Types }
Single = 0;
Extended = 1;
{ Move Operation Modes }
NoMoving = 0;
UMBToEMB = 1;
EMBtoUMB = 2;
MM_Init:boolean=FALSE;
{****************************************************************************}
Var
{ Points to the service memory block }
MemoryBuffer:pointer;
{****************************************************************************}
function Init_MemMgr:word;
function Done_MemMgr:word;
function XMSInstalled:boolean;
function MM_FreeXMS:word;
function MM_Limit(MinDosMem,MinXMS:word):boolean;
function MM_Move(var HeapBuf;var EMBHandle;Qsize:word;
MO_type,Mode:byte):byte;
function MM_Allocate(var EMBHandle;MO_type:byte;QSize:word):byte;
function MM_FreeMem(var EMBHandle;MO_type:byte):byte;
IMPLEMENTATION
{****************************************************************************}
type EMMStructure=record
Size:LongInt;
SourceHandle:word;
SourceOfs:Longint;
DestHandle:word;
DestOfs:Longint;
end;
{****************************************************************************}
Const
{ XMM driver functions }
XMS_MEMALLOC=$09;
XMS_FREEMEM=$0A;
XMS_MOVEMEM=$0B;
{****************************************************************************}
var
XMSaddr:array[1..2] of word;
r:registers;
XMSok,Init:boolean;
EMMS:EMMstructure;
H1:XMSHandle;
H2:ExtHandle;
{****************************************************************************}
{* ROUTINES *}
{****************************************************************************}
function even(num:word):longint;
begin
if num and 1=1 then even:=num xor 1 else even:=num;
end;
{****************************************************************************}
{* MEM_MGR PROCEDURES *}
{****************************************************************************}
function Init_MemMgr;
{****************************************************************************}
{* Initializes MEM_MGR unit. Should be always started first, before using *}
{* any other MEM_MGR procedures. *}
{****************************************************************************}
begin
Init_MemMgr:=0;
if not MM_Init then
begin
if XMSInstalled then
begin
{ Get XMS driver address }
r.ax:=$4300;
intR($2F,r);
XMSok:=(r.al=$80);
if XMSok then
begin
r.ax:=$4310;
intR($2F,r);
XMSAddr[1]:=r.bx;
XMSAddr[2]:=r.es;
end;
if XMSok then
begin
Init_MemMgr:=0;
Init:=TRUE;
GetMem(MemoryBuffer,$FFFF);
end
else Init_MemMgr:=1;
MM_Init:=TRUE;
end;
end;
end;
{****************************************************************************}
function Done_MemMgr;
{****************************************************************************}
{* This clears memory and retrieves the normal PC state *}
{****************************************************************************}
begin
if MM_Init then
begin
MM_Init:=FALSE;
FreeMem(MemoryBuffer,$FFFF);
Done_MemMgr:=0;
end;
end;
{****************************************************************************}
function XMSInstalled;assembler;
{****************************************************************************}
{* Checks if XMM driver is resident in conventional memory *}
{****************************************************************************}
asm
mov ax, $4300
int $2f
cmp al, $80
je @@1
xor ax, ax
@@1:
end;
{****************************************************************************}
function MM_FreeXMS;
{****************************************************************************}
{* Returns the size of the free XMS in kilobytes *}
{****************************************************************************}
var
temp:word;
begin
MM_FreeXMS:=0;
if Init then
begin
asm
mov ah,$08
call [XMSaddr]
mov temp,dx
end;
MM_FreeXMS:=temp;
end;
end;
{****************************************************************************}
function MM_Limit;
{****************************************************************************}
{* Sets the limits for the lowest memory sizes, returns true if available *}
{****************************************************************************}
begin
MM_Limit:=FALSE;
if Init then
if (MM_FreeXMS>=MinXMS) and (MemAvail>=(MinDosMem div 1024)) then
MM_Limit:=TRUE;
end;
{****************************************************************************}
function MM_Move;
{****************************************************************************}
{* Moves data to and from EMB *}
{****************************************************************************}
var
erc:byte;
EMMSeg,EMMOfs,XSeg:word;
begin
Erc:=0;
if MO_Type=Single then
begin
move(EMBHandle,H1,4);
EMMS.Size:=even(QSize+1);
if Mode=UMBToEMB then
begin
EMMS.SourceHandle:=0;
EMMS.SourceOfs:=LongInt(Addr(HeapBuf));
EMMS.DestHandle:=H1.Handle;
EMMS.DestOfs:=0;
end;
if Mode=EMBtoUMB then
begin
EMMS.SourceHandle:=H1.Handle;
EMMS.SourceOfs:=0;
EMMS.DestHandle:=0;
EMMS.DestOfs:=Longint(Addr(HeapBuf));
end;
end else
if MO_type=Extended then
begin
move(EMBHandle,H2,10);
EMMS.Size:=even(QSize+1);
if Mode=UMBToEMB then
begin
EMMS.SourceHandle:=0;
EMMS.SourceOfs:=LongInt(Addr(HeapBuf));
EMMS.DestHandle:=H2.Handle;
EMMS.DestOfs:=H2.Offset;
end;
if Mode=EMBtoUMB then
begin
EMMS.SourceHandle:=H2.Handle;
EMMS.SourceOfs:=H2.Offset;
EMMS.DestHandle:=0;
EMMS.DestOfs:=Longint(Addr(HeapBuf));
end;
end else
begin
MM_Move:=$FF;
exit;
end;
EMMSeg:=Seg(EMMS);
EMMOfs:=Ofs(EMMS);
XSeg:=Seg(XMSaddr);
asm
push DS
mov AH,XMS_MOVEMEM
mov SI,EMMOfs
mov BX,XSeg;
mov ES,BX
mov BX,EMMSeg
mov DS,BX
call [ES:XMSAddr]
cmp ax,1
jne @@1
jmp @@2
@@1:
mov erc,bl
@@2:
pop ds
end;
MM_Move:=Erc;
end;
{****************************************************************************}
function MM_Allocate;
{****************************************************************************}
{* Allocates memory in EMB *}
{****************************************************************************}
var
Hnd:word;
Erc:byte;
begin
Erc:=0;
{if Size>64 then Size:=Size mod 64;}
if XMSok then
begin
asm
mov ah,XMS_MEMALLOC
mov dx,QSize
call [XMSaddr]
cmp al,1
jne @@1
mov Hnd,dx
jmp @@2
@@1:{XMSerror}
mov erc,bl
mov Hnd,$FFFF
@@2:{End of function}
end;
if Hnd<>$FFFF then
begin
if MO_type=Single then
begin
H1.Handle:=Hnd;
H1.Size:=(QSize shl 10)-1; { Convert from Kilobytes to bytes }
move(H1,EMBHandle,4);
end
else if MO_type=Extended then
begin
H2.Handle:=Hnd;
H2.Offset:=0;
H2.Size:=(longint(QSize) shl 10)-1;
move(H2,EMBHandle,10);
end;
end;
MM_Allocate:=erc;
end;
end;
{****************************************************************************}
function MM_FreeMem;
{****************************************************************************}
{* Clears memory allocated under given handle *}
{****************************************************************************}
var
Hnd:word;
Erc:byte;
begin
if MO_type=Extended then
begin
move(EMBHandle,H2,10);
Hnd:=H2.Handle;
end
else
begin {Single}
move(EMBHandle,H1,4);
Hnd:=H1.Handle;
end;
Erc:=0;
if XMSok then
begin
asm
mov ah,XMS_FREEMEM
mov dx,Hnd
call [XMSaddr]
cmp al,1
jne @@1
mov Hnd,0
jmp @@2
@@1:{XMSerror}
mov erc,bl
mov Hnd,$FFFF
@@2:{End of function}
end;
if MO_type=Extended then
begin
H2.Handle:=0;
H2.Size:=0;
H2.Offset:=0;
move(H2,EMBHandle,10);
end
else
begin {Single}
H1.Handle:=0;
H1.Size:=0;
move(H1,EMBHandle,4);
end;
MM_FreeMem:=Erc;
end;
end;
{****************************************************************************}
BEGIN
Init:=False;
END.