[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]
{
Here is the UMB_Heap unit i found in a copy of PC Magazine a while back..
This code works on my 486DX/2 66mhz with 4meg ram... so it should (i hope)
run on yourz too.... All you need to do to use this is just call
Extend_Heap in your program someplace to get the extra heap memory, and
GetBlockSizes if you wish to know how large the UMB blocks are that were
allocated...
}
Unit
UMB_Heap;
Interface
Const
Max_Blocks = 4;
Type
UMBDataType = Array[1..Max_Blocks] Of Word;
Procedure Extend_Heap;
Procedure GetBlockSizes(Var US : UMBDataType);
Implementation
Type
PFreeRec = ^TFreeRec;
TFreeRec = Record
Next : PFreeRec;
Size : Pointer;
End;
Var
Block_Segments : UMBDataType;
Block_Sizes : UMBDataType;
SaveExitProc : Pointer;
Function UMB_Driver_Present : Boolean;
Var
Flag : Boolean;
Begin
Flag := False;
Asm
Mov AX, $4300
Int $2F
CMP AL, $80
JNE @Done
Inc [Flag]
@Done:
End;
UMB_Driver_Present := Flag;
End;
Procedure Allocate_UMB;
Var
I,
Save_Strategy,
Block_Segment,
Block_Size : Word;
Begin
For I := 1 To Max_Blocks Do
Begin
Block_Segments[I] := 0;
Block_Sizes[I] := 0;
End;
Asm
Mov AX, $5801
Mov BX, $0FFFF
Int $21
Mov AX, $5803
Mov BX, $0001
Int $21
End;
For I := 1 To Max_Blocks Do
Begin
Block_Segment := 0;
Block_Size := 0;
Asm
Mov AX, $4800
Mov BX, $0FFFF
Int $21
CMP BX, 0
JE @Fail
Mov AX, $4800
Int $21
JC @Fail
Mov [Block_Segment], AX
Mov [Block_Size], BX
@Fail:
End;
Block_Segments[I] := Block_Segment;
Block_Sizes[I] := Block_Size;
End;
End;
Procedure Release_UMB; Far;
Var
I,
Segment : Word;
Begin
ExitProc := SaveExitProc;
Asm
Mov AX, $5803
Mov BX, $0000
Int $21
End;
For I := 1 To Max_Blocks Do
Begin
Segment := Block_Segments[I];
If (Segment > 0) Then
Asm
Mov AX, $4901
Mov BX, [Segment]
Mov ES, BX
Int $21
End;
End;
End;
Function Pointer_To_LongInt(p : Pointer) : LongInt;
Type
PtrRec = Record
Lo, Hi : Word;
End;
Begin
Pointer_To_LongInt := LongInt(PtrRec(P).Hi * 16 + PtrRec(P).Lo);
End;
Procedure Extend_Heap;
Var
I : Word;
Temp : PFreeRec;
Begin
If UMB_Driver_Present then
Begin
Allocate_UMB;
Temp := HeapPtr;
I := 1;
While ((Block_Sizes[I] > 0) And
(I <= Max_Blocks)) Do
Begin
Temp^.Next := Ptr(Block_Segments[I], 0);
Temp := Temp^.Next;
Temp^.Next := HeapPtr;
Move(Block_Sizes[I], Temp^.Size, SizeOf(Word));
Temp^.Size := Pointer(LongInt(Temp^.Size) SHL 16);
Inc(I);
End;
If (Block_Sizes[1] > 0) then
FreeList := Ptr(Block_Segments[1], 0);
End;
End;
Procedure GetBlockSizes(Var US : UMBDataType);
Begin
US := Block_Sizes;
End;
Begin
FillChar(Block_Sizes, SizeOf(Block_Sizes), 0);
SaveExitProc := ExitProc;
ExitProc := @Release_UMB;
End.
[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]