Get EMB Handle Information (Function 0Eh):
------------------------------------------

ARGS:   AH = 0Eh
DX = Extended memory block handle
RETS:   AX = 0001h if the block's information is found, 0000h
otherwise
BH = The block's lock count
BL = Number of free EMB handles in the system
DX = The block's length in K-bytes
ERRS:   BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = A2h if the handle is invalid

This function returns additional information about an extended
memoryblock to the caller.

NOTE: To get the block's base address, use Function 0Ch (Lock
Extended
Memory Block).


Reallocate Extended Memory Block (Function 0Fh):
------------------------------------------------

ARGS:   AH = 0Fh
BX = New size for the extended memory block in K-bytes
DX = Unlocked extended memory block handle to reallocate
RETS:   AX = 0001h if the block is reallocated, 0000h otherwise
ERRS:   BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = A0h if all available extended memory is allocated
BL = A1h if all available extended memory handles are in use
BL = A2h if the handle is invalid
BL = ABh if the block is locked

This function attempts to reallocate an unlocked extended memory
block
so that it becomes the newly specified size.  If the new size is
smaller
than the old block's size, all data at the upper end of the old block 
is
lost.


Request Upper Memory Block (Function 10h):
------------------------------------------

ARGS:   AH = 10h
DX = Size of requested memory block in paragraphs
RETS:   AX = 0001h if the request is granted, 0000h otherwise
BX = Segment number of the upper memory block
If the request is granted,
DX = Actual size of the allocated block in paragraphs
otherwise,
DX = Size of the largest available UMB in paragraphs
ERRS:   BL = 80h if the function is not implemented
BL = B0h if a smaller UMB is available
BL = B1h if no UMBs are available

This function attempts to allocate an upper memory block to the
caller.
If the function fails, the size of the largest free UMB is returned
in DX.

NOTE: By definition UMBs are located below the 1MB address boundary.
The A20 Line does not need to be enabled before accessing an
allocated UMB.

UMBs are paragraph aligned.

To determine the size of the largest available UMB, attempt to
allocate one with a size of FFFFh.

UMBs are unaffected by EMS calls.


Release Upper Memory Block (Function 11h):
------------------------------------------

ARGS:   AH = 11h
DX = Segment number of the upper memory block
RETS:   AX = 0001h if the block was released, 0000h otherwise
ERRS:   BL = 80h if the function is not implemented
BL = B2h if the UMB segment number is invalid

This function frees a previously allocated upper memory block.  When
an
UMB has been released, any code or data stored in it becomes invalid
and
should not be accessed.


PRIORITIZING HMA USAGE:
-----------------------

For DOS users to receive the maximum benefit from the High Memory
Area,
programs which use the HMA must store as much of their resident code
in it as
is possible.  It is very important that developers realize that the
HMA is
allocated as a single unit. 

For example, a TSR program which grabs the HMA and puts 10K of code
into
it may prevent a later TSR from putting 62K into the HMA.  Obviously, 
regular
DOS programs would have more memory available to them below the 640K
line if
the 62K TSR was moved into the HMA instead of the 10K one.

The first method for dealing with conflicts such as this is to
require 
programs which use the HMA to provide a command line option for
disabling
this feature.  It is crucial that TSRs which do not make full use of
the HMA
provide such a switch on their own command line (suggested name
"/NOHMA").

The second method for optimizing HMA usage is through the /HMAMIN=
parameter on the XMS device driver line.  The number after the
parameter
is defined to be the minimum amount of HMA space (in K-bytes) used by 
any
driver or TSR.For example, if "DEVICE=HIMEM.SYS /HMAMIN=48" is in a
user's CONFIG.SYS file, only programs which request at least 48K
would be
allowed to allocate the HMA.  This number can be adjusted either by
installation programs or by the user himself.  If this parameter is
not
specified, the default value of 0 is used causing the HMA to be
allocated
on a first come, first served basis.

Note that this problem does not impact application programs.  If the
HMA
is available when an application program starts, the application is
free to
use as much or as little of the HMA as it wants.  For this reason,
applications should pass FFFFh in DX when calling Function 01h.


HIGH MEMORY AREA RESTRICTIONS:
------------------------------

-   Far pointers to data located in the HMA cannot be passed to DOS.  
DOS
normalizes any pointer which is passed into it.  This will cause data
addresses in the HMA to be invalidated.

-   Disk I/O directly into the HMA (via DOS, INT 13h, or otherwise)
is not
recommended.

-   Programs, especially drivers and TSRs, which use the HMA *MUST*
use
as much of it as possible.  If a driver or TSR is unable to use at
least 90% of the available HMA (typically ~58K), they must provide
a command line switch for overriding HMA usage.  This will allow
the user to configure his machine for optimum use of the HMA.

-   Device drivers and TSRs cannot leave the A20 line permanently
turned
on.  Several applications rely on 1MB memory wrap and will overwrite
the
HMA if the A20 line is left enabled potentially causing a system
crash.

-   Interrupt vectors must not point into the HMA.  This is a result
of
the previous restriction.  Note that interrupt vectors can point
into    any allocated upper memory blocks however.

ERROR CODE INDEX:
-----------------

If AX=0000h when a function returns and the high bit of BL is set,

BL=80h if the function is not implemented
81h if a VDISK device is detected
82h if an A20 error occurs
8Eh if a general driver error occurs
8Fh if an unrecoverable driver error occurs
90h if the HMA does not exist
91h if the HMA is already in use
92h if DX is less than the /HMAMIN= parameter
93h if the HMA is not allocated
94h if the A20 line is still enabled
A0h if all extended memory is allocated
A1h if all available extended memory handles are in use
A2h if the handle is invalid
A3h if the SourceHandle is invalid
A4h if the SourceOffset is invalid
A5h if the DestHandle is invalid
A6h if the DestOffset is invalid
A7h if the Length is invalid
A8h if the move has an invalid overlap
A9h if a parity error occurs
AAh if the block is not locked
ABh if the block is locked
ACh if the block's lock count overflows
ADh if the lock fails
B0h if a smaller UMB is available
B1h if no UMBs are available
B2h if the UMB segment number is invalid

IMPLEMENTATION NOTES FOR DOS XMS DRIVERS:
-----------------------------------------

-   A DOS XMS driver's control function must begin with code similar
to the
following:

XMMControl  proc    far

jmp     short XCControlEntry    ; For "hookability"
nop     ; NOTE: The jump must be a short
nop     ;  jump to indicate the end of
nop     ;  any hook chain.The nop's
;  allow a far jump to be
;  patched in.
XCControlEntry:


-   XMS drivers must preserve all registers except those containing
returned values across any function call.

-   XMS drivers are required to hook INT 15h and watch for calls to
functions 87h (Block Move) and 88h (Extended Memory Available).  The
INT 15h Block Move function must be hooked so that the state of the
A20
line is preserved across the call.The INT 15h Extended Memory
Available function must be hooked to return 0h to protect the HMA.

-   In order to maintain compatibility with existing device drivers,
DOS XMS
drivers must not hook INT 15h until the first non-Version Number
call    to the control function is made.

-   XMS drivers are required to check for the presence of drivers
which
use the IBM VDISK allocation scheme.  Note that it is not sufficient
to
check for VDISK users at installation time but at the time when the
HMA
is first allocated.  If a VDISK user is detected, the HMA must not
be    allocated.Microsoft will publish a standard method for
detecting
drivers which use the VDISK allocation scheme.

-   XMS drivers which have a fixed number of extended memory handles
(most
do) should implement a command line parameter for adjusting that
number
(suggested name "/NUMHANDLES=")

-   XMS drivers should make sure that the major DOS version number
is    greater than or equal to 3 before installing themselves.

-   UMBs cannot occupy memory addresses that can be banked by EMS
4.0.
EMS 4.0 takes precedence over UMBs for physically addressable
memory.
-   All driver functions must be re-entrant.  Care should be taken to 
not
leave interrupts disabled for long periods of time.

-   Allocation of a zero length extended memory buffer is allowed. 
Programs
which hook XMS drivers may need to reserve a handle for private use
via
this method.  Programs which hook an XMS driver should pass all
requests
for zero length EMBs to the next driver in the chain.

-   Drivers should control the A20 line via an "enable count."Local
En-
able only enables the A20 line if the count is zero.  It then
increments
the count.Local Disable only disables A20 if the count is one.  It
then decrements the count.Global Enable/Disable keeps a flag which
indicates the state of A20.  They use Local Enable/Disable to
actually
change the state.

IMPLEMENTATION NOTES FOR HIMEM.SYS:
-----------------------------------

-   HIMEM.SYS currently supports true AT-compatibles, 386 AT
machines, IBM
PS/2s, AT&T 6300 Plus systems and Hewlett Packard Vectras.

-   If HIMEM finds that it cannot properly control the A20 line or if 
there
is no extended memory available when HIMEM.SYS is invoked, the driver
does not install itself.  HIMEM.SYS displays the message "High Memory
Area Unavailable" when this situation occurs.

-   If HIMEM finds that the A20 line is already enabled when it is
invoked,
it will NOT change the A20 line's state.  The assumption is that
whoever
enabled it knew what they were doing.  HIMEM.SYS displays the message 
"A20
Line Permanently Enabled" when this situation occurs.

-   HIMEM.SYS is incompatible with IBM's VDISK.SYS driver and other
drivers
which use the VDISK scheme for allocating extended memory.  However,
HIMEM does attempt to detect these drivers and will not allocate the
HMA if one is found.

-   HIMEM.SYS supports the optional "/HMAMIN=" parameter.  The valid
values
are decimal numbers between 0 and 63.

-   By default, HIMEM.SYS has 32 extended memory handles available
for use.
This number may be adjusted with the "/NUMHANDLES=" parameter.  The
maximum value for this parameter is 128 and the minimum is 0.  Each
handle currently requires 6 bytes of resident space.


Copyright (c) 1988, Microsoft Corporation

