home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PSP.ZIP / SAMPLE.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1988-04-10  |  17.8 KB  |  440 lines

  1. PROGRAM Ems_Test;
  2.  
  3. (*******************************************************************)
  4. (* This program shows you how to use the basic functions of the    *)
  5. (* LIM Expanded Memory Specification. Since it does not use any of *)
  6. (* the LIM EMS 4.0 function calls, you can also use it on systems  *)
  7. (* with EMS versions less than 4.0                                 *)
  8. (*                                                                 *)
  9. (* Written by:                                                     *)
  10. (*   Peter Immarco.                                                *)
  11. (*    Thought Dynamics                                             *)
  12. (*    Manhattan Beach, CA                                          *)
  13. (*    Compuserve ID# 73770,123                                     *)
  14. (*     *** Public Domain ***                                       *)
  15. (*                                                                 *)
  16. (* Used by permission of the author.                               *)
  17. (*                                                                 *)
  18. (* This program does the following:                                *)
  19. (*                                                                 *)
  20. (* * Makes sure the LIM Expanded Memory Manager (EMM) has been     *)
  21. (*   installed in memory                                           *)
  22. (* * Displays the version number of the EMM present in memory      *)
  23. (* * Determines if there are enough pages (16k blocks) of memory   *)
  24. (*   for our test program's usage. It then displays the total num- *)
  25. (*   ber of EMS pages present in the system, and how many are      *)
  26. (*   available for our usage                                       *)
  27. (* * Requests the desired number of pages from the EMM             *)
  28. (* * Maps a logical page onto one of the physical pages given to   *)
  29. (*   us                                                            *)
  30. (* * Displays the base address of our EMS memory page frame        *)
  31. (* * Performs a simple read/write test on the EMS memory given to  *)
  32. (*   us                                                            *)
  33. (* * Returns the EMS memory given to us back to the EMM, and exits *)
  34. (*                                                                 *)
  35. (* All the calls are structured to return the result or error code *)
  36. (* of the Expanded Memory function performed as an integer.  If    *)
  37. (* the error code is not zero, which means the call failed, a sim- *)
  38. (* ple error procedure is called and the program terminates.       *)
  39. (*                                                                 *)
  40. (*******************************************************************)
  41.  
  42. USES
  43.   Crt, Dos;
  44.  
  45. TYPE
  46.   ST3  = string[3];
  47.   ST80 = string[80];
  48.   ST5  = string[5];
  49.  
  50. CONST
  51.   EMM_INT                    = $67;
  52.   DOS_Int                    = $21;
  53.   Get_Page_Frame             = $41;
  54.   Get_Unallocated_Page_Count = $42;
  55.   Allocate_Pages             = $43;
  56.   Map_Pages                  = $44;
  57.   Deallocate_Pages           = $45;
  58.   Get_Version                = $46;
  59.  
  60.   Status_OK                  = 0;
  61.  
  62.   (* We'll say we need 1 EMS page for our application               *)
  63.   APPLICATION_PAGE_COUNT     = 1;
  64.  
  65. VAR
  66.   Regs: Registers;
  67.   Emm_Handle,
  68.   Page_Frame_Base_Address,
  69.   Pages_Needed,
  70.   Physical_Page,
  71.   Logical_Page,
  72.   Offset,
  73.   Error_Code,
  74.   Pages_EMS_Available,
  75.   Total_EMS_Pages,
  76.   Available_EMS_Pages: Word;
  77.   Version_Number,
  78.   Pages_Number_String: ST3;
  79.   Verify: Boolean;
  80.  
  81. FUNCTION Hex_String(Number: Word): ST5;
  82. (*******************************************************************)
  83. (* The function Hex_String converts an Word into a four character  *)
  84. (* hexadecimal number(string) with leading zeroes.                 *)
  85. (*******************************************************************)
  86.   Var
  87.     S: ST5;
  88.   Function Hex_Char(Number: Word): Char;
  89.     Begin
  90.       If Number<10 then
  91.         Hex_Char:=Char(Number+48)
  92.       else
  93.         Hex_Char:=Char(Number+55);
  94.     End;  (* Function Hex_Char *)
  95.   Begin  (* Hex_String *)
  96.     S          :='';
  97.     S          := Hex_Char((Number shr 1) div 2048);
  98.     Number     := (((Number shr 1) mod 2048) shl 1) + (Number and 1) ;
  99.     S          := S+Hex_Char(Number div 256);
  100.     Number     := Number mod 256;
  101.     S          := S + Hex_Char(Number div 16);
  102.     Number     := Number mod 16;
  103.     S          := S + Hex_Char(Number);
  104.     Hex_String := S + 'h';
  105.   End;  (* Function Hex_String *)
  106.  
  107. FUNCTION Emm_Installed: Boolean;
  108. (*******************************************************************)
  109. (* The function Emm_Installed checks to see if the Expanded Memory *)
  110. (* Manager (EMM) is loaded in memory. It does this by looking for  *)
  111. (* the string 'EMMXXXX0', which should be located at 10 bytes from *)
  112. (* the beginning of the code segment pointed to by the EMM inter-  *)
  113. (* rupt, 67h                                                       *)
  114. (*******************************************************************)
  115.   Var
  116.     Emm_Device_Name    : string[8];
  117.     Int_67_Device_Name : string[8];
  118.     Position           : Word;
  119.     Regs               : registers;
  120.   Begin
  121.     Int_67_Device_Name := '';
  122.     Emm_Device_Name    := 'EMMXXXX0';
  123.     with Regs do
  124.       Begin
  125.  
  126.         (* Get the code segment pointed to by Interrupt 67h, the EMM in-  *)
  127.         (* terrupt by using DOS call $35, 'get interrupt vector'          *)
  128.         AH := $35;
  129.         AL := EMM_INT;
  130.         Intr(DOS_int,Regs);
  131.  
  132.         (* The ES pseudo-register contains the segment address pointed to *)
  133.         (* by Interrupt 67h.  Create an 8 character string from the 8     *)
  134.         (* successive bytes pointed to by ES:$0A (10 bytes from ES)       *)
  135.         For Position := 0 to 7 do
  136.           Int_67_Device_Name := Int_67_Device_Name + Chr(mem[ES:Position+$0A]);
  137.         Emm_Installed := True;
  138.  
  139.         (* Is it the EMM manager signature, 'EMMXXXX0'? then EMM is in-   *)
  140.         (* stalled and ready for use, if not, then the EMM manager is not *)
  141.         (* present                                                        *)
  142.         If Int_67_Device_Name <> Emm_Device_Name then
  143.           Emm_Installed := False;
  144.       End;  (* with Regs do *)
  145.   End;  (* Function Emm_Installed *)
  146.  
  147. FUNCTION EMS_Pages_Available (Var Total_EMS_Pages, Pages_Available: Word): Word;
  148. (*******************************************************************)
  149. (* This function returns the total number of EMS pages present in  *)
  150. (* the system, and the number of EMS pages that are available for  *)
  151. (* our use                                                         *)
  152. (*******************************************************************)
  153.   Var
  154.     Regs : Registers;
  155.   Begin
  156.     with Regs do
  157.       Begin
  158.  
  159.         (* Put the desired EMS function number in the AH pseudo-register. *)
  160.         AH := Get_Unallocated_Page_Count;
  161.         intr(EMM_INT,Regs);
  162.  
  163.         (* The number of EMS pages available is returned in BX            *)
  164.         Pages_Available := BX;
  165.  
  166.         (* The total number of pages present in the system is returned in *)
  167.         (* DX                                                             *)
  168.         Total_EMS_Pages := DX;
  169.  
  170.         (* Return the error code                                          *)
  171.         EMS_Pages_Available := AH
  172.       End;
  173.   End;  (* EMS_Pages_Available *)
  174.  
  175. FUNCTION Allocate_Expanded_Memory_Pages (Pages_Needed : Word; Var Handle :
  176.     Word): Word;
  177. (*******************************************************************)
  178. (* This function requests the desired number of pages from the EMM *)
  179. (*******************************************************************)
  180.   Var
  181.     Regs : Registers;
  182.   Begin
  183.     with Regs do
  184.       Begin
  185.  
  186.         (* Put the desired EMS function number in the AH pseudo-register  *)
  187.         AH:= Allocate_Pages;
  188.  
  189.         (* Put the desired number of pages in BX                          *)
  190.         BX := Pages_Needed;
  191.         intr(EMM_INT,Regs);
  192.  
  193.         (* Our EMS handle is returned in DX                               *)
  194.         Handle := DX;
  195.  
  196.         (* Return the error code                                          *)
  197.         Allocate_Expanded_Memory_Pages := AH;
  198.       End;
  199.     End;  (* Function Allocate_Expanded_Memory_Pages *)
  200.  
  201. FUNCTION Map_Expanded_Memory_Pages (Handle, Logical_Page, Physical_Page: Word):
  202.     Word;
  203. (*******************************************************************)
  204. (* This function maps a logical page onto one of the physical      *)
  205. (* pages made available to us by the Allocate_Expanded_Memory_Pag- *)
  206. (* es function                                                     *)
  207. (*******************************************************************)
  208.   Var
  209.     Regs : Registers;
  210.   Begin
  211.     with Regs do
  212.       Begin
  213.  
  214.         (* Put the desired EMS function number in the AH pseudo-register  *)
  215.         AH := Map_Pages;
  216.  
  217.         (* Put the physical page number to be mapped into AL              *)
  218.         AL := Physical_Page;
  219.  
  220.         (* Put the logical page number to be mapped in BX                 *)
  221.         BX := Logical_Page;
  222.  
  223.         (* Put the EMS handle assigned to us earlier in DX                *)
  224.         DX := Handle;
  225.         Intr(EMM_INT,Regs);
  226.  
  227.         (* Return the error code                                          *)
  228.         Map_Expanded_Memory_Pages := AH;
  229.       End;  (* with Regs do *)
  230.   End;  (* Function Map_Expanded_Memory_Pages *)
  231.  
  232. FUNCTION Get_Page_Frame_Base_Address (Var Page_Frame_Address : Word): Word;
  233. (*******************************************************************)
  234. (* This function gets the physical address of the EMS page frame   *)
  235. (* we are using. The address returned is the segment of the page   *)
  236. (* frame.                                                          *)
  237. (*******************************************************************)
  238.   Var
  239.     Regs : Registers;
  240.   Begin
  241.     with Regs do
  242.       Begin
  243.  
  244.         (* Put the desired EMS function number in the AH pseudo-register  *)
  245.         AH := Get_Page_Frame;
  246.         intr(EMM_INT,Regs);
  247.  
  248.         (* The page frame base address is returned in BX                  *)
  249.         Page_Frame_Address := BX;
  250.  
  251.         (* Return the error code                                          *)
  252.         Get_Page_Frame_Base_Address := AH;
  253.        End;  (* Regs *)
  254.   End;  (* Function Get_Page_Frame_Base_Address *)
  255.  
  256. FUNCTION Deallocate_Expanded_Memory_Pages (Handle : Word): Word;
  257. (*******************************************************************)
  258. (* This function releases the EMS memory pages allocated to us,    *)
  259. (* back to the EMS memory pool.                                    *)
  260. (*******************************************************************)
  261.   Var
  262.     Regs : Registers;
  263.   Begin
  264.     with Regs do
  265.       Begin
  266.  
  267.         (* Put the desired EMS function number in the AH pseudo-register  *)
  268.         AH := Deallocate_Pages;
  269.  
  270.         (* Put the EMS handle assigned to our EMS memory pages in DX      *)
  271.         DX := Emm_Handle;
  272.         Intr(EMM_INT,Regs);
  273.  
  274.         (* Return the error code                                          *)
  275.         Deallocate_Expanded_Memory_Pages := AH;
  276.       End;  (* with Regs do *)
  277.   End;  (* Function Deallocate_Expanded_Memory_Pages *)
  278.  
  279. FUNCTION Get_Version_Number (Var Version_String : ST3): Word;
  280. (*******************************************************************)
  281. (* This function returns the version number of the EMM as a 3      *)
  282. (* character string.                                               *)
  283. (*******************************************************************)
  284.   Var
  285.     Regs : Registers;
  286.     Word_Part, Fractional_Part: Char;
  287.   Begin
  288.     with Regs do
  289.       Begin
  290.  
  291.         (* Put the desired EMS function number in the AH pseudo-register  *)
  292.         AH := Get_Version;
  293.         Intr(EMM_INT,Regs);
  294.  
  295.         (* See if call was successful                                     *)
  296.         If AH = Status_OK then
  297.           Begin
  298.  
  299.             (* The upper four bits of AH are the Word portion of the ver- *)
  300.             (* sion number, the lower four bits are the fractional por-   *)
  301.             (* tion. Convert the Word value to ASCII by adding 48.        *)
  302.             Word_Part       := Char(AL shr 4 +  48);
  303.             Fractional_Part := Char(AL and $F + 48);
  304.             Version_String  := Word_Part + '.' + Fractional_Part;
  305.           End;  (* If AH=Status_OK *)
  306.  
  307.         (* Return the function calls error code                           *)
  308.         Get_Version_Number := AH;
  309.       End;  (* with Regs do *)
  310.   End;  (* Function Get_Version_Number *)
  311.  
  312. PROCEDURE Error (Error_Message : ST80; Error_Number: Word);
  313. (*******************************************************************)
  314. (* This procedure prints an error message passed by the caller,    *)
  315. (* prints the error code passed by the caller in hex, and then     *)
  316. (* terminates the program with the an error level of 1             *)
  317. (*******************************************************************)
  318.   Begin
  319.     Writeln(Error_Message);
  320.     Writeln('  Error_Number = ',Hex_String(Error_Number) );
  321.     Writeln('EMS test program aborting.');
  322.     Halt(1);
  323.   End;  (* Procedure Error_Message *)
  324.  
  325. BEGIN
  326.  
  327. (*******************************************************************)
  328. (* EMS_TEST                                                        *)
  329. (*                                                                 *)
  330. (* This program is an example of the basic EMS functions that you  *)
  331. (* need to execute in order to use EMS memory with Turbo Pascal    *)
  332. (*******************************************************************)
  333.  
  334.   ClrScr;
  335.   Window(5,2,77,22);
  336.  
  337.   (* Determine if the Expanded Memory Manager is installed.  If    *)
  338.   (* not, then terminate 'main' with an ErrorLevel code of 1.      *)
  339.   If not (Emm_Installed) then
  340.     Begin
  341.       Writeln('The LIM Expanded Memory Manager is not installed.');
  342.       Halt(1);
  343.     End;
  344.  
  345.   (* Get the version number and display it                         *)
  346.   Error_Code:= Get_Version_Number(Version_Number);
  347.   If Error_Code<>Status_OK then
  348.     Error('Error trying to get the EMS version number ', Error_code)
  349.   Else
  350.     Writeln('LIM Expanded Memory Manager, version ', Version_Number,
  351.         ' is ready for use.');
  352.   Writeln;
  353.  
  354.   (* Determine if there are enough expanded memory pages for this   *)
  355.   (* application.                                                   *)
  356.   Pages_Needed := APPLICATION_PAGE_COUNT;
  357.   Error_Code := EMS_Pages_Available(Total_EMS_Pages,Available_EMS_Pages);
  358.   If Error_Code<>Status_OK then
  359.     Error('Error trying to determine the number of EMS pages available.',
  360.         Error_code);
  361.   Writeln('There are a total of ',Total_EMS_Pages, ' expanded memory pages ',
  362.       'present in this system.');
  363.   Writeln('  ',Available_EMS_Pages, ' of those pages are available for your ',
  364.       'usage.');
  365.   Writeln;
  366.  
  367.   (* If there is an insufficient number of pages for our applica-   *)
  368.   (* tion, then report the error and terminate the EMS test program *)
  369.   If Pages_Needed > Available_EMS_Pages then
  370.     Begin
  371.       Str(Pages_Needed,Pages_Number_String);
  372.       Error('We need ' + Pages_Number_String + ' EMS pages. There are not ' +
  373.           'that many available.', Error_Code);
  374.     End;  (* Pages_Needed>Available_EMS_Pages *)
  375.  
  376.   (* Allocate expanded memory pages for our usage                   *)
  377.   Error_Code:= Allocate_Expanded_Memory_Pages(Pages_Needed,Emm_Handle);
  378.   Str(Pages_Needed,Pages_Number_String);
  379.   If Error_Code<>Status_OK then
  380.     Error('EMS test program failed trying to allocate ' + Pages_Number_String +
  381.         ' pages for usage.',Error_Code);
  382.   Writeln(APPLICATION_PAGE_COUNT, ' EMS page(s) allocated for the EMS test ' +
  383.       'program.');
  384.   Writeln;
  385.  
  386.   (* Map in the required logical pages to the physical pages given  *)
  387.   (* to us, in this case just one page                              *)
  388.   Logical_Page  := 0;
  389.   Physical_Page := 0;
  390.   Error_Code := Map_Expanded_Memory_Pages(Emm_Handle,Logical_Page,
  391.       Physical_Page);
  392.   If Error_Code<>Status_OK then
  393.     Error('EMS test program failed trying to map ' + 'logical pages onto ' +
  394.         'physical pages.',Error_Code);
  395.   Writeln('Logical Page ',Logical_Page,' successfully mapped onto Physical ',
  396.       'Page ',Physical_Page);
  397.   Writeln;
  398.  
  399.   (* Get the expanded memory page frame address                     *)
  400.   Error_Code:= Get_Page_Frame_Base_Address(Page_Frame_Base_Address);
  401.   If Error_Code<>Status_OK then
  402.     Error('EMS test program unable to get the base Page' + ' Frame Address.',
  403.         Error_Code);
  404.   Writeln('The base address of the EMS page frame is - ' +
  405.       Hex_String(Page_Frame_Base_Address));
  406.   Writeln;
  407.  
  408.   (* Write a test pattern to expanded memory                        *)
  409.   For Offset:=0 to 16382 do
  410.     Mem[Page_Frame_Base_Address:Offset] := Offset mod 256;
  411.  
  412.   (* Make sure that what is in EMS memory is what we just wrote     *)
  413.   Writeln('Testing EMS memory.');
  414.   Offset :=    1;
  415.   Verify := True;
  416.   While (Offset <= 16382) and (Verify = True) do
  417.     Begin
  418.       If Mem[Page_Frame_Base_Address:Offset] <> Offset mod 256 then
  419.         Verify:=False;
  420.       Offset := Succ(Offset);
  421.     End;  (* while (Offset<=16382) and (Verify=True) *)
  422.  
  423.   (* If it isn't report the error                                   *)
  424.   If not Verify then
  425.     Error('What was written to EMS memory was not found during ' + 'memory ' +
  426.         'verification  test.',0);
  427.   Writeln('EMS memory test successful.');
  428.   Writeln;
  429.  
  430.   (* Return the expanded memory pages given to us back to the EMS   *)
  431.   (* memory pool before terminating our test program                *)
  432.   Error_Code := Deallocate_Expanded_Memory_Pages(Emm_Handle);
  433.   If Error_Code <> Status_OK then
  434.     Error('EMS test program was unable to deallocate ' + 'the EMS pages in '
  435.         + 'use.',Error_Code);
  436.   Writeln(APPLICATION_PAGE_COUNT, ' page(s) deallocated.');
  437.   Writeln;
  438.   Writeln('EMS test program completed.');
  439.  
  440. END.