home *** CD-ROM | disk | FTP | other *** search
- program Ems_Test;
- { *************************************************************
- * This program shows you how to use the basic functions of *
- * the LIM Expanded Memory Specification. Since it does not *
- * use any of the LIM EMS 4.0 function calls, you can also *
- * use it on systems with EMS versions less than 4.0 *
- ************************************************************* }
-
- { Written by:
- Peter Immarco.
- Thought Dynamics
- Manhattan Beach, CA
- Compuserve ID# 73770,123
- *** Public Domain ***
-
- Used by permission of the author.
- }
-
- { This program does the following:
- +------------------------------------------------------------+
- | * Makes sure the LIM Expanded Memory Manager (EMM) has |
- | been installed in memory |
- | * Displays the version number of the EMM present in memory |
- | * Determines if there are enough pages (16k blocks) of |
- | memory for our test program's usage. It then displays |
- | the total number of EMS pages present in the system, |
- | and how many are available for our usage |
- | * Requests the desired number of pages from the EMM |
- | * Maps a logical page onto one of the physical pages given |
- | to us |
- | * Displays the base address of our EMS memory page frame |
- | * Performs a simple read/write test on the EMS memory given|
- | to us |
- | * Returns the EMS memory given to us back to the EMM, and |
- | exits |
- +------------------------------------------------------------|}
-
-
- { All the calls are structured to return the result or error
- code of the Expanded Memory function performed as an integer.
- If the error code is not zero, which means the call failed,
- a simple error procedure is called and the program terminates.}
-
- uses Crt, Dos;
-
- Type
- ST3 = string[3];
- ST80 = string[80];
- ST5 = string[5];
-
- Const
- EMM_INT = $67;
- DOS_Int = $21;
- GET_PAGE_FRAME = $41;
- GET_UNALLOCATED_PAGE_COUNT= $42;
- ALLOCATE_PAGES = $43;
- MAP_PAGES = $44;
- DEALLOCATE_PAGES = $45;
- GET_VERSION = $46;
-
- STATUS_OK = 0;
-
- { We'll say we need 1 EMS page for our application }
- APPLICATION_PAGE_COUNT = 1;
-
- Var
- Regs: Registers;
- Emm_Handle,
- Page_Frame_Base_Address,
- Pages_Needed,
- Physical_Page,
- Logical_Page,
- Offset,
- Error_Code,
- Pages_EMS_Available,
- Total_EMS_Pages,
- Available_EMS_Pages: Word;
- Version_Number,
- Pages_Number_String: ST3;
- Verify: Boolean;
-
- { * --------------------------------------------------------- * }
- { The function Hex_String converts an Word into a four
- character hexadecimal number(string) with leading zeroes. }
- Function Hex_String(Number: Word): ST5;
- Function Hex_Char(Number: Word): Char;
- Begin
- If Number<10 then
- Hex_Char:=Char(Number+48)
- else
- Hex_Char:=Char(Number+55);
- end; { Function Hex_Char }
-
- Var
- S: ST5;
- Begin
- S:='';
- S:=Hex_Char( (Number shr 1) div 2048);
- Number:=( ((Number shr 1) mod 2048) shl 1)+
- (Number and 1) ;
- S:=S+Hex_Char(Number div 256);
- Number:=Number mod 256;
- S:=S+Hex_Char(Number div 16);
- Number:=Number mod 16;
- S:=S+Hex_Char(Number);
- Hex_String:=S+'h';
- end; { Function Hex_String }
-
- { * --------------------------------------------------------- * }
-
- { The function Emm_Installed checks to see if the Expanded
- Memory Manager (EMM) is loaded in memory. It does this by
- looking for the string 'EMMXXXX0', which should be located
- at 10 bytes from the beginning of the code segment pointed
- to by the EMM interrupt, 67h }
- Function Emm_Installed: Boolean;
- Var
- Emm_Device_Name : string[8];
- Int_67_Device_Name : string[8];
- Position : Word;
- Regs : registers;
-
- Begin
- Int_67_Device_Name:='';
- Emm_Device_Name :='EMMXXXX0';
- with Regs do
- Begin
- { Get the code segment pointed to by Interrupt 67h, the EMM
- interrupt by using DOS call $35, 'get interrupt vector' }
- AH:=$35;
- AL:=EMM_INT;
- Intr(DOS_int,Regs);
-
- { The ES pseudo-register contains the segment address pointed
- to by Interrupt 67h }
- { Create an 8 character string from the 8 successive bytes
- pointed to by ES:$0A (10 bytes from ES) }
- For Position:=0 to 7 do
- Int_67_Device_Name:=
- Int_67_Device_Name+Chr(mem[ES:Position+$0A]);
- Emm_Installed:=True;
- { Is it the EMM manager signature, 'EMMXXXX0'? then EMM is
- installed and ready for use, if not, then the EMM manager
- is not present }
- If Int_67_Device_Name<>Emm_Device_Name
- then Emm_Installed:=False;
- end; { with Regs do }
- end; { Function Emm_Installed }
-
- { * --------------------------------------------------------- * }
-
- { This function returns the total number of EMS pages present
- in the system, and the number of EMS pages that are
- available for our use }
- Function EMS_Pages_Available
- (Var Total_EMS_Pages,Pages_Available: Word): Word;
- Var
- Regs: Registers;
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-
- register }
- AH:=Get_Unallocated_Page_Count;
- intr(EMM_INT,Regs);
- { The number of EMS pages available is returned in BX }
- Pages_Available:=BX;
- { The total number of pages present in the system is
- returned in DX }
- Total_EMS_Pages:=DX;
- { Return the error code }
- EMS_Pages_Available:=AH
- end;
- end; { EMS_Pages_Available }
-
- { * --------------------------------------------------------- * }
-
- { This function requests the desired number of pages from the
- EMM }
- Function Allocate_Expanded_Memory_Pages
- (Pages_Needed: Word; Var Handle: Word ): Word;
- Var
- Regs: Registers;
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-
- register }
- AH:= Allocate_Pages;
- { Put the desired number of pages in BX }
- BX:=Pages_Needed;
- intr(EMM_INT,Regs);
- { Our EMS handle is returned in DX }
- Handle:=DX;
- { Return the error code }
- Allocate_Expanded_Memory_Pages:=AH;
- end;
- end; { Function Allocate_Expanded_Memory_Pages }
-
- { * --------------------------------------------------------- * }
-
- { This function maps a logical page onto one of the physical
- pages made available to us by the
- Allocate_Expanded_Memory_Pages function }
- Function Map_Expanded_Memory_Pages
- (Handle,Logical_Page,Physical_Page: Word): Word;
- Var
- Regs: Registers;
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-
- register }
- AH:=Map_Pages;
- { Put the physical page number to be mapped into AL }
- AL:=Physical_Page;
- { Put the logical page number to be mapped in BX }
- BX:=Logical_Page;
- { Put the EMS handle assigned to us earlier in DX }
- DX:=Handle;
- Intr(EMM_INT,Regs);
- { Return the error code }
- Map_Expanded_Memory_Pages:=AH;
- end; { with Regs do }
- end; { Function Map_Expanded_Memory_Pages }
-
- { * --------------------------------------------------------- * }
-
- { This function gets the physical address of the EMS page
- frame we are using. The address returned is the segment
- of the page frame. }
- Function Get_Page_Frame_Base_Address
- (Var Page_Frame_Address: Word): Word;
- Var
- Regs: Registers;
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-
- register }
- AH:=Get_Page_Frame;
- intr(EMM_INT,Regs);
- { The page frame base address is returned in BX }
- Page_Frame_Address:=BX;
- { Return the error code }
- Get_Page_Frame_Base_Address:=AH;
- end; { Regs }
- end; { Function Get_Page_Frame_Base_Address }
-
- { * --------------------------------------------------------- * }
-
- { This function releases the EMS memory pages allocated to
- us, back to the EMS memory pool. }
- Function Deallocate_Expanded_Memory_Pages
- (Handle: Word): Word;
- Var
- Regs: Registers;
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-register }
- AH:=DEALLOCATE_PAGES;
- { Put the EMS handle assigned to our EMS memory pages in DX }
- DX:=Emm_Handle;
- Intr(EMM_INT,Regs);
- { Return the error code }
- Deallocate_Expanded_Memory_Pages:=AH;
- end; { with Regs do }
- end; { Function Deallocate_Expanded_Memory_Pages }
-
- { * --------------------------------------------------------- * }
-
- { This function returns the version number of the EMM as
- a 3 character string. }
- Function Get_Version_Number(Var Version_String: ST3): Word;
- Var
- Regs: Registers;
- Word_Part,Fractional_Part: Char;
-
- Begin
- with Regs do
- Begin
- { Put the desired EMS function number in the AH pseudo-register }
- AH:=GET_VERSION;
- Intr(EMM_INT,Regs);
- { See if call was successful }
- If AH=STATUS_OK then
- Begin
- { The upper four bits of AH are the Word portion of the
- version number, the lower four bits are the fractional
- portion. Convert the Word value to ASCII by adding 48. }
- Word_Part := Char( AL shr 4 + 48);
- Fractional_Part:= Char( AL and $F +48);
- Version_String:= Word_Part+'.'+Fractional_Part;
- end; { If AH=STATUS_OK }
- { Return the function calls error code }
- Get_Version_Number:=AH;
- end; { with Regs do }
- end; { Function Get_Version_Number }
-
- { * --------------------------------------------------------- * }
-
- { This procedure prints an error message passed by the caller,
- prints the error code passed by the caller in hex, and then
- terminates the program with the an error level of 1 }
-
- Procedure Error(Error_Message: ST80; Error_Number: Word);
- Begin
- Writeln(Error_Message);
- Writeln(' Error_Number = ',Hex_String(Error_Number) );
- Writeln('EMS test program aborting.');
- Halt(1);
- end; { Procedure Error_Message }
-
- { * --------------------------------------------------------- * }
-
- { EMS_TEST }
-
- { This program is an example of the basic EMS functions that you
- need to execute in order to use EMS memory with Turbo Pascal }
-
- Begin
- ClrScr;
- Window(5,2,77,22);
-
- { Determine if the Expanded Memory Manager is installed, If
- not, then terminate 'main' with an ErrorLevel code of 1. }
-
- If not (Emm_Installed) then
- Begin
- Writeln('The LIM Expanded Memory Manager is not installed.');
- Halt(1);
- end;
-
- { Get the version number and display it }
- Error_Code:= Get_Version_Number(Version_Number);
- If Error_Code<>STATUS_OK then
- Error('Error trying to get the EMS version number ',
- Error_code)
- else
- Writeln('LIM Expanded Memory Manager, version ',
- Version_Number,' is ready for use.');
- Writeln;
-
- { Determine if there are enough expanded memory pages for this
- application. }
- Pages_Needed:=APPLICATION_PAGE_COUNT;
- Error_Code:=
- EMS_Pages_Available(Total_EMS_Pages,Available_EMS_Pages);
- If Error_Code<>STATUS_OK then
- Error('Error trying to determine the number of EMS pages available.',
- Error_code);
-
- Writeln('There are a total of ',Total_EMS_Pages,
- ' expanded memory pages present in this system.');
- Writeln(' ',Available_EMS_Pages,
- ' of those pages are available for your usage.');
- Writeln;
-
- { If there is an insufficient number of pages for our application,
- then report the error and terminate the EMS test program }
- If Pages_Needed>Available_EMS_Pages then
- Begin
- Str(Pages_Needed,Pages_Number_String);
- Error('We need '+Pages_Number_String+
- ' EMS pages. There are not that many available.',
- Error_Code);
- end; { Pages_Needed>Available_EMS_Pages }
-
- { Allocate expanded memory pages for our usage }
- Error_Code:= Allocate_Expanded_Memory_Pages(Pages_Needed,Emm_Handle);
- Str(Pages_Needed,Pages_Number_String);
- If Error_Code<>STATUS_OK then
- Error('EMS test program failed trying to allocate '+Pages_Number_String+
- ' pages for usage.',Error_Code);
- Writeln(APPLICATION_PAGE_COUNT,
- ' EMS page(s) allocated for the EMS test program.');
- Writeln;
-
- { Map in the required logical pages to the physical pages
- given to us, in this case just one page }
- Logical_Page :=0;
- Physical_Page:=0;
- Error_Code:=
- Map_Expanded_Memory_Pages(
- Emm_Handle,Logical_Page,Physical_Page);
- If Error_Code<>STATUS_OK then
- Error('EMS test program failed trying to map '+
- 'logical pages onto physical pages.',Error_Code);
-
- Writeln('Logical Page ',Logical_Page,
- ' successfully mapped onto Physical Page ',
- Physical_Page);
- Writeln;
-
- { Get the expanded memory page frame address }
- Error_Code:= Get_Page_Frame_Base_Address(Page_Frame_Base_Address);
- If Error_Code<>STATUS_OK then
- Error('EMS test program unable to get the base Page'+
- ' Frame Address.',Error_Code);
- Writeln('The base address of the EMS page frame is - '+
- Hex_String(Page_Frame_Base_Address) );
- Writeln;
-
- { Write a test pattern to expanded memory }
- For Offset:=0 to 16382 do
- Mem[Page_Frame_Base_Address:Offset]:=Offset mod 256;
-
- { Make sure that what is in EMS memory is what we just wrote }
- Writeln('Testing EMS memory.');
-
- Offset:=1;
- Verify:=True;
- while (Offset<=16382) and (Verify=True) do
- Begin
- If Mem[Page_Frame_Base_Address:Offset]<>Offset mod 256 then
- Verify:=False;
- Offset:=Succ(Offset);
- end; { while (Offset<=16382) and (Verify=True) }
-
- { If it isn't report the error }
- If not Verify then
- Error('What was written to EMS memory was not found during '+
- 'memory verification test.',0);
- Writeln('EMS memory test successful.');
- Writeln;
-
- { Return the expanded memory pages given to us back to the
- EMS memory pool before terminating our test program }
- Error_Code:=Deallocate_Expanded_Memory_Pages(Emm_Handle);
- If Error_Code<>STATUS_OK then
- Error('EMS test program was unable to deallocate '+
- 'the EMS pages in use.',Error_Code);
- Writeln(APPLICATION_PAGE_COUNT,
- ' page(s) deallocated.');
- Writeln;
- Writeln('EMS test program completed.');
- end.