home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PCGPEV10.ZIP / XMS30.TXT < prev    next >
Text File  |  1994-05-10  |  46KB  |  1,080 lines

  1. eXtended Memory Specification (XMS), ver 3.0
  2.  
  3.  
  4. January 1991
  5.  
  6.  
  7. Copyright (c) 1988, Microsoft Corporation, Lotus Development
  8. Corporation, Intel Corporation, and AST Research, Inc.
  9.  
  10. Microsoft Corporation                                            
  11. Box 97017
  12.  
  13. One Microsoft Way                                       
  14. Redmond, WA 98073
  15.  
  16. LOTUS (r)
  17. INTEL (r)
  18. MICROSOFT (r)
  19. AST (r) Research
  20.  
  21. This specification was jointly developed by Microsoft Corporation,
  22. Lotus Development Corporation, Intel Corporation,and AST Research,
  23. Inc. Although it has been released into the public domain and is not
  24. confidential or proprietary, the specification is still the copyright
  25. and property of Microsoft Corporation, Lotus Development Corporation,
  26. Intel Corporation, and AST Research, Inc.
  27.  
  28. Disclaimer of Warranty
  29.  
  30. MICROSOFT CORPORATION, LOTUS DEVELOPMENT CORPORATION, INTEL
  31. CORPORATION, AND AST RESEARCH, INC., EXCLUDE ANY AND ALL IMPLIED
  32. WARRANTIES, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  33. PARTICULAR PURPOSE. NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST
  34. RESEARCH MAKE ANY WARRANTY OF REPRESENTATION, EITHER EXPRESS OR
  35. IMPLIED, WITH RESPECT TO THIS SPECIFICATION, ITS QUALITY,
  36. PERFORMANCE, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
  37. NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST RESEARCH SHALL HAVE ANY
  38. LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
  39. OUT OF OR RESULTING FROM THE USE OR MODIFICATION OF THIS
  40. SPECIFICATION.
  41.  
  42. This specification uses the following trademarks:
  43.  
  44. Intel is a registered trademark of Intel Corporation, Microsoft is a
  45. registered trademark of Microsoft Corporation, Lotus is a registered
  46. trademark of Lotus Development Corporation, and AST is a registered
  47. trademark of AST Research, Inc.
  48.  
  49.  
  50.  
  51. Extended Memory Specification
  52.  
  53.     The purpose of this document is to define the Extended Memory Specification (XMS) version 3.00 for MS-DOS.  XMS allows DOS programs to utilize additional memory found in Intel's 80286 and 80386 based machines in a consistent, machine independent manner.  With some restrictions, XMS adds almost 64K to the 640K which DOS programs can access directly.  Depending on available hardware, XMS may provide even more memory to DOS programs.  XMS also provides DOS programs with a standard method of storing data in extended memory.
  54.  
  55.         To be considered fully XMS 3.0 compliant, all calls except those associated with UMB support must be implemented. UMB functions 10h, 11h and 12h are optional for XMS 3.0 and may return the Function Not Implemented error code, 80h.
  56.  
  57. DEFINITIONS:
  58. ------------
  59.  
  60. Extended Memory:
  61. Memory in 80286 and 80386 based machines which is located above the 1MB address boundary.
  62.  
  63. High Memory Area (HMA):
  64. The first 64K of extended memory.  The High Memory Area is unique because code can be executed in it while in real mode.  The HMA officially starts at FFFF:10h and ends at FFFF:FFFFh making it 64K-16 bytes in length.
  65.                     
  66. Upper Memory Blocks (UMBs):
  67. Blocks of memory available on some 80x86 based machines which are located between DOS's 640K limit and the 1MB address boundary.  The number, size, and location of these blocks vary widely depending upon the types of hardware adapter cards installed in the machine.
  68.                     
  69. Extended Memory Blocks (EMBs):
  70. Blocks of extended memory located above the HMA which can only be used for data storage.
  71.                     
  72. A20 Line:
  73. The 21st address line of 80x86 CPUs.  Enabling the A20 line allows access to the HMA.
  74.  
  75. XMM:
  76. An Extended Memory Manager.  A DOS device driver which implements XMS.  XMMs are machine specific but allow programs to use extended memory in a machine-independent manner.
  77.     
  78. HIMEM.SYS:
  79. The Extended Memory Manager currently being distributed by Microsoft.
  80.  
  81.  
  82.  
  83. Helpful Diagram:
  84.  
  85. |               |   Top of Memory
  86. |               |
  87. |               |
  88. |       /\      |
  89. |       /||\    |
  90. |       ||      |
  91. |       ||      |
  92. |               |
  93. |               |
  94. |               |
  95. |       Possible Extended Memory Block  |
  96. |               |
  97. |               |
  98. |               |
  99. |       ||      |
  100. |       ||      |
  101. |       \||/    |
  102. |       \/      |
  103. |               |
  104. |               |
  105. |       Other EMBs could exist above 1088K (1MB+64K)    |
  106. |               |
  107. |               |
  108. |               |   1088K
  109. |               |
  110. |               |
  111. |       The High Memory Area    |
  112. |               |
  113. |               |
  114. |               |   1024K or 1MB
  115. |               |
  116. |       /\      |
  117. |       /||\    |
  118. |       ||      |
  119. |       ||      |
  120. |               |
  121. |               |
  122. |       Possible Upper Memory Block     |
  123. |               |
  124. |       ||      |
  125. |       ||      |
  126. |       \||/    |
  127. |       \/      |
  128. |               |
  129. |       Other UMBs could exist between 640K and 1MB     |
  130. |               |
  131. |               |   640K
  132.  
  133. |               |
  134. |               |
  135. |               |
  136. |       Conventional or DOS Memory      |
  137. |               |
  138. |               |
  139. |               |
  140. |               |
  141. |               |
  142. +               +   0K
  143.  
  144. DRIVER INSTALLATION:
  145. --------------------
  146.  
  147.     An XMS driver is installed by including a DEVICE= statement in the
  148. machine's CONFIG.SYS file.  It must be installed prior to any other
  149. devices or TSRs which use it.  An optional parameter after the driver's 
  150. name (suggested name "/HMAMIN=") indicates the minimum amount of space in
  151. the HMA a program can use.  Programs which use less than the minimum will
  152. not be placed in the HMA.  See "Prioritizing HMA Usage" below for more
  153. information.  A second optional parameter (suggested name "/NUMHANDLES=")
  154. allows users to specify the maximum number of extended memory blocks which
  155. may be allocated at any time.
  156.  
  157.     NOTE: XMS requires DOS 3.00 or above.
  158.  
  159.  
  160. THE PROGRAMMING API:
  161. --------------------
  162.  
  163.     The XMS API Functions are accessed via the XMS driver's Control Function.
  164. The address of the Control Function is determined via INT 2Fh.  First, a
  165. program should determine if an XMS driver is installed.  Next, it should
  166. retrieve the address of the driver's Control Function.  It can then use any
  167. of the available XMS functions.  The functions are divided into several
  168. groups:
  169.  
  170.         1. Driver Information Functions (0h)
  171.         2. HMA Management Functions (1h-2h)
  172.         3. A20 Management Functions (3h-7h)
  173.         4. Extended Memory Management Functions (8h-Fh)
  174.         5. Upper Memory Management Functions (10h-11h)
  175.  
  176.  
  177. DETERMINING IF AN XMS DRIVER IS INSTALLED:
  178. ------------------------------------------
  179.  
  180.     The recommended way of determining if an XMS driver is installed is to
  181. set AH=43h and AL=00h and then execute INT 2Fh.  If an XMS driver is available,
  182. 80h will be returned in AL.
  183.  
  184.     Example:
  185.             ; Is an XMS driver installed?
  186.             mov     ax,4300h
  187.             int     2Fh         
  188.             cmp     al,80h  
  189.             jne     NoXMSDriver
  190.             
  191.  
  192. CALLING THE API FUNCTIONS:
  193. --------------------------
  194.  
  195.     Programs can execute INT 2Fh with AH=43h and AL=10h to obtain the address
  196. of the driver's control function.  The address is returned in ES:BX.  This
  197. function is called to access all of the XMS functions.  It should be called
  198. with AH set to the number of the API function requested.  The API function
  199. will put a success code of 0001h or 0000h in AX.  If the function succeeded
  200. (AX=0001h), additional information may be passed back in BX and DX.  If the
  201. function failed (AX=0000h), an error code may be returned in BL.  Valid
  202. error codes have their high bit set.  Developers should keep in mind that
  203. some of the XMS API functions may not be implemented by all drivers and will
  204. return failure in all cases.
  205.  
  206.     Example:
  207.             ; Get the address of the driver's control function
  208.             mov     ax,4310h
  209.             int     2Fh
  210.             mov     word ptr [XMSControl],bx        ; XMSControl is a DWORD
  211.             mov     word ptr [XMSControl+2],es
  212.             
  213.             ; Get the XMS driver's version number
  214.             mov     ah,00h
  215.             call    [XMSControl]    ; Get XMS Version Number
  216.  
  217.     NOTE: Programs should make sure that at least 256 bytes of stack space
  218.           is available before calling XMS API functions.
  219.  
  220.  
  221. API FUNCTION DESCRIPTIONS:
  222. --------------------------
  223.  
  224.     The following XMS API functions are available:
  225.  
  226.        0h)  Get XMS Version Number
  227.        1h)  Request High Memory Area
  228.        2h)  Release High Memory Area
  229.        3h)  Global Enable A20
  230.        4h)  Global Disable A20
  231.        5h)  Local Enable A20
  232.        6h)  Local Disable A20
  233.        7h)  Query A20
  234.        8h)  Query Free Extended Memory
  235.        9h)  Allocate Extended Memory Block
  236.        Ah)  Free Extended Memory Block
  237.        Bh)  Move Extended Memory Block
  238.        Ch)  Lock Extended Memory Block
  239.        Dh)  Unlock Extended Memory Block
  240.        Eh)  Get Handle Information
  241.        Fh)  Reallocate Extended Memory Block
  242.       10h)  Request Upper Memory Block
  243.       11h)  Release Upper Memory Block
  244.       12h) Realloc Upper Memory Block
  245.       88h) Query any Free Extended Memory
  246.       89h) Allocate any Extended Memory Block
  247.       8Eh) Get Extended EMB Handle
  248.       8Fh) Realloc any Extended Memory
  249.  
  250. Each is described below.
  251.  
  252.  
  253. Get XMS Version Number (Function 00h):
  254. --------------------------------------
  255.  
  256.     ARGS:   AH = 00h
  257.     RETS:   AX = XMS version number
  258.             BX = Driver internal revision number
  259.             DX = 0001h if the HMA exists, 0000h otherwise
  260.     ERRS:   None
  261.  
  262.     This function returns with AX equal to a 16-bit BCD number representing
  263. the revision of the DOS Extended Memory Specification which the driver
  264. implements (e.g. AX=0235h would mean that the driver implemented XMS version
  265. 2.35).  BX is set equal to the driver's internal revision number mainly for
  266. debugging purposes.  DX indicates the existence of the HMA (not its
  267. availability) and is intended mainly for installation programs.
  268.     
  269.     NOTE: This document defines version 3.00 of the specification.
  270.  
  271.  
  272. Request High Memory Area (Function 01h):
  273. ----------------------------------------
  274.  
  275.     ARGS:   AH = 01h
  276.             If the caller is a TSR or device driver,
  277.                 DX = Space needed in the HMA by the caller in bytes
  278.             If the caller is an application program,
  279.                 DX = FFFFh     
  280.     RETS:   AX = 0001h if the HMA is assigned to the caller, 0000h otherwise
  281.     ERRS:   BL = 80h if the function is not implemented
  282.             BL = 81h if a VDISK device is detected
  283.             BL = 90h if the HMA does not exist
  284.             BL = 91h if the HMA is already in use
  285.             BL = 92h if DX is less than the /HMAMIN= parameter
  286.  
  287.     This function attempts to reserve the 64K-16 byte high memory area for
  288. the caller.  If the HMA is currently unused, the caller's size parameter is
  289. compared to the /HMAMIN= parameter on the driver's command line.  If the
  290. value passed by the caller is greater than or equal to the amount specified
  291. by the driver's parameter, the request succeeds.  This provides the ability
  292. to ensure that programs which use the HMA efficiently have priority over
  293. those which do not.
  294.  
  295.     NOTE: See the sections "Prioritizing HMA Usage" and "High Memory Area
  296.           Restrictions" below for more information.
  297.  
  298.  
  299. Release High Memory Area (Function 02h):
  300. ----------------------------------------
  301.  
  302.     ARGS:   AH = 02h
  303.     RETS:   AX = 0001h if the HMA is successfully released, 0000h otherwise
  304.     ERRS:   BL = 80h if the function is not implemented
  305.             BL = 81h if a VDISK device is detected
  306.             BL = 90h if the HMA does not exist
  307.             BL = 93h if the HMA was not allocated
  308.  
  309.     This function releases the high memory area and allows other programs to
  310. use it.  Programs which allocate the HMA must release it before exiting.  
  311. When the HMA has been released, any code or data stored in it becomes invalid
  312. and should not be accessed.
  313.  
  314.  
  315. Global Enable A20 (Function 03h):
  316. ---------------------------------
  317.  
  318.     ARGS:   AH = 03h
  319.     RETS:   AX = 0001h if the A20 line is enabled, 0000h otherwise
  320.     ERRS:   BL = 80h if the function is not implemented
  321.             BL = 81h if a VDISK device is detected
  322.             BL = 82h if an A20 error occurs
  323.  
  324.     This function attempts to enable the A20 line.  It should only be used
  325. by programs which have control of the HMA.  The A20 line should be turned
  326. off via Function 04h (Global Disable A20) before a program releases control
  327. of the system.
  328.  
  329.     NOTE: On many machines, toggling the A20 line is a relatively slow
  330.           operation.
  331.  
  332.  
  333. Global Disable A20 (Function 04h):
  334. ----------------------------------
  335.  
  336.     ARGS:   AH = 04h
  337.     RETS:   AX = 0001h if the A20 line is disabled, 0000h otherwise
  338.     ERRS:   BL = 80h if the function is not implemented
  339.             BL = 81h if a VDISK device is detected
  340.             BL = 82h if an A20 error occurs
  341.             BL = 94h if the A20 line is still enabled
  342.     
  343.     This function attempts to disable the A20 line.  It should only be used
  344. by programs which have control of the HMA.  The A20 line should be disabled
  345. before a program releases control of the system.
  346.  
  347.     NOTE: On many machines, toggling the A20 line is a relatively slow
  348.           operation.
  349.  
  350.  
  351. Local Enable A20 (Function 05h):
  352. --------------------------------
  353.  
  354.     ARGS:   AH = 05h
  355.     RETS:   AX = 0001h if the A20 line is enabled, 0000h otherwise
  356.     ERRS:   BL = 80h if the function is not implemented
  357.             BL = 81h if a VDISK device is detected
  358.             BL = 82h if an A20 error occurs
  359.  
  360.     This function attempts to enable the A20 line.  It should only be used
  361. by programs which need direct access to extended memory.  Programs which use
  362. this function should call Function 06h (Local Disable A20) before releasing
  363. control of the system.
  364.  
  365.     NOTE: On many machines, toggling the A20 line is a relatively slow
  366.           operation.
  367.  
  368.  
  369. Local Disable A20 (Function 06h):
  370. ---------------------------------
  371.  
  372.     ARGS:   AH = 06h
  373.     RETS:   AX = 0001h if the function succeeds, 0000h otherwise
  374.     ERRS:   BL = 80h if the function is not implemented
  375.             BL = 81h if a VDISK device is detected
  376.             BL = 82h if an A20 error occurs
  377.             BL = 94h if the A20 line is still enabled
  378.  
  379.     This function cancels a previous call to Function 05h (Local Enable
  380. A20).  It should only be used by programs which need direct access to
  381. extended memory.  Previous calls to Function 05h must be canceled before
  382. releasing control of the system.
  383.  
  384.     NOTE: On many machines, toggling the A20 line is a relatively slow
  385.           operation.
  386.  
  387.  
  388. Query A20 (Function 07h):
  389. -------------------------
  390.  
  391.     ARGS:   AH = 07h
  392.     RETS:   AX = 0001h if the A20 line is physically enabled, 0000h otherwise
  393.     ERRS:   BL = 00h if the function succeeds
  394.             BL = 80h if the function is not implemented
  395.             BL = 81h if a VDISK device is detected
  396.  
  397.     This function checks to see if the A20 line is physically enabled.  It
  398. does this in a hardware independent manner by seeing if "memory wrap" occurs.
  399.  
  400.  
  401. Query Free Extended Memory (Function 08h):
  402. ------------------------------------------
  403.  
  404.     ARGS:   AH = 08h
  405.     RETS:   AX = Size of the largest free extended memory block in K-bytes
  406.             DX = Total amount of free extended memory in K-bytes
  407.     ERRS:   BL = 80h if the function is not implemented
  408.             BL = 81h if a VDISK device is detected
  409.             BL = A0h if all extended memory is allocated
  410.  
  411.     This function returns the size of the largest available extended memory
  412. block in the system.
  413.  
  414.     NOTE: The 64K HMA is not included in the returned value even if it is
  415.           not in use.
  416.  
  417.  
  418. Allocate Extended Memory Block (Function 09h):
  419. ----------------------------------------------
  420.  
  421.     ARGS:   AH = 09h
  422.             DX = Amount of extended memory being requested in K-bytes
  423.     RETS:   AX = 0001h if the block is allocated, 0000h otherwise
  424.             DX = 16-bit handle to the allocated block
  425.     ERRS:   BL = 80h if the function is not implemented
  426.             BL = 81h if a VDISK device is detected
  427.             BL = A0h if all available extended memory is allocated
  428.             BL = A1h if all available extended memory handles are in use
  429.             
  430.     This function attempts to allocate a block of the given size out of the
  431. pool of free extended memory.  If a block is available, it is reserved
  432. for the caller and a 16-bit handle to that block is returned.  The handle
  433. should be used in all subsequent extended memory calls.  If no memory was
  434. allocated, the returned handle is null.
  435.  
  436.     NOTE: Extended memory handles are scarce resources.  Programs should
  437.           try to allocate as few as possible at any one time.  When all
  438.           of a driver's handles are in use, any free extended memory is
  439.           unavailable.
  440.  
  441.  
  442.  
  443. Free Extended Memory Block (Function 0Ah):
  444. ------------------------------------------
  445.  
  446.     ARGS:   AH = 0Ah
  447.             DX = Handle to the allocated block which should be freed
  448.     RETS:   AX = 0001h if the block is successfully freed, 0000h otherwise
  449.     ERRS:   BL = 80h if the function is not implemented
  450.             BL = 81h if a VDISK device is detected
  451.             BL = A2h if the handle is invalid
  452.             BL = ABh if the handle is locked
  453.  
  454.     This function frees a block of extended memory which was previously
  455. allocated using Function 09h (Allocate Extended Memory Block).  Programs
  456. which allocate extended memory should free their memory blocks before
  457. exiting.  When an extended memory buffer is freed, its handle and all data
  458. stored in it become invalid and should not be accessed.
  459.  
  460.  
  461. Move Extended Memory Block (Function 0Bh):
  462. ------------------------------------------
  463.  
  464.     ARGS:   AH = 0Bh
  465.             DS:SI = Pointer to an Extended Memory Move Structure (see below)
  466.     RETS:   AX = 0001h if the move is successful, 0000h otherwise
  467.     ERRS:   BL = 80h if the function is not implemented
  468.             BL = 81h if a VDISK device is detected
  469.             BL = 82h if an A20 error occurs
  470.             BL = A3h if the SourceHandle is invalid
  471.             BL = A4h if the SourceOffset is invalid
  472.             BL = A5h if the DestHandle is invalid
  473.             BL = A6h if the DestOffset is invalid
  474.             BL = A7h if the Length is invalid
  475.             BL = A8h if the move has an invalid overlap
  476.             BL = A9h if a parity error occurs
  477.  
  478.     Extended Memory Move Structure Definition:
  479.  
  480.         ExtMemMoveStruct    struc
  481.             Length              dd  ?   ; 32-bit number of bytes to transfer
  482.             SourceHandle        dw  ?   ; Handle of source block
  483.             SourceOffset        dd  ?   ; 32-bit offset into source 
  484.             DestHandle          dw  ?   ; Handle of destination block
  485.             DestOffset          dd  ?   ; 32-bit offset into destination block
  486.         ExtMemMoveStruct    ends
  487.             
  488.     This function attempts to transfer a block of data from one location to
  489. another.  It is primarily intended for moving blocks of data between
  490. conventional memory and extended memory, however it can be used for moving
  491. blocks within conventional memory and within extended memory.
  492.  
  493.     NOTE: If SourceHandle is set to 0000h, the SourceOffset is interpreted
  494.           as a standard segment:offset pair which refers to memory that is
  495.           directly accessible by the processor.  The segment:offset pair
  496.           is stored in Intel DWORD notation.  The same is true for DestHandle
  497.           and DestOffset.
  498.           
  499.           SourceHandle and DestHandle do not have to refer to locked memory
  500.           blocks.
  501.           
  502.           Length must be even.  Although not required, WORD-aligned moves
  503.           can be significantly faster on most machines.  DWORD aligned move
  504.           can be even faster on 80386 machines.
  505.           
  506.           If the source and destination blocks overlap, only forward moves
  507.           (i.e. where the source base is less than the destination base) are
  508.           guaranteed to work properly.
  509.           
  510.           Programs should not enable the A20 line before calling this
  511.           function.  The state of the A20 line is preserved.
  512.  
  513.           This function is guaranteed to provide a reasonable number of
  514.           interrupt windows during long transfers.
  515.           
  516.           
  517. Lock Extended Memory Block (Function 0Ch):
  518. ------------------------------------------
  519.  
  520.     ARGS:   AH = 0Ch
  521.             DX = Extended memory block handle to lock
  522.     RETS:   AX = 0001h if the block is locked, 0000h otherwise
  523.             DX:BX = 32-bit physical address of the locked block
  524.     ERRS:   BL = 80h if the function is not implemented
  525.             BL = 81h if a VDISK device is detected
  526.             BL = A2h if the handle is invalid
  527.             BL = ACh if the block's lock count overflows
  528.             BL = ADh if the lock fails
  529.             
  530.     This function locks an extended memory block and returns its base 
  531. address as a 32-bit physical address.  Locked memory blocks are guaranteed not
  532. to move.  The 32-bit pointer is only valid while the block is locked.
  533. Locked blocks should be unlocked as soon as possible.
  534.  
  535.     NOTE: A block does not have to be locked before using Function 0Bh (Move
  536.           Extended Memory Block).
  537.           
  538.           "Lock counts" are maintained for EMBs.
  539.  
  540.  
  541.  
  542. Unlock Extended Memory Block (Function 0Dh):
  543. --------------------------------------------
  544.  
  545.     ARGS:   AH = 0Dh
  546.             DX = Extended memory block handle to unlock
  547.     RETS:   AX = 0001h if the block is unlocked, 0000h otherwise
  548.     ERRS:   BL = 80h if the function is not implemented
  549.             BL = 81h if a VDISK device is detected
  550.             BL = A2h if the handle is invalid
  551.             BL = AAh if the block is not locked
  552.     
  553.     This function unlocks a locked extended memory block.  Any 32-bit
  554. pointers into the block become invalid and should no longer be used.
  555.  
  556.  
  557. Get EMB Handle Information (Function 0Eh):
  558. ------------------------------------------
  559.  
  560.     ARGS:   AH = 0Eh
  561.             DX = Extended memory block handle
  562.     RETS:   AX = 0001h if the block's information is found, 0000h otherwise
  563.             BH = The block's lock count
  564.             BL = Number of free EMB handles in the system
  565.             DX = The block's length in K-bytes
  566.     ERRS:   BL = 80h if the function is not implemented
  567.             BL = 81h if a VDISK device is detected
  568.             BL = A2h if the handle is invalid
  569.  
  570.     This function returns additional information about an extended memory
  571. block to the caller.
  572.  
  573.     NOTE: To get the block's base address, use Function 0Ch (Lock Extended
  574.           Memory Block).
  575.           
  576.           
  577. Reallocate Extended Memory Block (Function 0Fh):
  578. ------------------------------------------------
  579.  
  580.     ARGS:   AH = 0Fh
  581.             BX = New size for the extended memory block in K-bytes
  582.             DX = Unlocked extended memory block handle to reallocate
  583.     RETS:   AX = 0001h if the block is reallocated, 0000h otherwise
  584.     ERRS:   BL = 80h if the function is not implemented
  585.             BL = 81h if a VDISK device is detected
  586.             BL = A0h if all available extended memory is allocated
  587.             BL = A1h if all available extended memory handles are in use
  588.             BL = A2h if the handle is invalid
  589.             BL = ABh if the block is locked
  590.  
  591.     This function attempts to reallocate an unlocked extended memory block
  592. so that it becomes the newly specified size.  If the new size is smaller
  593. than the old block's size, all data at the upper end of the old block is
  594. lost.
  595.  
  596.  
  597. Request Upper Memory Block (Function 10h):
  598. ------------------------------------------
  599.  
  600.     ARGS:   AH = 10h
  601.             DX = Size of requested memory block in paragraphs
  602.     RETS:   AX = 0001h if the request is granted, 0000h otherwise
  603.             BX = Segment number of the upper memory block
  604.             If the request is granted,
  605.                 DX = Actual size of the allocated block in paragraphs
  606.             otherwise,
  607.                 DX = Size of the largest available UMB in paragraphs
  608.     ERRS:   BL = 80h if the function is not implemented
  609.             BL = B0h if a smaller UMB is available
  610.             BL = B1h if no UMBs are available
  611.  
  612.     This function attempts to allocate an upper memory block to the caller.
  613. If the function fails, the size of the largest free UMB is returned in DX.
  614.  
  615.     NOTE: By definition UMBs are located below the 1MB address boundary.
  616.           The A20 Line does not need to be enabled before accessing an
  617.           allocated UMB.
  618.  
  619.           UMBs are paragraph aligned.
  620.  
  621.           To determine the size of the largest available UMB, attempt to
  622.           allocate one with a size of FFFFh.
  623.  
  624.           UMBs are unaffected by EMS calls.
  625.  
  626.  
  627. Release Upper Memory Block (Function 11h):
  628. ------------------------------------------
  629.  
  630.     ARGS:   AH = 11h
  631.             DX = Segment number of the upper memory block
  632.     RETS:   AX = 0001h if the block was released, 0000h otherwise
  633.     ERRS:   BL = 80h if the function is not implemented
  634.             BL = B2h if the UMB segment number is invalid
  635.  
  636.     This function frees a previously allocated upper memory block.  When an
  637. UMB has been released, any code or data stored in it becomes invalid and
  638. should not be accessed.
  639.  
  640.  
  641.  
  642.  
  643. Reallocate Upper Memory Block (Function 12h)
  644.  
  645.         ARGS:
  646.                 AH = 12h
  647.                 BX = New size for UMB in paragraphs
  648.                 DX = Segment number of the UMB to reallocate
  649.         RETS:
  650.                 AX = 1 if the block was reallocated, 0 otherwise
  651.         ERRS:
  652.                 BL = 80h if the function is not implemented
  653.                 BL = B0h if no UMB large enough to satisfy the request is available.
  654.                         In this event, DX is returned with the size of the largest UMB that is                  available.
  655.                 BL = B2h if the UMB segment number is invalid
  656.  
  657. This function attempts to reallocate an Upper Memory Block to a newly specified size.  If the new size is smaller than the old block's size, all data at the upper end of the block is lost.
  658.  
  659.  
  660.  
  661. Super Extended Memory Support
  662.  
  663. These changes are intended to provide support for extended memory pools up to 4 Gb in size.  The current XMS API, since it uses 16-bit values to specify block sizes in Kb, is limited to 64 Mb maximum block size.  Future machines are expected to support memory above 64 MB.
  664.  
  665. This support is implemented in the form of extensions to existing functions, rather than entirely new entry points, to allow for more efficient implementations.
  666.  
  667. Programs should generally use the existing functions, instead of these extended ones, unless they have an explicit need to deal with memory above 64 Mb.  
  668.  
  669.  
  670. Query Any Free Extended Memory (Function 88h)
  671.  
  672.         Entry:
  673.                 AH = 88h                        
  674.         Exit:
  675.                 EAX = Size of largest free extended memory block in Kb.
  676.                 BL = 0 if no error occurs, otherwise it takes an error code.
  677.                 ECX = Highest ending address of any memory block.
  678.                 EDX = Total amount of free memory in Kb.
  679.         Errors:
  680.                 BL = 80h if the function is not implemented.
  681.                 BL = 81h if a VDISK device is detected.
  682.                 BL = A0h if all extended memory is allocated.
  683.  
  684. This function uses 32-bit values to return the size of available memory, thus allowing returns up to 4GByte.  Additionally, it returns the highest known physical memory address, that is, the physical address of the last byte of memory.  There may be discontinuities in the memory map below this address.
  685.  
  686. The memory pool reported on is the same as that reported on by the existing Query Free Extended Memory function.  If the highest memory address is not more than 64 Mb, then these two functions will return the same results.
  687.  
  688. Because of its reliance on 32-bit registers, this function is only available on 80386 and higher processors.  XMS drivers on 80286 machines should return error code 80h if this function is called.
  689.  
  690. If error code 81h is returned, the value in ECX will still be valid.  If error code A0h is returned, EAX and EDX will be 0, and ECX will still be valid.
  691.  
  692.  
  693. Allocate Any Extended Memory (Function 89h)
  694.  
  695.         Entry:
  696.                 AH = 89h
  697.                 EDX = Amount of extended memory requested, in Kb.
  698.         Exit:
  699.                 AX = 1 if the block is allocated, 0 if not
  700.                 DX = Handle to allocated block.
  701.         Errors:
  702.                 BL = 80h if the function is not implemented.
  703.                 BL = 81h if a VDISK device is detected.
  704.                 BL = A0h if all available extended memory is allocated.
  705.                 BL = A1h if all available extended memory handles are in use.
  706.  
  707. This function is similar to the existing Allocate Extended Memory, except that it uses a 32-bit instead of a 16-bit value to specify the amount of memory requested.  It allocates from the same memory and handle pool as the current function.  Since it requires a 32-bit register, this function can be supported only on 80386 and higher processors, and XMS drivers on 80286 machines should return error code 80h.
  708.  
  709.  
  710. Get Extended EMB Handle Information (Function 8Eh)
  711.  
  712.         Entry:
  713.                 AH = 8Eh
  714.                 DX = Extended memory block handle.
  715.         Exit:
  716.                 AX = 1 if the block's information is found, 0 if not
  717.                 BH = Block lock count
  718.                 CX = Number of free EMB handles in the system
  719.                 EDX = Block's length in Kb.
  720.         Errors:
  721.                 BL = 80h if the function is not implemented.
  722.                 BL = 81h if a VDISK device is detected.
  723.                 BL = A2h if the handle is invalid.
  724.  
  725. This function is similar to the Get EMB Handle Information function.  Since it uses a 32-bit register to report the block size, it can be used to get information on blocks larger than 64 Mb.  It also uses a 16-bit instead of 8-bit register to report the number of free handles, allowing the handle pool to be extended beyond 256 entries.
  726.  
  727. Because of its reliance on a 32-bit register, this function is available on 80386 and higher processors.  XMS drivers on 80286 machines should return error code 80h if this function is called.
  728.  
  729.  
  730. Reallocate Any Extended Memory (Function 8Fh)
  731.  
  732.         Entry:
  733.                 AH = 8Fh
  734.                 EBX = New size for extended memory block, in Kb.
  735.                 DX = Unlocked handle for memory block to be resized.
  736.         Exit:
  737.                 AX = 1 if the block is reallocated, 0 if not
  738.         Errors:
  739.                 BL = 80h if the function is not implemented.
  740.                 BL = 81h if a VDISK device is detected.
  741.                 BL = A0h if all available extended memory is allocated.
  742.                 BL = A1h if all available extended memory handles are in use.
  743.                 BL = A2h if the handle is invalid.
  744.                 BL = ABh if the block is locked.
  745.  
  746. This function is similar to the existing Reallocate Extended Memory, except that it uses a 32-bit instead of a 16-bit value to specify the amount of memory requested.  It allocates from the same memory and handle pool as the current function.  Since it requires a 32-bit register, this function can be supported only on 80386 and higher processors, and XMS drivers on 80286 machines should return error code 80h.
  747.  
  748.  
  749.  
  750.  
  751. PRIORITIZING HMA USAGE:
  752. -----------------------
  753.  
  754.     For DOS users to receive the maximum benefit from the High Memory Area,
  755. programs which use the HMA must store as much of their resident code in it as
  756. is possible.  It is very important that developers realize that the HMA is
  757. allocated as a single unit. 
  758.  
  759.     For example, a TSR program which grabs the HMA and puts 10K of code into
  760. it may prevent a later TSR from putting 62K into the HMA.  Obviously, regular
  761. DOS programs would have more memory available to them below the 640K line if
  762. the 62K TSR was moved into the HMA instead of the 10K one.
  763.  
  764.     The first method for dealing with conflicts such as this is to require 
  765. programs which use the HMA to provide a command line option for disabling
  766. this feature.  It is crucial that TSRs which do not make full use of the HMA
  767. provide such a switch on their own command line (suggested name "/NOHMA").
  768.  
  769.     The second method for optimizing HMA usage is through the /HMAMIN=
  770. parameter on the XMS device driver line.  The number after the parameter
  771. is defined to be the minimum amount of HMA space (in K-bytes) used by any
  772. driver or TSR.  For example, if "DEVICE=HIMEM.SYS /HMAMIN=48" is in a
  773. user's CONFIG.SYS file, only programs which request at least 48K would be
  774. allowed to allocate the HMA.  This number can be adjusted either by
  775. installation programs or by the user himself.  If this parameter is not
  776. specified, the default value of 0 is used causing the HMA to be allocated
  777. on a first come, first served basis.
  778.  
  779.     Note that this problem does not impact application programs.  If the HMA
  780. is available when an application program starts, the application is free to
  781. use as much or as little of the HMA as it wants.  For this reason,
  782. applications should pass FFFFh in DX when calling Function 01h.
  783.  
  784.  
  785.  
  786. HIGH MEMORY AREA RESTRICTIONS:
  787. ------------------------------
  788.  
  789. -   Far pointers to data located in the HMA cannot be passed to DOS.  DOS
  790.     normalizes any pointer which is passed into it.  This will cause data
  791.     addresses in the HMA to be invalidated.
  792.  
  793. -   Disk I/O directly into the HMA (via DOS, INT 13h, or otherwise) is not
  794.     recommended.
  795.        
  796. -   Programs, especially drivers and TSRs, which use the HMA *MUST* use
  797.     as much of it as possible.  If a driver or TSR is unable to use at
  798.     least 90% of the available HMA (typically ~58K), they must provide
  799.     a command line switch for overriding HMA usage.  This will allow
  800.     the user to configure his machine for optimum use of the HMA.
  801.        
  802. -   Device drivers and TSRs cannot leave the A20 line permanently turned
  803.     on.  Several applications rely on 1MB memory wrap and will overwrite the
  804.     HMA if the A20 line is left enabled potentially causing a system crash.
  805.         
  806. -   Interrupt vectors must not point into the HMA.  This is a result of
  807.     the previous restriction.  Note that interrupt vectors can point into
  808.     any allocated upper memory blocks however.
  809.  
  810. ERROR CODE INDEX:
  811. -----------------
  812.  
  813. If AX=0000h when a function returns and the high bit of BL is set,
  814.  
  815.     BL=80h if the function is not implemented
  816.        81h if a VDISK device is detected
  817.        82h if an A20 error occurs
  818.        8Eh if a general driver error occurs
  819.        8Fh if an unrecoverable driver error occurs
  820.        90h if the HMA does not exist
  821.        91h if the HMA is already in use
  822.        92h if DX is less than the /HMAMIN= parameter
  823.        93h if the HMA is not allocated
  824.        94h if the A20 line is still enabled
  825.        A0h if all extended memory is allocated
  826.        A1h if all available extended memory handles are in use
  827.        A2h if the handle is invalid
  828.        A3h if the SourceHandle is invalid
  829.        A4h if the SourceOffset is invalid
  830.        A5h if the DestHandle is invalid
  831.        A6h if the DestOffset is invalid
  832.        A7h if the Length is invalid
  833.        A8h if the move has an invalid overlap
  834.        A9h if a parity error occurs
  835.        AAh if the block is not locked
  836.        ABh if the block is locked
  837.        ACh if the block's lock count overflows
  838.        ADh if the lock fails
  839.        B0h if a smaller UMB is available
  840.        B1h if no UMBs are available
  841.        B2h if the UMB segment number is invalid
  842.  
  843.  
  844. IMPLEMENTATION NOTES FOR DOS XMS DRIVERS:
  845. -----------------------------------------
  846.  
  847. -   A DOS XMS driver's control function must begin with code similar to the
  848.     following:
  849.  
  850. XMMControl  proc    far
  851.  
  852.             jmp     short XCControlEntry    ; For "hookability"
  853.             nop                     ; NOTE: The jump must be a short
  854.             nop                     ;  jump to indicate the end of
  855.             nop                     ;  any hook chainThe nop's
  856.                                             ;  allow a far jump to be
  857.                                             ;  patched in.
  858. XCControlEntry:
  859.  
  860.  
  861. -   XMS drivers must preserve all registers except those containing
  862.     returned values across any function call.
  863.  
  864. -   XMS drivers are required to hook INT 15h and watch for calls to
  865.     functions 87h (Block Move) and 88h (Extended Memory Available).  The
  866.     INT 15h Block Move function must be hooked so that the state of the A20
  867.     line is preserved across the call.  The INT 15h Extended Memory
  868.     Available function must be hooked to return 0h to protect the HMA.
  869.  
  870. -   In order to maintain compatibility with existing device drivers, DOS XMS
  871.     drivers must not hook INT 15h until the first non-Version Number call
  872.     to the control function is made.
  873.  
  874. -   XMS drivers are required to check for the presence of drivers which
  875.     use the IBM VDISK allocation scheme.  Note that it is not sufficient to
  876.     check for VDISK users at installation time but at the time when the HMA
  877.     is first allocated.  If a VDISK user is detected, the HMA must not be
  878.     allocated.  Microsoft will publish a standard method for detecting
  879.     drivers which use the VDISK allocation scheme.
  880.  
  881. -   XMS drivers which have a fixed number of extended memory handles (most
  882.     do) should implement a command line parameter for adjusting that number
  883.     (suggested name "/NUMHANDLES=")
  884.  
  885. -   XMS drivers should make sure that the major DOS version number is
  886.     greater than or equal to 3 before installing themselves.
  887.  
  888. -   UMBs cannot occupy memory addresses that can be banked by EMS 4.0.
  889.     EMS 4.0 takes precedence over UMBs for physically addressable memory.
  890.  
  891. -   All driver functions must be re-entrant.  Care should be taken to not
  892.     leave interrupts disabled for long periods of time.
  893.  
  894. -   Allocation of a zero length extended memory buffer is allowed.  Programs
  895.     which hook XMS drivers may need to reserve a handle for private use via
  896.     this method.  Programs which hook an XMS driver should pass all requests
  897.     for zero length EMBs to the next driver in the chain.
  898.  
  899. -   Drivers should control the A20 line via an "enable count."  Local En-
  900.     able only enables the A20 line if the count is zero.  It then increments
  901.     the count.  Local Disable only disables A20 if the count is one.  It
  902.     then decrements the count.  Global Enable/Disable keeps a flag which
  903.     indicates the state of A20.  They use Local Enable/Disable to actually
  904.     change the state.
  905.  
  906. -  Drivers should always check the physical A20 state in the local Enable-Disable calls, to see
  907.     that the physical state matches the internal count.  If the physical state does not match, it should
  908.     be modified so that it matches the internal count.  This avoids problems with applications that 
  909.     modify A20 directly.
  910.  
  911.  
  912. IMPLEMENTATION OF CODE FOR HOOKING THE XMS DRIVER:
  913.  
  914.   In order to support the hooking of the XMS driver by multiple
  915.   pieces of code, the following code sample should be followed.
  916.   Use of other methods for hooking the XMS driver will not work
  917.   in many cases. This method is the official supported one.
  918.  
  919.   The basic strategy is:
  920.  
  921.     Find the XMS driver header which has the "near jump" dispatch.
  922.  
  923.     Patch the near jump to a FAR jump which jumps to my HOOK XMS
  924.         driver header.
  925.  
  926.   NOTES:
  927.  
  928.     o This architecture allows the most recent HOOKer to undo his
  929.         XMS driver hook at any time without having to worry about
  930.         damaging a "hook chain".
  931.  
  932.     o This architecture allows the complete XMS hook chain to be
  933.         enumerated at any time. There are no "hidden hooks".
  934.  
  935.     o This architecture allows the HOOKer to not have to worry
  936.         about installing an "INT 2F hook" to hook the AH=43h
  937.         INT 2Fs handled by the XMS driver. The base XMS driver
  938.         continues to be the only one installed on INT 2Fh AH=43h.
  939.  
  940.         This avoids all of the problems of undoing a software
  941.         interrupt hook.
  942.  
  943.   ;
  944.   ; When I wish to CHAIN to the previous XMS driver, I execute a FAR JMP
  945.   ;     to the address stored in this DWORD.
  946.   ;
  947.   PrevXMSControlAddr    dd      ?
  948.  
  949.   ;
  950.   ; The next two data items are needed ONLY if I desire to be able to undo
  951.   ;     my XMS hook.
  952.   ; PrevXMSControlJmpVal stores the previos XMS dispatch near jump offset
  953.   ;     value that is used to unhook my XMS hook
  954.   ; PrevXMSControlBase stores the address of the XMS header that I hooked
  955.   ;
  956.   PrevXMSControlBase    dd      ?
  957.   PrevXMSControlJmpVal  db      ?
  958.  
  959.   ;
  960.   ; This is MY XMS control header.
  961.   ;
  962.   MyXMSControlFunc proc FAR
  963.         jmp     short XMSControlEntry
  964.         nop
  965.         nop
  966.         nop
  967.   XMSControlEntry:
  968.  
  969.   ......
  970.  
  971.   Chain:
  972.         jmp     cs:[PrevXMSControlAddr]
  973.  
  974.   MyXMSControlFunc endp
  975.  
  976.  
  977.   .......
  978.   ;
  979.   ; This is the code which installs my hook into the XMS driver.
  980.   ;
  981.     ;
  982.     ; See if there is an XMS driver to hook
  983.     ;
  984.         mov     ax,4300h
  985.         int     2Fh
  986.         cmp     al,80h
  987.         jne     NoXMSDrvrToHookError
  988.     ;
  989.     ; Get the current XMS driver Control address
  990.     ;
  991.         mov     ax,4310h
  992.         int     2Fh
  993.   NextXMSHeader:
  994.         mov     word ptr [PrevXMSControlAddr+2],es
  995.         mov     word ptr [PrevXMSControlBase+2],es
  996.         mov     word ptr [PrevXMSControlBase],bx
  997.         mov     cx,word ptr es:[bx]
  998.         cmp     cl,0EBh                         ; Near JUMP
  999.         je      ComputeNearJmp
  1000.         cmp     cl,0EAh                         ; Far JUMP
  1001.         jne     XMSDrvrChainMessedUpError
  1002.   ComputeFarJmp:
  1003.         mov     si,word ptr es:[bx+1]           ; Offset of jump
  1004.         mov     es,word ptr es:[bx+1+2]         ; Seg of jump
  1005.         mov     bx,si
  1006.         jmp     short NextXMSHeader
  1007.  
  1008.   ComputeNearJmp:
  1009.         cmp     word ptr es:[bx+2],9090h        ; Two NOPs?
  1010.         jne     XMSDrvrChainMessedUpError       ; No
  1011.         cmp     byte ptr es:[bx+4],90h          ; Total of 3 NOPs?
  1012.         jne     XMSDrvrChainMessedUpError       ; No
  1013.         mov     di,bx                           ; Save pointer to header
  1014.         xor     ax,ax
  1015.         mov     al,ch                           ; jmp addr of near jump
  1016.         mov     [PrevXMSControlJmpVal],al
  1017.         add     ax,2                            ; NEAR JMP is 2 byte instruction
  1018.         add     bx,ax                           ; Target of jump
  1019.         mov     word ptr [PrevXMSControlAddr],bx
  1020.     ;
  1021.     ; Now INSTALL my XMS HOOK
  1022.     ;
  1023.         cli                             ; Disable INTs in case someone calls
  1024.                                         ;       XMS at interrupt time
  1025.         mov     byte ptr es:[di],0EAh   ; Far Immed. JUMP instruction
  1026.         mov     word ptr es:[di+1],offset MyXMSControlFunc
  1027.         mov     word ptr es:[di+3],cs
  1028.         sti
  1029.     .....
  1030.  
  1031.     ;
  1032.     ; Deinstall my XMS hook. This can be done IF AND ONLY IF my XMS header
  1033.     ;   still contains the near jump dispatch
  1034.     ;
  1035.         cmp     byte ptr [MyXMSControlFunc],0EBh
  1036.         jne     CantDeinstallError
  1037.         mov     al,0EBh
  1038.         mov     ah,[PrevXMSControlJmpVal]
  1039.         les     bx,[PrevXMSControlBase]
  1040.         cli                             ; Disable INTs in case someone calls
  1041.                                         ;       XMS at interrupt time
  1042.         mov     word ptr es:[bx],ax
  1043.         mov     word ptr es:[bx+2],9090h
  1044.         mov     byte ptr es:[bx+4],90h
  1045.         sti
  1046.     ....
  1047.  
  1048. IMPLEMENTATION NOTES FOR HIMEM.SYS:
  1049. -----------------------------------
  1050.  
  1051. -   HIMEM.SYS currently supports true AT-compatibles, 386 AT machines, IBM
  1052.     PS/2s, AT&T 6300 Plus systems and Hewlett Packard Vectras.
  1053.  
  1054. -   If HIMEM finds that it cannot properly control the A20 line or if there
  1055.     is no extended memory available when HIMEM.SYS is invoked, the driver
  1056.     does not install itself.  HIMEM.SYS displays the message "High Memory
  1057.     Area Unavailable" when this situation occurs.
  1058.  
  1059. -   If HIMEM finds that the A20 line is already enabled when it is invoked,
  1060.     it will NOT change the A20 line's state.  The assumption is that whoever
  1061.     enabled it knew what they were doing.  HIMEM.SYS displays the message "A20
  1062.     Line Permanently Enabled" when this situation occurs.
  1063.  
  1064. -   HIMEM.SYS is incompatible with IBM's VDISK.SYS driver and other drivers
  1065.     which use the VDISK scheme for allocating extended memory.  However, 
  1066.     HIMEM does attempt to detect these drivers and will not allocate the
  1067.     HMA if one is found.
  1068.  
  1069. -   HIMEM.SYS supports the optional "/HMAMIN=" parameter.  The valid values
  1070.     are decimal numbers between 0 and 63.
  1071.  
  1072. -   By default, HIMEM.SYS has 32 extended memory handles available for use.
  1073.     This number may be adjusted with the "/NUMHANDLES=" parameter.  The
  1074.     maximum value for this parameter is 128 and the minimum is 0.  Each
  1075.     handle currently requires 6 bytes of resident space.
  1076.  
  1077.  
  1078. Copyright (c) 1988, Microsoft Corporation
  1079.  
  1080.