home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / EMS40UPD.ZIP / EMS40UPD.TXT next >
Encoding:
Text File  |  1987-11-15  |  50.4 KB  |  1,301 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.           Example 2
  7.  
  8.           This program shows you how to use the basic functions of the LIM
  9.           Expanded Memory Specification with Turbo Pascal.  The program
  10.           does the following:
  11.  
  12.                1.  Makes sure the LIM Expanded Memory Manager (EMM) has
  13.                    been installed.
  14.  
  15.                2.  Displays the version number of the EMM.
  16.  
  17.                3.  Determines if there are enough pages of memory for the
  18.                    program.  It then displays the total number of EMM pages
  19.                    present in the system and the number available for use.
  20.  
  21.                4.  Requests the desired number of pages from the EMM.
  22.  
  23.                5.  Maps a logical page into one of the physical pages.
  24.  
  25.                6.  Displays the base address of our EMM memory page frame. 
  26.                    Performs a simple read/write test on the EMM memory.
  27.  
  28.                7.  Returns the EMM memory given to us back to the EMM.
  29.  
  30.                8.  Exits.
  31.  
  32.           All the calls are structured to return the result or error code
  33.           of the Expanded Memory function performed as an integer.  If the
  34.           error code is not zero, an error has occurred, a simple error
  35.           procedure is called, and the program terminates.
  36.  
  37.           Type
  38.             ST3  = string[3];
  39.             ST80 = string[80];
  40.             ST5  = string[5];
  41.  
  42.             Registers = record
  43.               case integer of
  44.                 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS: Integer);
  45.                 2: (AL,AH,BL,BH,CL,CH,DL,DH         : Byte);
  46.               end;
  47.  
  48.           Const
  49.             EMM_INT                    = $67;
  50.             DOS_Int                    = $21;
  51.             GET_PAGE_FRAME             = $41;
  52.             GET_UNALLOCATED_PAGE_COUNT = $42;
  53.             ALLOCATE_PAGES             = $43;
  54.             MAP_PAGES                  = $44;
  55.             DEALLOCATE_PAGES           = $45;
  56.             GET_VERSION                = $46;
  57.             STATUS_OK                  = 0;
  58.  
  59.           Writing Programs That Use Expanded Memory                      19
  60.  
  61.  
  62.  
  63.  
  64.  
  65.             {------------------------------------------------------------}
  66.             { Assume the application needs one EMM page.                 }
  67.             {------------------------------------------------------------}
  68.             APPLICATION_PAGE_COUNT = 1;
  69.  
  70.           Var
  71.             Regs: Registers;
  72.  
  73.             Emm_handle,
  74.             Page_Frame_Base_Address,
  75.             Pages_Needed,
  76.             Physical_Page,
  77.             Logical_Page,
  78.             Offset,
  79.             Error_Code,
  80.             Pages_EMM_Available,
  81.             Total_EMM_Pages,
  82.             Available_EMM_Pages: Integer;
  83.  
  84.             Version_Number,
  85.             Pages_Number_String: ST3;
  86.  
  87.             Verify: Boolean;
  88.  
  89.             {------------------------------------------------------------}
  90.             { The function Hex_String converts an integer into a four    }
  91.             { character hexadecimal number (string) with leading zeros.  }
  92.             {------------------------------------------------------------}
  93.             Function Hex_String (Number: Integer): ST5;
  94.               Function Hex_Char (Number: Integer): Char;
  95.                 Begin
  96.                   If Number < 10 then
  97.                     Hex_Char := Char (Number + 48)
  98.                   else
  99.                     Hex_Char := Char (Number + 55);
  100.                 end; { Function Hex_char }
  101.  
  102.             Var
  103.               S: ST5;
  104.  
  105.             Begin
  106.               S := '';
  107.               S := Hex_Char ((Number shr 1) div 2048);
  108.               Number := (((Number shr 1) mod 2048) shl 1) + (Number and 1);
  109.               S := S + Hex_Char (Number div 256);
  110.               Number := Number mod 256;
  111.               S := S + Hex_Char (Number div 16);
  112.               Number := Number mod 16;
  113.               S := S + Hex_Char (Number);
  114.               Hex_String := S + 'h';
  115.             end; { Function Hex_String }
  116.  
  117.  
  118.           Writing Programs That Use Expanded Memory                      20
  119.  
  120.  
  121.  
  122.  
  123.  
  124.             {------------------------------------------------------------}
  125.             { The function Emm_Installed checks to see if the            }
  126.             { EMM is loaded in memory.  It does this by looking          }
  127.             { for the string 'EMMXXXX0', which should be located         }
  128.             { at 10 bytes from the beginning of the code segment the     }
  129.             { EMM interrupt, 67h, points to.                             }
  130.             {------------------------------------------------------------}
  131.             Function Emm_Installed: Boolean;
  132.               Var
  133.                 Emm_Device_Name   : string[8];
  134.                 Int_67_Device_Name: string[8];
  135.                 Position          : integer;
  136.                 Regs              : registers;
  137.  
  138.               Begin
  139.                 Int_67_Device_Name := '';
  140.                 Emm_Device_Name    := 'EMMXXXX0';
  141.                 with Regs do
  142.                   Begin
  143.                     {----------------------------------------------------}
  144.                     { Get the code segment interrupt 67h points to       }
  145.                     { the EMM interrupt by using DOS function 35h.       }
  146.                     { (get interrupt vector)                             }
  147.                     {----------------------------------------------------}
  148.                     AH := $35;
  149.                     AL := EMM_INT;
  150.                     Intr (DOS_Int, Regs);
  151.                     {----------------------------------------------------}
  152.                     { The ES pseudo-register contains the segment        }
  153.                     { address pointed to by interrupt 67h.  Create an    }
  154.                     { eight character string from the eight successive   }
  155.                     { bytes at address ES:$000A (10 bytes from ES)       }
  156.                     {----------------------------------------------------}
  157.                     For Position := 0 to 7 do
  158.                       Int_67_Device_Name :=
  159.                         Int_67_Device_Name + Chr (mem[ES:Position + $0A]);
  160.                     Emm_Installed := True;
  161.                     {----------------------------------------------------}
  162.                     { If the string is the EMM manager signature,        }
  163.                     { 'EMMXXXX0', then EMM is installed and ready for    }
  164.                     { use.  If not, then EMM is not present.             }
  165.                     {----------------------------------------------------}
  166.                     If Int_67_Device_Name <> Emm_Device_Name
  167.                       then Emm_Installed := False;
  168.                   end; { with Regs do }
  169.               end; { Function Emm_Installed }
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.           Writing Programs That Use Expanded Memory                      21
  178.  
  179.  
  180.  
  181.  
  182.  
  183.             {------------------------------------------------------------}
  184.             { This function returns the total number of EMM pages        }
  185.             { present in the system, and the number of EMM pages that    }
  186.             { are available.                                             }
  187.             {------------------------------------------------------------}
  188.             Function EMM_Pages_Available
  189.               (Var Total_EMM_Pages, Pages_Available: Integer): Integer;
  190.               Var
  191.                 Regs: Registers;
  192.  
  193.               Begin
  194.                 with Regs do
  195.                   Begin
  196.                     {----------------------------------------------------}
  197.                     { Get the number of currently unallocated pages and  }
  198.                     { the total number of pages in the system from EMM.  }
  199.                     { Load pseudo-registers prior to invoking EMM.       }
  200.                     {    AH = get unallocated page count function        }
  201.                     {----------------------------------------------------}
  202.                     AH := GET_UNALLOCATED_PAGE_COUNT;
  203.                     Intr (EMM_INT, Regs);
  204.                     {----------------------------------------------------}
  205.                     { Unload the pseudo-registers after invoking EMM.    }
  206.                     {    BX = currently unallocated pages                }
  207.                     {    DX = total pages in the system                  }
  208.                     {    AH = status                                     }
  209.                     {----------------------------------------------------}
  210.                     Pages_Available := BX;
  211.                     Total_EMM_Pages := DX;
  212.                     EMM_Pages_Available := AH;
  213.                   end;
  214.               end; { Function EMM_Pages_Available }
  215.  
  216.  
  217.             {------------------------------------------------------------}
  218.             { This function requests the specified number of pages       }
  219.             { from the EMM.                                              }
  220.             {------------------------------------------------------------}
  221.             Function Allocate_Expanded_Memory_Pages
  222.               (Pages_Needed: Integer; Var Handle: Integer): Integer;
  223.               Var
  224.                 Regs: Registers;
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.           Writing Programs That Use Expanded Memory                      22
  237.  
  238.  
  239.  
  240.  
  241.  
  242.               Begin
  243.                 with Regs do
  244.                   Begin
  245.                     {----------------------------------------------------}
  246.                     { Allocate the specified number of pages from EMM.   }
  247.                     { Load pseudo-registers prior to invoking EMM.       }
  248.                     {    AH = allocate pages function.                   }
  249.                     {    BX = number of pages to allocate.               }
  250.                     {----------------------------------------------------}
  251.                     AH := ALLOCATE_PAGES;
  252.                     BX := Pages_Needed;
  253.                     Intr (EMM_INT, Regs);
  254.                     {----------------------------------------------------}
  255.                     { Unload the pseudo-registers after invoking EMM.    }
  256.                     {    DX = EMM handle                                 }
  257.                     {    AH = status                                     }
  258.                     {----------------------------------------------------}
  259.                     Handle := DX;
  260.                     Allocate_Expanded_Memory_Pages := AH;
  261.                   end;
  262.               end; { Function Allocate_Expanded_Memory_Pages }
  263.  
  264.  
  265.             {------------------------------------------------------------}
  266.             { This function maps a logical page allocated by the         }
  267.             { Allocate_Expanded_Memory_Pages function into one of the    }
  268.             { four physical pages.                                       }
  269.             {------------------------------------------------------------}
  270.             Function Map_Expanded_Memory_Pages
  271.               (Handle, Logical_Page, Physical_Page: Integer): Integer;
  272.               Var
  273.                 Regs: Registers;
  274.  
  275.               Begin
  276.                 with Regs do
  277.                   Begin
  278.                     {----------------------------------------------------}
  279.                     { Map a logical page at a physical page.             }
  280.                     { Load pseudo-registers prior to invoking EMM.       }
  281.                     {    AH = map page function                          }
  282.                     {    DX = handle                                     }
  283.                     {    BX = logical page number                        }
  284.                     {    AL = physical page number                       }
  285.                     {----------------------------------------------------}
  286.                     AH := MAP_PAGES;
  287.                     DX := Handle;
  288.                     BX := Logical_Page;
  289.                     AL := Physical_Page;
  290.                     Intr (EMM_INT, Regs);
  291.  
  292.  
  293.  
  294.  
  295.           Writing Programs That Use Expanded Memory                      23
  296.  
  297.  
  298.  
  299.  
  300.  
  301.                     {----------------------------------------------------}
  302.                     { Unload the pseudo-registers after invoking EMM.    }
  303.                     {    AH = status                                     }
  304.                     {----------------------------------------------------}
  305.                     Map_Expanded_Memory_Pages := AH;
  306.                   end; { with Regs do }
  307.               end; { Function Map_Expanded_Memory_Pages }
  308.  
  309.  
  310.             {------------------------------------------------------------}
  311.             { This function gets the physical address of the EMM page    }
  312.             { frame we are using.  The address returned is the segment   }
  313.             { of the page frame.                                         }
  314.             {------------------------------------------------------------}
  315.             Function Get_Page_Frame_Base_Address
  316.               (Var Page_Frame_Address: Integer): Integer;
  317.               Var
  318.                 Regs: Registers;
  319.  
  320.               Begin
  321.                 with Regs do
  322.                   Begin
  323.                     {----------------------------------------------------}
  324.                     { Get the page frame segment address from EMM.       }
  325.                     { Load pseudo-registers prior to invoking EMM.       }
  326.                     {    AH = get page frame segment function            }
  327.                     {----------------------------------------------------}
  328.                     AH := GET_PAGE_FRAME;
  329.                     Intr (EMM_INT, Regs);
  330.                     {----------------------------------------------------}
  331.                     { Unload the pseudo-registers after invoking EMM.    }
  332.                     {    BX = page frame segment address                 }
  333.                     {    AH = status                                     }
  334.                     {----------------------------------------------------}
  335.                     Page_Frame_Address := BX;
  336.                     Get_Page_Frame_Base_Address := AH;
  337.                   end; { with Regs do }
  338.               end; { Function Get_Page_Frame_Base_Address }
  339.  
  340.  
  341.             {------------------------------------------------------------}
  342.             { This function releases the EMM memory pages allocated to   }
  343.             { us, back to the EMM memory pool.                           }
  344.             {------------------------------------------------------------}
  345.             Function Deallocate_Expanded_Memory_Pages
  346.               (Handle: Integer): Integer;
  347.               Var
  348.                 Regs: Registers;
  349.  
  350.  
  351.  
  352.  
  353.  
  354.           Writing Programs That Use Expanded Memory                      24
  355.  
  356.  
  357.  
  358.  
  359.  
  360.               Begin
  361.                 with Regs do
  362.                   Begin
  363.                     {----------------------------------------------------}
  364.                     { Deallocate the pages allocated to an EMM handle.   }
  365.                     { Load pseudo-registers prior to invoking EMM.       }
  366.                     {    AH = deallocate pages function                  }
  367.                     {    DX = EMM handle                                 }
  368.                     {----------------------------------------------------}
  369.                     AH := DEALLOCATE_PAGES;
  370.                     DX := Handle;
  371.                     Intr (EMM_INT, Regs);
  372.                     {----------------------------------------------------}
  373.                     { Unload the pseudo-registers after invoking EMM.    }
  374.                     {    AH = status                                     }
  375.                     {----------------------------------------------------}
  376.                     Deallocate_Expanded_Memory_Pages := AH;
  377.                   end; { with Regs do }
  378.               end; { Function Deallocate_Expanded_Memory_Pages }
  379.  
  380.  
  381.             {------------------------------------------------------------}
  382.             { This function returns the version number of the EMM as     }
  383.             { a three-character string.                                  }
  384.             {------------------------------------------------------------}
  385.             Function Get_Version_Number (Var Version_String: ST3): Integer;
  386.               Var
  387.                 Regs: Registers;
  388.                 Integer_Part, Fractional_Part: Char;
  389.  
  390.               Begin
  391.                 with Regs do
  392.                   Begin
  393.                     {----------------------------------------------------}
  394.                     { Get the version of EMM.                            }
  395.                     { Load pseudo-registers prior to invoking EMM.       }
  396.                     {    AH = get EMM version function                   }
  397.                     {----------------------------------------------------}
  398.                     AH := GET_VERSION;
  399.                     Intr (EMM_INT, Regs);
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.           Writing Programs That Use Expanded Memory                      25
  414.  
  415.  
  416.  
  417.  
  418.  
  419.                     {----------------------------------------------------}
  420.                     { If the version number returned was OK, then        }
  421.                     { convert it to a three-character string.            }
  422.                     {----------------------------------------------------}
  423.                     If AH=STATUS_OK then
  424.                       Begin
  425.                         {------------------------------------------------}
  426.                         { The upper four bits of AH are the integer      }
  427.                         { portion of the version number, the lower four  }
  428.                         { bits are the fractional portion.  Convert the  }
  429.                         { integer value to ASCII by adding 48.           }
  430.                         {------------------------------------------------}
  431.                         Integer_Part    := Char (AL shr 4  + 48);
  432.                         Fractional_Part := Char (AL and $F + 48);
  433.                         Version_String  := Integer_Part + '.' +
  434.                                                           Fractional_Part;
  435.                       end; { If AH=STATUS_OK }
  436.                     {----------------------------------------------------}
  437.                     { Unload the pseudo-registers after invoking EMM.    }
  438.                     {    AH = status                                     }
  439.                     {----------------------------------------------------}
  440.                     Get_Version_Number := AH;
  441.                   end; { with Regs do }
  442.               end; { Function Get_Version_Number }
  443.  
  444.  
  445.             {------------------------------------------------------------}
  446.             { This procedure prints an error message passed by the       }
  447.             { caller, prints the error code passed by the caller in hex, }
  448.             { and then terminates the program with an error level of 1.  }
  449.             {------------------------------------------------------------}
  450.             Procedure Error (Error_Message: ST80; Error_Number: Integer);
  451.               Begin
  452.                 Writeln (Error_Message);
  453.                 Writeln ('  Error_Number = ', Hex_String (Error_Number));
  454.                 Writeln ('EMM test program aborting.');
  455.                 Halt (1);
  456.               end; { Procedure Error }
  457.  
  458.  
  459.           {--------------------------------------------------------------}
  460.           { This program is an example of the basic EMM functions that   }
  461.           { you need in order to use EMM memory with Turbo Pascal.       }
  462.           {--------------------------------------------------------------}
  463.           Begin
  464.             ClrScr;
  465.             Window (5,2,77,22);
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.           Writing Programs That Use Expanded Memory                      26
  473.  
  474.  
  475.  
  476.  
  477.  
  478.             {------------------------------------------------------------}
  479.             { Determine if the Expanded Memory Manager is installed.  If }
  480.             { not, then terminate 'main' with an ErrorLevel code of 1.   }
  481.             {------------------------------------------------------------}
  482.             If not (Emm_Installed) then
  483.               Begin
  484.                 Writeln ('The LIM EMM is not installed.');
  485.                 Halt (1);
  486.               end
  487.             else
  488.               Begin
  489.                 { Get the version number and display it }
  490.                 Error_Code := Get_Version_Number (Version_Number);
  491.                 If Error_Code <> STATUS_OK then
  492.                   Error ('Error getting EMM version number.', Error_Code)
  493.                 else
  494.                   Writeln ('LIM Expanded Memory Manager, version ',
  495.                            Version_Number, ' is ready for use.');
  496.               end;
  497.             Writeln;
  498.  
  499.             {------------------------------------------------------------}
  500.             { Determine if there are enough expanded memory pages for    }
  501.             { this application.                                          }
  502.             {------------------------------------------------------------}
  503.             Pages_Needed := APPLICATION_PAGE_COUNT;
  504.             Error_Code   := EMM_Pages_Available (Total_EMM_Pages,
  505.                                                  Available_EMM_Pages);
  506.             If Error_Code <> STATUS_OK then
  507.               Error ('Error determining number of EMM pages available.',
  508.                      Error_Code);
  509.             Writeln ('There are a total of ', Total_EMM_Pages,
  510.                      ' expanded memory pages present in this system.');
  511.             Writeln ('  ', Available_EMM_Pages,
  512.                      ' of those pages are available for use.');
  513.             Writeln;
  514.  
  515.             {------------------------------------------------------------}
  516.             { If there is an insufficient number of pages for the        }
  517.             { application, then report the error and terminate the EMM   }
  518.             { example program.                                           }
  519.             {------------------------------------------------------------}
  520.             If Pages_Needed > Available_EMM_Pages then
  521.               Begin
  522.                 Str (Pages_Needed, Pages_Number_String);
  523.                 Error ('We need ' + Pages_Number_String +
  524.                        ' EMM pages.  There are not that many available.',
  525.                        Error_Code);
  526.               end; { Pages_Needed > Available_EMM_Pages }
  527.  
  528.  
  529.  
  530.  
  531.           Writing Programs That Use Expanded Memory                      27
  532.  
  533.  
  534.  
  535.  
  536.  
  537.             {------------------------------------------------------------}
  538.             { Allocate expanded memory pages for our use.                }
  539.             {------------------------------------------------------------}
  540.             Error_Code :=
  541.               Allocate_Expanded_Memory_Pages (Pages_Needed, Emm_Handle);
  542.             Str (Pages_Needed, Pages_Number_String);
  543.             If Error_Code <> STATUS_OK then
  544.               Error ('EMM test program failed trying to allocate '
  545.                      + Pages_Number_String
  546.                      + ' pages for usage.', Error_Code);
  547.             Writeln (APPLICATION_PAGE_COUNT,
  548.                      ' EMM page(s) allocated for the EMM test program.');
  549.             Writeln;
  550.  
  551.             {------------------------------------------------------------}
  552.             { Map in the required logical pages to the physical pages    }
  553.             { given to us, in this case just one page.                   }
  554.             {------------------------------------------------------------}
  555.             Logical_Page  := 0;
  556.             Physical_Page := 0;
  557.             Error_Code := Map_Expanded_Memory_Pages (Emm_Handle,
  558.                                                      Logical_Page,
  559.                                                      Physical_Page);
  560.             If Error_Code <> STATUS_OK then
  561.               Error ('EMM test program failed trying to map '
  562.                      + 'logical pages into physical pages.',
  563.                      Error_Code);
  564.  
  565.             Writeln ('Logical Page ',
  566.                      Logical_Page,
  567.                      ' successfully mapped into Physical Page ',
  568.                      Physical_Page);
  569.             Writeln;
  570.  
  571.             {------------------------------------------------------------}
  572.             { Get the expanded memory page frame address.                }
  573.             {------------------------------------------------------------}
  574.             Error_Code := Get_Page_Frame_Base_Address
  575.                             (Page_Frame_Base_Address);
  576.             If Error_Code <> STATUS_OK then
  577.               Error ('EMM test program unable to get the base Page'
  578.                      + ' Frame Address.',
  579.                      Error_Code);
  580.             Writeln ('The base address of the EMM page frame is = '
  581.                      + Hex_String (Page_Frame_Base_Address));
  582.             Writeln;
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.           Writing Programs That Use Expanded Memory                      28
  591.  
  592.  
  593.  
  594.  
  595.  
  596.             {------------------------------------------------------------}
  597.             { Write a test pattern to expanded memory.                   }
  598.             {------------------------------------------------------------}
  599.             For Offset := 0 to 16382 do
  600.               Begin
  601.                 Mem[Page_Frame_Base_Address:Offset] := Offset mod 256;
  602.               end;
  603.  
  604.             {------------------------------------------------------------}
  605.             { Make sure that what is in EMM memory is what was just      }
  606.             { written.                                                   }
  607.             {------------------------------------------------------------}
  608.             Writeln ('Testing EMM memory.');
  609.  
  610.             Offset := 1;
  611.             Verify := True;
  612.             while (Offset <= 16382) and (Verify = True) do
  613.               Begin
  614.                 If Mem[Page_Frame_Base_Address:Offset] <> Offset mod 256
  615.                   then Verify := False;
  616.                 Offset := Succ (Offset);
  617.               end; { while (Offset <= 16382) and (Verify = True) }
  618.  
  619.             {------------------------------------------------------------}
  620.             { If what is read does not match what was written,           }
  621.             { an error occurred.                                         }
  622.             {------------------------------------------------------------}
  623.             If not Verify then
  624.               Error ('What was written to EMM memory was not found during'
  625.                      + ' memory verification test.',
  626.                      0);
  627.             Writeln ('EMM memory test successful.');
  628.             Writeln;
  629.  
  630.             {------------------------------------------------------------}
  631.             { Return the expanded memory pages given to us back to the   }
  632.             { EMM memory pool before terminating our test program.       }
  633.             {------------------------------------------------------------}
  634.             Error_Code := Deallocate_Expanded_Memory_Pages (Emm_Handle);
  635.             If Error_Code <> STATUS_OK then
  636.               Error ('EMM test program was unable to deallocate '
  637.                      + 'the EMM pages in use.',
  638.                      Error_Code);
  639.             Writeln (APPLICATION_PAGE_COUNT,
  640.                      ' pages(s) deallocated.');
  641.             Writeln;
  642.             Writeln ('EMM test program completed.');
  643.  
  644.           end.
  645.  
  646.  
  647.  
  648.  
  649.           Writing Programs That Use Expanded Memory                      29
  650.  
  651.  
  652.  
  653.  
  654.  
  655.           Function 4. Allocate Pages
  656.  
  657.  
  658.  
  659.                The Allocate Pages function allocates the number of pages
  660.                requested and assigns a unique EMM handle to these pages. 
  661.                The EMM handle owns these pages until the application
  662.                deallocates them.
  663.  
  664.                Handles which are assigned using this function will have
  665.                16K-byte pages, the size of a standard expanded memory page. 
  666.                If the expanded memory board hardware isn't able to supply
  667.                16K-byte pages, it will emulate them by combining multiple
  668.                non-standard size pages to form a single 16K-byte page.  All
  669.                application programs and functions that use the handles this
  670.                function returns will deal with 16K-byte pages.
  671.  
  672.                The numeric value of the handles the EMM returns are in the
  673.                range of 1 to 254 decimal (0001h to 00FEh).  The OS handle
  674.                (handle value 0) is never returned by the Allocate Pages
  675.                function.  Also, the uppermost byte of the handle will be
  676.                zero and cannot be used by the application.  A memory
  677.                manager should be able to supply up to 255 handles, includ-
  678.                ing the OS handle.  An application can use Function 21 to
  679.                find out how many handles an EMM supports.
  680.  
  681.                Allocating zero pages to a handle is not valid.  If an
  682.                application needs to allocate 0 pages to a handle it should
  683.                use Function 27 (Allocate Standard Pages subfunction)
  684.                provided for this purpose.
  685.  
  686.           Note............................................................
  687.                This note affects expanded memory manager implementors and
  688.                operating system developers only.  Applications should not
  689.                use the following characteristics of the memory manager.  An
  690.                application violating this rule will be incompatible with
  691.                future versions of Microsoft's operating systems and
  692.                environments.
  693.  
  694.                To be compatible with this specification, an expanded memory
  695.                manager will provide a special handle which is available to
  696.                the operating system only.  This handle will have a value of
  697.                0000h and will have a set of pages allocated to it when the
  698.                expanded memory manager driver installs.  The pages that the
  699.                memory manager will automatically allocate to handle 0000h
  700.                are those that backfill conventional memory.  Typically,
  701.                this backfill occurs between addresses 40000h (256K) and
  702.                9FFFFh (640K).  However, the range can extend below and
  703.                above this limit if the hardware and memory manager have the
  704.                capability.
  705.  
  706.  
  707.  
  708.           EMM Functions                                                  42
  709.  
  710.  
  711.  
  712.  
  713.  
  714.           Function 4. Allocate Pages
  715.  
  716.  
  717.  
  718.                An operating system won't have to invoke Function 4 to
  719.                obtain this handle because it can assume the handle already
  720.                exists and is available for use immediately after the
  721.                expanded memory device driver installs.  When an operating
  722.                system wants to use this handle, it uses the special handle
  723.                value of 0000h.  The operating system will be able to invoke
  724.                any EMM function using this special handle value.  To
  725.                allocate pages to this handle, the operating system need
  726.                only invoke Function 18 (Reallocate Pages).
  727.  
  728.                There are two special cases for this handle:
  729.  
  730.                1.  Function 4 (Allocate Pages).  This function must never
  731.                    return zero as a handle value.  Applications must always
  732.                    invoke Function 4 to allocate pages and obtain a handle
  733.                    which identifies the pages which belong to it.  Since
  734.                    Function 4 never returns a handle value of zero, an
  735.                    application will never gain access to this special
  736.                    handle.
  737.  
  738.                2.  Function 6 (Deallocate Pages).  If the operating system
  739.                    uses it to deallocate the pages which are allocated to
  740.                    this special handle, the pages the handle owns will be
  741.                    returned to the manager for use.  But the handle will
  742.                    not be available for reassignment.  The manager should
  743.                    treat a deallocate pages function request for this
  744.                    handle the same as a reallocate pages function request,
  745.                    where the number of pages to reallocate to this handle
  746.                    is zero.
  747.  
  748.  
  749.           CALLING PARAMETERS
  750.  
  751.                AH = 43h
  752.                    Contains the Allocate Pages function.
  753.  
  754.                BX = num_of_pages_to_alloc
  755.                    Contains the number of pages you want your program to
  756.                    allocate.
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.           EMM Functions                                                  43
  768.  
  769.  
  770.  
  771.  
  772.  
  773.           Function 4. Allocate Pages
  774.  
  775.  
  776.  
  777.           RESULTS
  778.  
  779.                These results are valid only if the status returned is zero.
  780.  
  781.                DX = handle
  782.                    Contains a unique EMM handle.  Your program must use
  783.                    this EMM handle (as a parameter) in any function that
  784.                    requires it.  You can use up to 255 handles.  The
  785.                    uppermost byte of the handle will be zero and cannot be
  786.                    used by the application.
  787.  
  788.  
  789.           REGISTERS MODIFIED
  790.  
  791.                AX, DX
  792.  
  793.  
  794.           STATUS
  795.  
  796.                AH = 0   SUCCESSFUL.
  797.                    The manager has allocated the requested pages to the
  798.                    assigned EMM handle.
  799.  
  800.                AH = 80h   NON-RECOVERABLE.
  801.                    The manager detected a malfunction in the memory manager
  802.                    software.
  803.  
  804.                AH = 81h   NON-RECOVERABLE.
  805.                    The manager detected a malfunction in the expanded
  806.                    memory hardware.
  807.  
  808.                AH = 84h   NON-RECOVERABLE.
  809.                    The function code passed to the memory manager is not
  810.                    defined.
  811.  
  812.                AH = 85h   RECOVERABLE.
  813.                    All EMM handles are being used.
  814.  
  815.                AH = 87h   RECOVERABLE.
  816.                    There aren't enough expanded memory pages present in the
  817.                    system to satisfy your program's request.
  818.  
  819.                AH = 88h   RECOVERABLE.
  820.                    There aren't enough unallocated pages to satisfy your
  821.                    program's request.
  822.  
  823.                AH = 89h   RECOVERABLE.
  824.                    Your program attempted to allocate zero pages.
  825.  
  826.           EMM Functions                                                  44
  827.  
  828.  
  829.  
  830.  
  831.  
  832.           Function 4. Allocate Pages
  833.  
  834.  
  835.  
  836.           EXAMPLE
  837.  
  838.           num_of_pages_to_alloc          DW ?
  839.           emm_handle                     DW ?
  840.  
  841.           MOV   BX,num_of_pages_to_alloc ; load number of pages
  842.           MOV   AH,43h                   ; load function code
  843.           INT   67h                      ; call the memory manager
  844.           OR    AH,AH                    ; check EMM status
  845.           JNZ   emm_err_handler          ; jump to error handler on error
  846.           MOV   emm_handle,DX            ; save EMM handle
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.           EMM Functions                                                  45
  886.  
  887.  
  888.  
  889.  
  890.  
  891.           Function 27. Allocate Standard/Raw Pages
  892.           Allocate Standard Pages subfunction
  893.  
  894.  
  895.  
  896.           PURPOSE
  897.  
  898.                The Allocate Standard Pages subfunction allocates the number
  899.                of standard size (16K bytes) pages that the operating system
  900.                requests and assigns a unique EMM handle to these pages. 
  901.                The EMM handle owns these pages until the operating system
  902.                deallocates them.  This subfunction allows you to allocate
  903.                zero pages to a handle, unlike Function 4 (Allocate Pages).
  904.  
  905.           Note............................................................
  906.                This note affects expanded memory manager implementors and
  907.                operating system developers only.  Applications should not
  908.                use the following characteristic of the memory manager.  An
  909.                application violating this rule will be incompatible with
  910.                future versions of Microsoft's operating systems and
  911.                environments.
  912.  
  913.                To be compatible with this specification, an expanded memory
  914.                manager will provide a special handle which is available to
  915.                the operating system only.  This handle will have a value of
  916.                0000h and will have a set of pages allocated to it when the
  917.                expanded memory manager driver installs.  The pages that the
  918.                memory manager will automatically allocate to handle 0000h
  919.                are those that backfill conventional memory.  Typically,
  920.                this backfill occurs between addresses 40000h (256K) and
  921.                9FFFFh (640K).  However, the range can extend below and
  922.                above this limit if the hardware and memory manager have the
  923.                capability.
  924.  
  925.                An operating system won't have to invoke Function 27 to
  926.                obtain this handle because it can assume the handle already
  927.                exists and is available for use immediately after the
  928.                expanded memory device driver installs.  When an operating
  929.                system wants to use this handle, it uses the special handle
  930.                value of 0000h.  The operating system will be able to invoke
  931.                any EMM function using this special handle value.  To
  932.                allocate pages to this handle, the operating system need
  933.                only invoke Function 18 (Reallocate Pages).
  934.  
  935.                There are two special cases for this handle:
  936.  
  937.                1.  Function 27 (Allocate Standard Pages subfunction).  This
  938.                    function must never return zero as a handle value. 
  939.                    Applications must always invoke Function 27 to allocate
  940.                    pages and obtain a handle which identifies the pages
  941.                    which belong to it.  Since Function 27 never returns a
  942.  
  943.  
  944.           EMM Functions                                                 144
  945.  
  946.  
  947.  
  948.  
  949.  
  950.           Function 27. Allocate Standard/Raw Pages
  951.           Allocate Standard Pages subfunction
  952.  
  953.  
  954.  
  955.                    handle value of zero, an application will never gain
  956.                    access to this special handle.
  957.  
  958.                2.  Function 6 (Deallocate Pages).  If the operating system
  959.                    uses it to deallocate the pages which are allocated to
  960.                    this handle, the pages the handle owns will be returned
  961.                    to the manager for use.  But the handle will not be
  962.                    available for reassignment.  The manager should treat a
  963.                    deallocate pages function request for this handle the
  964.                    same as a reallocate pages function request, where the
  965.                    number of pages to reallocate to this handle is zero.
  966.  
  967.  
  968.           CALLING PARAMETERS
  969.  
  970.                AX = 5A00h
  971.                    Contains the Allocate Standard Pages subfunction.
  972.  
  973.                BX = num_of_standard_pages_to_alloc
  974.                    Contains the number of standard pages the operating
  975.                    system wants to allocate.
  976.  
  977.  
  978.           RESULTS
  979.  
  980.                These results are valid only if the status returned is zero.
  981.  
  982.                DX = handle
  983.                    Contains a unique EMM handle.  The operating system must
  984.                    use this EMM handle as a parameter in any function that
  985.                    requires it.  Up to 255 handles may be obtained.  (Both
  986.                    Function 27 and Function 4 must share the same 255
  987.                    handles.)
  988.  
  989.                    For all functions using this handle, the length of the
  990.                    physical and logical pages allocated to it are standard
  991.                    length (that is, 16K bytes).
  992.  
  993.  
  994.           REGISTERS MODIFIED
  995.  
  996.                AX, DX
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.           EMM Functions                                                 145
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.           Function 27. Allocate Standard/Raw Pages
  1010.           Allocate Standard Pages subfunction
  1011.  
  1012.  
  1013.  
  1014.           STATUS
  1015.  
  1016.                AH = 0   SUCCESSFUL.
  1017.                    The manager has allocated the pages to an assigned EMM
  1018.                    standard handle.
  1019.  
  1020.                AH = 80h   NON-RECOVERABLE.
  1021.                    The manager detected a malfunction in the memory manager
  1022.                    software.
  1023.  
  1024.                AH = 81h   NON-RECOVERABLE.
  1025.                    The manager detected a malfunction in the expanded
  1026.                    memory hardware.
  1027.  
  1028.                AH = 84h   NON-RECOVERABLE.
  1029.                    The function code passed to the memory manager is not
  1030.                    defined.
  1031.  
  1032.                AH = 85h   RECOVERABLE.
  1033.                    All EMM handles are being used.
  1034.  
  1035.                AH = 87h   RECOVERABLE.
  1036.                    There aren't enough expanded memory pages present in the
  1037.                    system to satisfy the operating system's request.
  1038.  
  1039.                AH = 88h   RECOVERABLE.
  1040.                    There aren't enough unallocated pages to satisfy the
  1041.                    operating system's request.
  1042.  
  1043.                AH = 8Fh   NON-RECOVERABLE.
  1044.                    The subfunction parameter is invalid.
  1045.  
  1046.  
  1047.           EXAMPLE
  1048.  
  1049.           num_of_standard_pages_to_alloc      DW ?
  1050.           emm_handle                          DW ?
  1051.  
  1052.           MOV   BX,num_of_standard_pages_to_alloc
  1053.           MOV   AX,5A00h                      ; load function code
  1054.           INT   67h                           ; call the memory manager
  1055.           OR    AH,AH                         ; check EMM status
  1056.           JNZ   emm_err_handler               ; jump to error handler on
  1057.                                               ; error
  1058.           MOV   emm_handle,DX                 ; save handle
  1059.  
  1060.  
  1061.  
  1062.           EMM Functions                                                 146
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.           Function 27. Allocate Standard/Raw Pages
  1069.           Allocate Raw Pages subfunction
  1070.  
  1071.  
  1072.  
  1073.           PURPOSE
  1074.  
  1075.                The Allocate Raw Pages function allocates the number of non-
  1076.                standard size pages that the operating system requests and
  1077.                assigns a unique EMM handle to these pages.  The EMM handle
  1078.                owns these pages until the operating system deallocates
  1079.                them.  This function allows you to allocate zero pages to a
  1080.                handle, unlike Function 4 (Allocate Pages).
  1081.  
  1082.                A hardware vendor may design an expanded memory board that
  1083.                has a page size which is a sub-multiple of 16K bytes.  A
  1084.                physical page which is a sub-multiple of 16K is termed a raw
  1085.                page.  The operating system may deal with page sizes which
  1086.                are sub-multiples of 16K bytes.  The memory manager must
  1087.                treat any function using a handle with raw pages allocated
  1088.                to it by Function 27 (Allocate Raw Pages subfunction)
  1089.                differently than it does a handle that has normal 16K-byte
  1090.                pages allocated to it.
  1091.  
  1092.                Handles which are assigned using Function 4 (Allocate Pages)
  1093.                or Function 27 (Allocate Standard Pages subfunction) must
  1094.                have pages which are 16K bytes -- this is the length of a
  1095.                standard expanded memory page.  If the expanded memory board
  1096.                hardware is not able to supply 16K-byte pages, the memory
  1097.                manager must emulate pages which are 16K bytes combining
  1098.                multiple non-standard size pages to form a single 16K-byte
  1099.                page.
  1100.  
  1101.                Handles which are assigned using Function 27 (Allocate Raw
  1102.                Pages subfunction) are called raw handles.  All logical
  1103.                pages allocated to a raw handle may have a non-standard
  1104.                length (that is, not 16K bytes).  However, once the operat-
  1105.                ing system has allocated a number of raw pages to a handle,
  1106.                it is the responsibility of the memory manager to recognize
  1107.                that raw handle as one that has non-standard size pages
  1108.                allocated to it.  The memory manager must identify these
  1109.                handles and treat all functions which use handles which have
  1110.                non-standard page lengths differently.  The logical page
  1111.                length becomes the length of the non-standard size page for
  1112.                any raw handle that Function 27 assigns.
  1113.  
  1114.           Note............................................................
  1115.                This note affects expanded memory manager implementors and
  1116.                operating system developers only.  Applications should not
  1117.                use the following characteristic of the memory manager.  An
  1118.                application violating this rule will be incompatible with
  1119.  
  1120.  
  1121.           EMM Functions                                                 147
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.           Function 27. Allocate Standard/Raw Pages
  1128.           Allocate Raw Pages subfunction
  1129.  
  1130.  
  1131.  
  1132.                future versions of Microsoft's operating systems and
  1133.                environments.
  1134.  
  1135.                To be compatible with this specification, an expanded memory
  1136.                manager will provide a special handle which is available to
  1137.                the operating system only.  This handle will have a value of
  1138.                0000h and will have a set of pages allocated to it when the
  1139.                expanded memory manager driver installs.  The pages that the
  1140.                memory manager will automatically allocate to handle 0000h
  1141.                are those that backfill conventional memory.  Typically,
  1142.                this backfill occurs between addresses 40000h (256K) and
  1143.                9FFFFh (640K).  However, the range can extend below and
  1144.                above this limit if the hardware and memory manager have the
  1145.                capability.
  1146.  
  1147.                An operating system won't have to invoke Function 27 to
  1148.                obtain this handle because it can assume the handle already
  1149.                exists and is available for use immediately after the
  1150.                expanded memory device driver installs.  When an operating
  1151.                system wants to use this handle, it uses the special handle
  1152.                value of 0000h.  The operating system will be able to invoke
  1153.                any EMM function using this special handle value.  To
  1154.                allocate pages to this handle, the operating system need
  1155.                only invoke Function 18 (Reallocate Pages).
  1156.  
  1157.                There are two special cases for this handle:
  1158.  
  1159.                1.  Function 27 (Allocate Raw Pages subfunction).  This
  1160.                    function must never return zero as a handle value. 
  1161.                    Applications must always invoke Function 27 to allocate
  1162.                    pages and obtain a handle which identifies the pages
  1163.                    which belong to it.  Since Function 27 never returns a
  1164.                    handle value of zero, an application will never gain
  1165.                    access to this special handle.
  1166.  
  1167.                2.  Function 6 (Deallocate Pages).  If the operating system
  1168.                    uses it to deallocate the pages which are allocated to
  1169.                    this handle, the pages the handle owns will be returned
  1170.                    to the manager for use.  But the handle will not be
  1171.                    available for reassignment.  The manager should treat a
  1172.                    deallocate pages function request for this handle the
  1173.                    same as a reallocate pages function request, where the
  1174.                    number of pages to reallocate to this handle is zero.
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.           EMM Functions                                                 148
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.           Function 27. Allocate Standard/Raw Pages
  1187.           Allocate Raw Pages subfunction
  1188.  
  1189.  
  1190.  
  1191.           CALLING PARAMETERS
  1192.  
  1193.                AX = 5A01h
  1194.                    Contains the Allocate Raw Pages subfunction.
  1195.  
  1196.                BX = num_of_raw_pages_to_alloc
  1197.                    Contains the number of raw pages the operating system
  1198.                    wishes to allocate.
  1199.  
  1200.  
  1201.           RESULTS
  1202.  
  1203.                These results are valid only if the status returned is zero.
  1204.  
  1205.                DX = raw handle
  1206.                    Contains a unique EMM raw handle.  The operating system
  1207.                    must use this EMM raw handle as a parameter in any
  1208.                    function that requires it.  Up to 255 handles may be
  1209.                    obtained.  (Both Function 4 and Function 27 must share
  1210.                    the same 255 handles).
  1211.  
  1212.                    For all functions using this raw handle, the length of
  1213.                    the physical and logical pages allocated to it may be
  1214.                    non-standard (that is, not 16K bytes).
  1215.  
  1216.  
  1217.           REGISTERS MODIFIED
  1218.  
  1219.                AX, DX
  1220.  
  1221.  
  1222.           STATUS
  1223.  
  1224.                AH = 0   SUCCESSFUL.
  1225.                    The manager has allocated the raw pages to an assigned
  1226.                    EMM raw handle.
  1227.  
  1228.                AH = 80h   NON-RECOVERABLE.
  1229.                    The manager detected a malfunction in the memory manager
  1230.                    software.
  1231.  
  1232.                AH = 81h   NON-RECOVERABLE.
  1233.                    The manager detected a malfunction in the expanded
  1234.                    memory hardware.
  1235.  
  1236.  
  1237.  
  1238.  
  1239.           EMM Functions                                                 149
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.           Function 27. Allocate Standard/Raw Pages
  1246.           Allocate Raw Pages subfunction
  1247.  
  1248.  
  1249.  
  1250.                AH = 84h   NON-RECOVERABLE.
  1251.                    The function code passed to the memory manager is not
  1252.                    defined.
  1253.  
  1254.                AH = 85h   RECOVERABLE.
  1255.                    All EMM handles are being used.
  1256.  
  1257.                AH = 87h   RECOVERABLE.
  1258.                    There aren't enough expanded memory raw pages present in
  1259.                    the system to satisfy the operating system's request.
  1260.  
  1261.                AH = 88h   RECOVERABLE.
  1262.                    There aren't enough unallocated raw pages to satisfy the
  1263.                    operating system's request.
  1264.  
  1265.                AH = 8Fh   NON-RECOVERABLE.
  1266.                    The subfunction parameter is invalid.
  1267.  
  1268.  
  1269.           EXAMPLE
  1270.  
  1271.           num_of_raw_pages_to_alloc           DW ?
  1272.           emm_raw_handle                      DW ?
  1273.  
  1274.           MOV   BX,num_of_raw_pages_to_alloc
  1275.           MOV   AX,5A01h                      ; load function code
  1276.           INT   67h                           ; call the memory manager
  1277.           OR    AH,AH                         ; check EMM status
  1278.           JNZ   emm_err_handler               ; jump to error handler
  1279.                                               ; on error
  1280.           MOV   emm_raw_handle,DX             ; save raw handle
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.           EMM Functions                                                 150
  1299.  
  1300.  
  1301.