[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]

    {
      From: Andrew Eigus                                 Read: Yes    Replied: No

    > Well, the subject says it, how can I get a 65536 Bytes hunk of memory?
    > There has to be another way, maybe a dos call or something?

    Yes. The following are routines to allocate memory using DOS functions,
    the limitation is that HeapMin and HeapMax should be set both to zero like
    this: {$M 8192,0,0}

    Function DosMaxAvail : longint;
    {$IFNDEF ProtectedMode}
    assembler;
    { Returns the size of the largest contiguous free memory block
      This function should be called ONLY when both HeapMin/HeapMax
      memory allocation parameters set to zero }
    Asm
      mov bx,0FFFFh
      mov ah,48h
      int 21h
      mov ax,bx
      mov bx,16
      mul BX
    End;
    {$ELSE}
    Begin
      DosMaxAvail := GetFreeSpace(0) { uses WinAPI for DPMI }
    End; { DosMaxAvail }
    {$ENDIF}

    Function DosGetMem(Size : longint) : pointer;
    { Creates a dynamic variable of the specified size and returns the pointer
      to it. This function should be called ONLY when both HeapMin/HeapMax
      memory allocation parameters set to zero. This function returns a pointer to
      allocated data buffer which can lie in different segments, or it returns
      a nil pointer if the dos call was unsuccessful; in that case, the
    Dos.DosError variable keeps error code }{$IFNDEF ProtectedMode}
    assembler;
    Asm
    @@1:
      mov DosError,0 { uses Dos }
      mov ax,word ptr [Size]
      mov dx,word ptr [Size+2]
      mov cx,16
      div cx
      inc ax
      mov bx,ax
      mov ah,48h
      int 21h
      jnc @@2
      mov DosError,ax { save error code in Dos.DosError variable }
      xor ax,ax { return nil pointer }
    @@2:
      mov dx,ax { save segment }
      xor ax,ax { offset allways zero }
    End;
    {$ELSE}
    Begin
      DosGetMem := GlobalAllocPtr(gmem_ZeroInit or gmem_Moveable, Size) { WinAPI }
    End; { DosGetMem }
    {$ENDIF}

    Function DosFreeMem(P : pointer) : integer;
    { Disposes of a given dynamic variable. This function should be called ONLY
      when both HeapMin/HeapMax memory allocation parameters set to zero. This
      function returns non-zero DOS error code if the function failed, or zero
      if the call was successful }
    {$IFNDEF ProtectedMode}
    assembler;
    Asm
      mov DosError,0 { set Dos.DosError to noerror }
      mov es,word ptr [P+2]
      mov ah,49h
      int 21h
      jnc @@1
      mov DosError,ax
    End;
    {$ELSE}
    Begin
      DosFreeMem := GlobalFreePtr(P)
    End; { DosFreeMem }
    {$ENDIF}

    Function DosRegetMem(P : pointer; NewSize : longint) : pointer;
    { Changes the size of an existing memory block. This function should be called
      ONLY when both HeapMin/HeapMax memory allocation parameters set to zero.
      It returns a nil pointer, if the call was unsuccessful, otherwise it returns
      a pointer to reallocated data buffer }
    {$IFNDEF ProtectedMode}
    assembler;
    Asm
    @@1:
      mov DosError,0 { using Dos unit still :) }
      mov ax,word ptr [NewSize]
      mov dx,word ptr [NewSize+2]
      mov cx,16
      div cx
      inc ax
      mov bx,ax
      mov ah,4Ah
      int 21h
      jnc @@2
      mov DorError,ax { save error code in DosError }
      xor ax,ax { return a nil pointer }
    @@2:
      mov dx,ax
      xor ax,ax
    End;
    {$ELSE}
    Begin
      DosRegetMem := GlobalReallocPtr(P, NewSize, gmem_ZeroInit or gmem_Moveable)
    End; { DosRegetMem }
    {$ENDIF}

    Example:

      {$M 4096,0,0}
      var P : pointer;

      Begin
        P := DosGetMem(128 shl 10); { allocate 128k }
        if P = nil then
          WriteLn('It seems that you haven''t enough memory, eh?')
        else
        begin
          P := DosRegetMem(256 shl 10); { reallocate this block to 256k }
          if P = nil then
            WriteLn('No, 256k is too much! :-)')
        end;
        DosFreeMem(P)
      End.

[Back to MEMORY SWAG index] [Back to Main SWAG index] [Original]