using expanded memory (EMS) 
Author Message
 using expanded memory (EMS)

hello,

does anybody know how I can utilize expanded memory (EMS) in my programs
?
(there are references to a number of books in the FAQ but I do not have
these books.)

thanks
Thomas van Buuren



Tue, 11 May 2004 22:59:20 GMT  
 using expanded memory (EMS)
AND I am using Borland Turbo Pascal 7.0 for DOS, no windows...
Quote:

> hello,

> does anybody know how I can utilize expanded memory (EMS) in my programs
> ?
> (there are references to a number of books in the FAQ but I do not have
> these books.)

> thanks
> Thomas van Buuren



Wed, 12 May 2004 00:40:36 GMT  
 using expanded memory (EMS)


Quote:
> AND I am using Borland Turbo Pascal 7.0 for DOS, no windows...


> > hello,

> > does anybody know how I can utilize expanded memory (EMS) in my programs
> > ?
> > (there are references to a number of books in the FAQ but I do not have
> > these books.)

Why are you interested in using expanded memory in the first place? If the
reason is the limitation of the 640Kb boundary, you are almost certainly
better off with a 32 bit compiler like GNU Pascal or FreePascal.

Back in 1995 (when I didn't know about the 32-bit Pascal compilers...) I
wrote an EMS unit for Turbo Pascal. The code is pasted-in below, but please
be advised that I have forgotten almost everything about the details of EMS
since then (except the basic idea that you map logical pages into physical
pages which reside below the 1Mb boundary accessible from DOS), so I cannot
answer any questions that you may have. Use and abuse the code at your own
risk!!

Best regards,
Jesper Lund

{ Copyright (c) 1995 by Jesper Lund          }
{ Latest modification on: October 17, 1995   }

unit EMS;

interface

uses
  Dos;

const
  EMS_Int = $67;
  MaxActiveHandles = 10;
  EMS_PageSize = 16384;     { bytes }

type
  Str5 = string [5];
  Str8 = string [8];
  ByteSet = set of Byte;

  PhysLogMapRec = record
    LogicalPageNo,
    PhysicalPageNo : Word;
  end;

  PhysLogMapArrayType = array [1..4] of PhysLogMapRec;

{ Global variables exported through this unit }

var
  EMS_StatusCode : Byte;  { Status of the latest EMS operation }
  EMS_MapArray : PhysLogMapArrayType;  { for mapping multiple pages }

function  HexWord (w : Word) : Str5;
function  EMS_Installed : Boolean;
procedure EMS_CheckStatus (ErrorFatal : Boolean);
procedure EMS_PagesAvail (var AvailPages : Word);
procedure EMS_AllocatePages (NoPages : Word; Name : str8; var Handle :
Word);
procedure EMS_DeallocatePages (Handle : Word);
procedure EMS_GetPageFrameAddress (var PageFrameAddress : Word);
function  EMS_AssignPhysicalPagePtr (PhysicalPageNo : Byte) : Pointer;
procedure EMS_SearchHandleName (Name : str8; var Handle : Word;
                                var HandleFound : Boolean);
procedure EMS_GetMappableAddr (Fname : string);

{ NO error checking is done in these procedures }

procedure EMS_MapSinglePage (Handle : Word; PhysicalPageNo : Byte;
                             LogicalPageNo : Word);
procedure EMS_MapMultiplePages (Handle, NoPages : Word);

implementation

{ Function No's below refer to the EMS documentation:     }
{ Lotus/Intel/Microsoft Expanded Memory Specification,    }
{ ver 4.0, October 1987, Document # 300275-005.           }

var
  ExitSave : Pointer;
  NoActiveHandles : Byte;
  ActiveHandles : array [1..MaxActiveHandles] of Word;

{ The initialization procedure and the Exit (error handling) procedure }

procedure EMS_ExitProc; far;
var
  i : Byte;
  Regs : Registers;

begin
  ExitProc := ExitSave;

  for i := 1 to MaxActiveHandles do
  begin
    if ActiveHandles [i] <> 0 then
    begin
      Regs.AH := $45;              { Deallocate pages }
      Regs.DX := ActiveHandles[i]; { Handle whose pages is to be
deallocated }
      Intr (EMS_Int, Regs);
    end; { if }
  end; { for }
end; { EMS_ExitProc }

procedure EMS_Init;
var
  i : Byte;

begin
  for i := 1 to MaxActiveHandles do ActiveHandles [i] := 0;
  NoActiveHandles := 0;

  ExitSave := ExitProc;

end; { EMS_Init }

{ Local procedures }

procedure FindHandleNo (HandleNo : Word; var TablePos : Byte);
var
  i : Byte;

begin
  TablePos := 0;

  for i := 1 to MaxActiveHandles do
  begin
    if ActiveHandles [i] = HandleNo then
    begin
      TablePos := i;
      Break;  { stop searching }
    end; { if }
  end; { for }
end; { FindHandleNo }

procedure EMS_ErrorCheck (const FatalCodes : ByteSet);
begin
  if EMS_StatusCode in FatalCodes then   { non-recoverable errors }
  begin
    Writeln ('Malfunction in the EMS driver');
    ExitProc := ExitSave;
    Halt;
  end; { if }
end; { EMS_ErrorCheck }

{ procedures exported through this unit }

function HexWord (w : Word) : Str5;
const
  hexChars: array [0..$F] of Char = '0123456789ABCDEF';

begin
  HexWord :=  hexChars[Hi(w) shr 4]  +
              hexChars[Hi(w) and $F] +
              hexChars[Lo(w) shr 4]  +
              hexChars[Lo(w) and $F] + 'h';
end; { HexWord }

function EMS_Installed : Boolean;  { Calls Int 21h (DOS interrupt) }
var
  Regs : Registers;
  Int67DeviceName : str8;
  i : Byte;

begin
  Regs.AH := $35;
  Regs.AL := $67;   { EMM interrupt }
  MsDos (Regs);

  Int67DeviceName := '';
  for i := 0 to 7 do
   Int67DeviceName := Int67DeviceName + Chr (Mem [Regs.ES:$0A+i]);

  EMS_Installed := (Int67DeviceName = 'EMMXXXX0');
end; { EMS_Installed }

procedure EMS_CheckStatus (ErrorFatal : Boolean);  { Function 1 }
var
  Regs : Registers;

begin
  Regs.AH := $40;
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;

  if ErrorFatal then
  begin
    EMS_ErrorCheck ([$80..$84]);
  end; { if }
end; { EMS_CheckStatus }

procedure EMS_PagesAvail (var AvailPages : Word);  { Function 3 }
var
  Regs : Registers;

begin
  Regs.AH := $42;
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$84]);

  if EMS_StatusCode = 0 then
  begin
    AvailPages := Regs.BX;
  end;
end; { EMS_PagesAvail }

{ Function 4 (allocate pages) and function 20 (set handle name) }
procedure EMS_AllocatePages (NoPages : Word; Name : str8; var Handle :
Word);
var
  Regs : Registers;
  NameTable : array [1..8] of Char;
  i, PosNo : Byte;

begin
  if NoActiveHandles = MaxActiveHandles then
  begin
    EMS_StatusCode := 1;
    Exit;
  end; { if }

  { Possible recoverable error codes                }
  {    85h = All EMS handles are being used         }
  {    87h = Not enough pages in the system         }
  {    88h = Not enough pages available             }
  {    89h = Tried to allocate zero pages           }
  {    A1h = A handle with the name already exists  }
  {          (occurs in the second Int_67 call).    }

  Regs.AH := $43;
  Regs.BX := NoPages;
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$84]);

  if EMS_StatusCode = 0 then
  begin
    Handle := Regs.DX;

    { Assign a name to the handle }
    for i := 1 to 8 do
    begin
      if i <= Length (Name) then
        NameTable[i] := Name[i]
      else
        NameTable[i] := Chr (0);
    end; { for i := 1 to 8 }

    Regs.AX := $5301;
    Regs.DX := Handle;
    Regs.DS := Seg (NameTable);
    Regs.SI := Ofs (NameTable);
    Intr (EMS_Int, Regs);
    EMS_StatusCode := Regs.AH;
    EMS_ErrorCheck ([$80..$8F]);

    FindHandleNo (0, PosNo);
    ActiveHandles [PosNo] := Handle;
    Inc (NoActiveHandles);
  end; { if }
end; { EMS_AllocatePages }

procedure EMS_DeallocatePages (Handle : Word);  { Function 6 }
var
  PosNo : Byte;
  Regs : Registers;

begin
  FindHandleNo (Handle, PosNo);

  if PosNo = 0 then  { handle not found }
  begin
    EMS_StatusCode := 1; { error }
  end
  else
  begin
    Regs.AH := $45;    { Deallocate pages }
    Regs.DX := Handle; { Handle whose pages is to be deallocated }
    Intr (EMS_Int, Regs);
    EMS_StatusCode := Regs.AH;
    EMS_ErrorCheck ([$80..$84]);

    if EMS_StatusCode = 0 then
    begin
      Dec (NoActiveHandles);
      ActiveHandles [PosNo] := 0;
    end; { if StatusCode = 0 }
  end; { if PosNo = 0 }
end; { EMS_DeallocatePages }

procedure EMS_GetPageFrameAddress (var PageFrameAddress : Word); { Function
2 }
var
  Regs : Registers;

begin
  Regs.AH := $41;
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$84]);
  PageFrameAddress := Regs.BX;
end; { EMS_GetPageFrameAddress }

function EMS_AssignPhysicalPagePtr (PhysicalPageNo : Byte) : Pointer;
var
  FrameSeg : Word;

begin
  if not PhysicalPageNo in [0..3] then  { preliminary check }
  begin
    EMS_StatusCode := 1;
    Exit;
  end;

  EMS_GetPageFrameAddress (FrameSeg);  { Sets EMS_StatusCode }
  if EMS_StatusCode = 0 then
  begin
    EMS_AssignPhysicalPagePtr := Ptr (FrameSeg, PhysicalPageNo *
EMS_PageSize);
  end; { if }
end; { EMS_AssignPtr }

{ Function 21 }
procedure EMS_SearchHandleName (Name : str8; var Handle : Word;
                                var HandleFound : Boolean);
var
  Regs : Registers;
  NameTable : array [1..8] of Char;
  i : Byte;

begin
  HandleFound := False;
  Handle := 999;  { Indicates that the handle has not been found }

  for i := 1 to 8 do
  begin
    if i <= Length (Name) then
      NameTable[i] := Name[i]
    else
      NameTable[i] := Chr (0);
  end; { for i := 1 to 8 }

  Regs.AX := $5401;
  Regs.DS := Seg (NameTable);
  Regs.SI := Ofs (NameTable);
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$8F]);

  if EMS_StatusCode = 0 then
  begin
    Handle := Regs.DX;
    HandleFound := True;
  end; { if }
end; { EMS_SearchHandleName }

procedure EMS_GetMappableAddr (Fname : string);    { Function 25 }
type
  WordArrayType = array [1..32760] of Word;  { Maximum size only }

var
  WordArray : ^WordArrayType;
  Entries, TableSize, i : Word;
  Regs : Registers;
  F : Text;

begin
  Regs.AX := $5801;
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$8F]);

  Entries := Regs.CX;
  TableSize := 4 * Entries;
  GetMem (WordArray, TableSize);

  Regs.AX := $5800;
  Regs.ES := Seg (WordArray^);
  Regs.DI := Ofs (WordArray^);
  Intr (EMS_Int, Regs);
  EMS_StatusCode := Regs.AH;
  EMS_ErrorCheck ([$80..$8F]);

  if EMS_StatusCode = 0 then
  begin
    Assign (F, Fname);
    Rewrite (F);

    Writeln (F);
    Writeln (F, 'EMS Mappable Physical Addresses');
    Writeln (F, '-------------------------------');
    Writeln (F, 'Physical pages: ', Entries);
    Writeln (F);

    for i := 1 to Entries do
    begin
      Write (F, HexWord (WordArray^[2*i-1]), '    ',
                HexWord (WordArray^[2*i]));
      if WordArray^[2*i-1] >=
...

read more »



Wed, 12 May 2004 04:36:49 GMT  
 using expanded memory (EMS)

Quote:
> AND I am using Borland Turbo Pascal 7.0 for DOS, no windows...


> > hello,

> > does anybody know how I can utilize expanded memory (EMS) in my
programs
> > ?

  You can use TEmsStream object from Objects.TPU

--
   Varyonov Konstantin       varkos^mail.ru      http://ghsrl.newmail.ru



Thu, 13 May 2004 01:40:35 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Please Help to Expand Memory

2. Extended/Expanded memory

3. Expanded Memory for TP 7.0

4. Using keyboard to expand a DBLookupComoBox

5. Need help with ems memory!

6. How do I use EMS or XMS memory???

7. How du I use XMS/EMS memory?

8. EMS memory

9. Using EMS for Graphics

10. Insufficient Memory Error using Paradox

11. Using video memory in fpk for linux

12. Using memory buffer as a temporary place

 

 
Powered by phpBB® Forum Software