home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
source
/
tpwhuge
/
hugemem.pas
Wrap
Pascal/Delphi Source File
|
1991-08-05
|
6KB
|
233 lines
{$A+,B-,I-,N-,R-,S-,V-,W+,X+}
Unit HugeMem;
{ HugeMem - manage huge global memory blocks
written by Peter Sawatzki <IN307@DHAFEU11>
(c) 1-May-1991 ver.0.1
This unit uses two undocumented windows 'functions':
__AHShift
__AHIncr
both are used by Microsoft C and Borland C to handle the HUGE
memory model, so i think it's ok to use it
}
Interface
Uses
WinTypes,
WinProcs;
Procedure hRead (Var aFile: File; aHandle: THandle; Size: LongInt);
Procedure hWrite (Var aFile: File; aHandle: THandle; Size: LongInt);
Procedure hMove (srcHandle, dstHandle: THandle; Size: LongInt);
Procedure hFillChar (aHandle: THandle; Size: LongInt; aByte: Byte);
Procedure hPutByte (aHandle: THandle; aByte: Byte; aLoc: LongInt);
Function hByteAt (aHandle: THandle; aLoc: LongInt): Byte;
Procedure pMove (srcPtr, dstPtr: Pointer; Size: LongInt);
Function IncPtr (aPtr: Pointer; anOffset: Word): Pointer;
Procedure AHIncr;
Procedure AHShift;
{NOTE: all procedures operate on unlocked memory blocks. Easily one can
add procedures to operate on locked memory blocks e.g. on Pointers, but
one must be careful not to cross segment boundaries. For example a
Move (x^,y^,$8000) will fail, if Word(x)>=$8001 !!!!!
}
Implementation
Procedure AHIncr; External 'KERNEL' Index 114; {magic function}
Procedure AHShift; External 'KERNEL' Index 113; {dito}
{note: AHincr is 8 in Standard and Enhanced mode, $1000 in real mode.
AHshift is 3 in Standard and Enhanced mode, 12 in real mode
(2^AHshift=AHincr)
}
Const
MaxBlock = $10000 Div 2; {- n Blocks *must* fit in a 64k Segment}
{-hrw: read/write huge amount of data:
aFile - File to read from/write to
aHandle - Handle to memory block of at least Size bytes memory
Size - number of bytes to transfer
rflag - read from file if True, write to file if False
}
procedure hrw(Var aFile: File; aHandle: THandle; Size: LongInt; rflag: Boolean);
var
Count: Word;
anAddr: Pointer;
begin
anAddr:= GlobalLock(aHandle);
while Size > 0 do begin
if Size>MaxBlock Then
Count:= MaxBlock
Else
Count:= Word(Size);
If rflag Then
BlockRead(aFile, anAddr^, Count)
Else
BlockWrite(aFile,anAddr^, Count);
Dec(Size,Count);
Asm
Mov Ax,Count
Add Word Ptr anAddr,Ax
Jnc @@1
Add Word Ptr anAddr+2,OFFSET AHIncr
@@1:
End;
end;
GlobalUnlock(aHandle);
end;
Procedure hread(Var aFile: File; aHandle: THandle; Size: LongInt);
Begin
hrw(aFile,aHandle,Size,True)
End;
Procedure hwrite(Var aFile: File; aHandle: THandle; Size: LongInt);
Begin
hrw(aFile,aHandle,Size,False)
End;
{-hMove: copy Size bytes from memory block srcHandle to dstHandle}
Procedure hMove (srcHandle, dstHandle: THandle; Size: LongInt);
Var
srcAdr, dstAdr: Pointer;
Count: Word;
Begin
srcAdr:= GlobalLock(srcHandle);
dstAdr:= GlobalLock(dstHandle);
While Size>0 Do Begin
If Size>MaxBlock Then
Count:= MaxBlock
Else
Count:= Word(Size);
Move(srcAdr^,dstAdr^,Count);
Dec(Size,Count);
Asm
Mov Ax,Count
Add Word Ptr srcAdr,Ax
Jnc @@1
Add Word Ptr srcAdr+2,OFFSET AHIncr
@@1:Add Word Ptr dstAdr,Ax
Jnc @@2
Add Word Ptr dstAdr+2,OFFSET AHIncr
@@2:
End;
End;
GlobalUnlock(srcHandle);
GLobalUnlock(dstHandle);
End;
{-hFillChar: fill memory block with aByte}
Procedure hFillChar (aHandle: THandle; Size: LongInt; aByte: Byte);
Var
anAddr: Pointer;
Count: Word;
Begin
anAddr:= GlobalLock(aHandle);
While Size>0 Do Begin
If Size>MaxBlock Then
Count:= MaxBlock
Else
Count:= Word(Size);
FillChar(anAddr^,Count,aByte);
Dec(Size,Count);
Asm
Mov Ax,Count
Add Word Ptr anAddr,Ax
Jnc @@1
Add Word Ptr anAddr+2,OFFSET AHIncr
@@1:
End;
End;
GlobalUnlock(aHandle);
End;
Procedure hPutByte (aHandle: THandle; aByte: Byte; aLoc: LongInt);
Var
anAddr: Pointer;
Begin
anAddr:= GlobalLock(aHandle);
Asm
Mov Ax,Word Ptr aLoc
Add Word Ptr anAddr,Ax {Mov would work as well!}
Mov Ax,Word Ptr aLoc+2
Mov Cx,OFFSET AHShift
Shl Ax,Cl {Calculate segment}
Add Word Ptr anAddr+2,Ax
End;
Byte(anAddr^):= aByte;
GlobalUnlock(aHandle);
End;
Function hByteAt (aHandle: THandle; aLoc: LongInt): Byte;
Var
aPtr: Pointer;
Begin
aPtr:= GlobalLock(aHandle);
Asm
Mov Ax,Word Ptr aLoc
Add Word Ptr aPtr,Ax {Mov would work as well!}
Mov Ax,Word Ptr aLoc+2
Mov Cx,OFFSET AHShift
Shl Ax,Cl {Calculate segment}
Add Word Ptr aPtr+2,Ax
End;
hByteAt:= Byte(aPtr^);
GlobalUnlock(aHandle);
End;
Procedure pMove (srcPtr, dstPtr: Pointer; Size: LongInt);
Var
Count: Word;
Begin
While Size>0 Do Begin
If Size>MaxBlock Then
Count:= MaxBlock
Else
Count:= Word(Size);
Asm
Mov Ax,Word(srcPtr)
Add Ax,Count
Jnc @@1
Sub Count,Ax
@@1:Mov Ax,Word(dstPtr)
Add Ax,Count
Jnc @@2
Sub Count,Ax
@@2:
End;
Move(srcPtr^,dstPtr^,Count);
Dec(Size,Count);
Asm
Mov Ax,Count
Add Word Ptr srcPtr,Ax
Jnc @@1
Add Word Ptr srcPtr+2,OFFSET AHIncr
@@1:Add Word Ptr dstPtr,Ax
Jnc @@2
Add Word Ptr dstPtr+2,OFFSET AHIncr
@@2:
End;
End;
End;
Function IncPtr (aPtr: Pointer; anOffset: Word): Pointer;
Assembler;
Asm
Mov Dx,Word Ptr aPtr[2]
Mov Ax,Word Ptr aPtr
Add Ax,anOffset
Jnc @@1
Add Dx,Offset AHincr
@@1:
End;
End.