{ Here are the routines I wrote. The PtrToLong routine is from TurboPower's OPINLINE unit; it just converts a pointer to a linear address, using 16*seg + ofs (in longint arithmetic, of course). Other than that, I think everything should be obvious. From: dmurdoch@mast.queensu.ca (Duncan Murdoch) } {$ifndef dpmi} type PFreeRec = ^TFreeRec; TFreeRec = record next: PFreeRec; size: Pointer; end; procedure GetMemHuge(var p:HugePtr;size:Longint); const blocksize = $FFF0; var prev,free : PFreeRec; save,temp : pointer; block : word; begin { Handle the easy cases first } if size > maxavail then p := nil else if size < 65521 then getmem(p,size) else begin {$ifndef ver60} {$ifndef ver70} The code below is extremely version specific to the TP 6/7 heap manager!! {$endif} {$endif} { Find the block that has enough space } prev := PFreeRec(@freeList); free := prev^.next; while (free <> heapptr) and (PtrToLong(free^.size) < size) do begin prev := free; free := prev^.next; end; { Now free points to a region with enough space; make it the first one and multiple allocations will be contiguous. } save := freelist; freelist := free; { In TP 6, this works; check against other heap managers } while size > 0 do begin block := minlong(blocksize,size); dec(size,block); getmem(temp,block); end; { We've got what we want now; just sort things out and restore the free list to normal } p := free; if prev^.next <> freelist then begin prev^.next := freelist; freelist := save; end; end; end; procedure FreeMemHuge(var p:HugePtr;size : longint); const blocksize = $FFF0; var block : word; begin while size > 0 do begin block := minlong(blocksize,size); dec(size,block); freemem(p,block); p := Normalized(AddWordToPtr(p,block)); end; end; {$else} Procedure GetMemHuge(var p : HugePtr; Size: LongInt); begin if Size < 65521 then GetMem(p,size) else p := GlobalAllocPtr(gmem_moveable,Size); end; Procedure FreeMemHuge(var p : HugePtr; Size: Longint); var h : THandle; begin if Size < 65521 then Freemem(p,size) else h := GlobalFreePtr(p); end; {$endif}