home *** CD-ROM | disk | FTP | other *** search
- {$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.
-