Want to see what people are talking about? See the latest forum posts.
*/
*/

View \HUGEMEM.PAS

Manage Huge Global Memory Blocks

Submitted By: WEBMASTER
Rating: Not rated (Rate It)


{$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.

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.
Resource Listings