//////////////////////////////////////////////////////////////////////////////
/                                                                            /
/               HDPMI - DPMI Server (Version 3.05)                           /
/                                                                            /
//////////////////////////////////////////////////////////////////////////////

 0. Contents

   1.    About HDPMI
   2.    Requirements
   3.    Commandline Options
   4.    Environment Settings
   5.    Returncodes and Messages
   6.    Technical Details
    6.1  Memory Management
    6.2  Interrupts
    6.3  Exceptions
    6.4  Stacks
    6.5  Client Initialization/Termination
    6.6  DPMI API
    6.7  DOS API Translation
    6.8  Other API Translation Support
    6.9  Debug Support
    6.10 Nested Execution of DPMI Clients
    6.11 Other Features of HDPMI
   7.    Restrictions of current Version
   8.    Known Problems/Hints
   9.    Compatibility List
  10.    History
  11.    Copyright


 1. About HDPMI

   HDPMI is a DPMI server which conforms to DPMI specification v0.9, but
   supports a large subset of DPMI v1.0 as well. Although it is part of
   the HX runtime, it doesn't depend on any other runtime modules and can
   be used as a standalone host.

   HDPMI exists in two versions called HDPMI16.EXE and HDPMI32.EXE. The
   first will run 16-bit DPMI clients, the latter executes 32-Bit DPMI
   clients. The HX PE binary loader DPMILD32 is aware of HDPMI and will
   try to load it silently in the background if no DPMI server is found
   in memory yet.

   A DPMI server's purpose is to run applications in protected-mode. This
   gives the following benefits compared to real-mode DOS:
   
    breaks the DOS 640 kB (conventional) memory limitation. The 80386 
     supports 4 GB memory.
    extends the 16-bit segment limit to 32-bit, which allows to forget
     all those segmented memory models and use the simple "flat" mode.
    several privilege levels which allows "user" and "system" code.
    paging.
    memory and I/O protection.
    additional exceptions.
   
   The DPMI server will have to manage all resources specific to protected
   mode (GDT, IDT, LDT, TSS, page tables, extended memory, ...). To make
   DOS and BIOS accessible it also has to provide the ability to switch
   between modes. That's why a DPMI server has to run at a high privilege
   level and cannot be launched in a "DOS box".

   Extended features of a DPMI server are:

    provide API translation services, thus allowing the application
     to use DOS Int 21h calls which use pointers, for example. HDPMI
     has such services implemented, see below.
    Support of a swapfile to increase available memory by hard disk space
     (virtual memory). HDPMI does not implement a swapfile on its own,
     but since version 3.03 it is possible for the client to do this.
    Support of multiple address spaces by the "virtual machine" concept.
     HDPMI does not support this feature, but allows to launch multiple
     instances of the server with each instance having its own address
     space.

   
 2. Requirements

   HDPMI requires the following resources to run:

    a 80386 or better cpu. If environment switch HDPMI=1 is used, at least
     a 80486 is required (see below).

    a minimum of 64 kB of extended memory for host initialization.
     By (optionally) adding conventional DOS memory to the page pool,
     HDPMI may run without any extended memory at all.

    MS-DOS 4.01+ or compatible OS. FreeDOS or DR-DOS should work as well.
   
    a XMS host if HDPMI cannot run in "raw" mode due to an unknown
     A20 gate switch mechanism.
   

 3. Commandline Options

   HDPMI accepts the following commandline options:
   
     -r: this will cause HDPMI to install permanently as a TSR. In this
         mode HDPMI will run until it is deinstalled using option -u.
         If option -r is *not* entered, HDPMI will install as a TSR as 
         well, but will terminate when the next client has terminated (*).
     -u: this switch will uninstall a running instance of HDPMI.
     -d: disable the current installed instance of HDPMI
     -e: reenable a disabled instance of HDPMI
     -m: disables support for DPMI 1.0 memory functions (AX >= 0504h).
     -l: TLB will be allocated in low DOS memory. Useful if DOS UMBs
         are slow or not accessible by DMA.
     -b: keep the TLB only when at least 1 client is running. This
         option is useful only in conjunction with -r and will result
         in conventional memory usage of just 5 kB when HDPMI is idle. But
         be aware that this constellation may not work with all clients!
     -t: don't touch NE bit in CR0. Without this option HDPMI will set
         the NE bit so floating point errors will cause an exception 0x10.
     -h: displays HDPMI version. It will not install as TSR.
   
   (*) Please note: Since HDPMI modifies some real mode interrupt vectors,
       it cannot terminate if any other application (it needn't be a
       protected mode app, a simple DOS TSR may suffice) has modified these
       vectors while HDPMI is running. In this case HDPMI has to remain
       resident in any case, regardless if a client is running or not.
       
   (*) It is possible to install both HDPMI16 and HDPMI32 permanently, but 
       for this to work it is required that HDPMI16 is installed first.
       Installing HDPMI16 permanently is the only way to run 16bit clients
       while HDPMI32 is loaded. The hosts will share one TLB, so both hosts
       will consume just about 20 kB conventional DOS memory.


 4. Environment Settings

   On startup HDPMI will search for environment variable "HDPMI". By setting
   this variable one may modify HDPMI's behaviour. It is interpreted as bit
   values, so one may set any combination of the following values:
   
   HDPMI=1:  this option makes the host aware of direct IVT access
             (read/writes to linear address range 0-3FFh) in protected mode.
             Thus it can ensure that IRQs are always handled in protected mode 
             first. If the option is set, opcode INVLPG is used, which is
             implemented on 80486 or better cpus only.
   HDPMI=2:  DOS memory is included in standard memory page pool.
             This option should be set only on machines with very
             little physical ram.
   HDPMI=4:  return 1.00 as DPMI server version. Some clients will
             refuse to work if server identifies itself as V0.90 only.
             Since HDPMI implements many DPMI V1.0 functions, such apps may
             work with this switch set.
   HDPMI=8:  allocate TLB in low DOS memory. Same effect as command line
             switch -l.
   HDPMI=16: prevents HDPMI from trying to allocate a temporary 64 kB TLB
             for DOS read/write functions which exceed the static TLB size.
   HDPMI=32: causes HDPMI to not respond to int 2Fh, ax=160Ah. This allows
             to start Windows 3.1 WIN.COM while HDPMI is loaded resident.
   HDPMI=64: don't use XMS v3+ functions. This should make HDPMI compatible
             with XMS hookers which aren't aware of XMS v3 (WSWAP.EXE). It
             will also restrict the amount of free memory the host reports.
   HDPMI=128: disable DOS API translation for LFN functions.
   HDPMI=256: when running as VCPI client, ensure that PTEs for HMA region
             (address space 100000h-10FFFFh) are set so that physical
             addresses match linear addresses. This may not work with all
             VCPI hosts.
   HDPMI=512: alloc IDT and LDT in client address space. Usually they are
             allocated in HDPMI's reserved space above linear address
             FF800000h, but some programs seem to not expect these tables
             at addresses such high. Furthermore, GDT is not moved to
             extended memory if this switch is on.
   HDPMI=1024: disables support for DPMI 1.0 memory functions (AX >= 0504h).
             Same effect as command line switch -m.
   HDPMI=2048: clear HiWord of ESI and EDI on initial switch to protected
             mode. This doesn't conform to the DPMI specs, but is required
             to make HDPMI compatible with Borlands's 32RTM.EXE when running
             on some versions of DOS.
   HDPMI=4096: don't allow client to write to GDT, IDT and LDT.


 5. Returncodes and Messages

   If HDPMI is launched by a program (because no DPMI support has been found),
   it will return with the following codes:

   rc   meaning
   ------------------------------------------------
   00   HDPMI is resident now in Int15 mode
   01   HDPMI is resident now in XMS mode
   02   HDPMI is resident now in VCPI mode
   03   DPMI server detected without VCPI support, HDPMI has terminated
        without taking over control. This state should be no error for
        the application since the DPMI API is available
   04   error: not enough memory for host initialization
   05   error: A20 cannot be enabled
   06   error: VCPI host has remapped IRQs
   07   error: CPU in V86 mode, but no VCPI or DPMI host found
   08   error: DOS version not 4.01 or later
   09   error: CPU not 80486 or better
   0A   error: invalid command line given

   If HDPMI is started with a nonempty command line, it may display 
   messages. These are:

   - "HDPMI already installed": may occur when starting HDPMI with 
     option "-r".
   - "HDPMI not installed or disabled": may occur when starting HDPMI with 
     option "-u". 
   - "HDPMI is busy": may occur when starting HDPMI with option "-u". 
     Reason: The server has at least 1 client running.
   - "HDPMI *not* uninstalled because real-mode interrupts were modified"
     may occur when starting HDPMI with option "-u". Reason: Another TSR
     has caught an interrupt which HDPMI is using as well, so it cannot
     restore the old value. Most likely this is interrupt 2Fh.
   - "no disabled instance of HDPMI found": may occur when starting HDPMI
     with option "-e". 


 6. Technical Details


 6.1 Memory Management

   a) Overview

     The memory usage of HDMI depends on the configuration found
     at startup. Possible configurations are:

      Int15 or "Raw" mode: CPU is in real-mode and no XMS host
       (HIMEM.SYS) has been found.

      XMS-Mode: CPU is in real-mode and a XMS host is running.

      VCPI-Mode: CPU is in v86-mode and a VCPI host has been detected.

      CPU is in v86-mode and no VCPI host has been found. HDPMI cannot
       enter ring 0 protected-mode and terminates without further message.


   b) Physical Memory Allocation

   Int15-Mode:  HDPMI allocates all of extended Memory by calling
                Int15, AX=E801h or, if this fails, by calling Int15, AH=88h. 
                When a real mode app is launched, half of currently unused
                extended memory is released. This is to allow
                nested execution of protected mode apps in this mode.
                When the launched app terminates, HDPMI graps this memory
                again.

   XMS-Mode:    Memory is allocated dynamically from the XMS-Host. The
                allocated memory blocks are released when the server
                terminates. If the server has been installed with option -r, 
                the XMS handles (except the first one) are released when
                the server enters idle state (no client running)

   VCPI-Mode:   If a XMS-Host is available in this mode, HDPMI prefers to 
                allocate memory through this host, because some VCPI
                aren't too fast when this function is called. So the VCPI
                memory allocation API is used only if no XMS host is found
                (which is a very rare constellation).

   If all extended memory has been allocated, HDPMI will try to use
   conventional memory if environment variable HDPMI=2 is set. So in tight
   memory conditions DOS memory may be a full part of HDPMI's memory pool.
   This is optional because there is a chance that this behaviour may cause
   problems (some clients simply allocate the largest available memory block
   as reported by the host, which will then make HDPMI to alloc all free DOS
   memory).

   c) Address Space Management

   HDPMI reserves the last 8 MB of address space for its usage (GDT, IDT,
   LDT, page tables, host code). The rest is left for the client, so 
   4088 MB address space is available in the range 0 - FF7FFFFFh. 
   Optionally HDPMI can be instructed to locate IDT and LDT in the client
   address space (see environment variable HDPMI).

   d) Virtual Memory

   HDPMI itself doesn't create a swap file. But support for "exception
   restartability" has been implemented in version 3.03. This allows a
   client to catch page faults occuring inside the host, which makes it
   possible to support swapfiles (or memory-mapped files) on the client
   level.

   e) Conventional Memory
   
   Conventional memory (address space 0-10FFFFh) is under control of DOS.
   In XMS and raw mode HDPMI will initialize the page table for this region
   so that physical memory addresses and linear memory addresses are identical. 
   For its API translation HDPMI will use a DOS memory block of 8 kB.
   Additionally some host code has to be run in real/v86-mode, and a 2 kB
   host stack also is located in conventional memory to make it accessible
   for both modes. All in all HDPMI will use about 13 kB of DOS memory.
   

 6.2 Interrupts

   According to DPMI docs a host must ensure that hardware interrupts (IRQs) 
   are routed to protected mode if they have occured in real/v86-mode.
   HDPMI fullfills this requirement, for this it intercepts the real-mode
   IVT vectors of all IRQs. Routing the IRQs to protected mode, however,
   is done only if a client has changed the protected-mode interrupt vector.

   There exist some DPMI clients which get in the way, however. Most 
   likely this is because some hosts had difficulties with the IRQ
   routing to protected-mode. So these clients try to do this routing
   on their own - which may cause problems with HDPMI. For this reason,
   HDPMI has an option to catch all direct accesses to the IVT in protected
   mode. This option is activated by setting environment variable "HDPMI=1".
   This will slow down any access to page 0, however, so it should be set only
   if it becomes obvious that the client will need it to run.

   Besides the hardware interrupts there are 3 software interrupts which
   will be routed to protected-mode as well: Int 1Ch, Int 23h and Int 24h.
   

 6.3 Exceptions
 
   If an exception occurs and the client hasn't installed an exception
   handler (or if it decides to not handle the exception), HDPMI's default
   exception handler will get the exception and will do:
   
   Exc    Action
   ----------------------------------------------------------------
   00-05  exception is routed to protected-mode INT 00-05.
   06     client is terminated.
   07     exception is routed to protected-mode INT 07.
   08-0E  client is terminated.
   10     client is terminated.

   The default handler for protected-mode interrupts 00-07 will do:
   
   Int    Action
   ----------------------------------------------------------------
   00     client is terminated.
   01-04  interrupt is routed to real-mode.
   05     interrupt is routed to real-mode if it is a programmed INT, else
          client is terminated.
   06     interrupt is routed to real-mode.
   07     client is terminated.
   
   In other words, exceptions 00 and 05-07 will not arrive in real-mode.
   This is not what DPMI docs are telling, but it wouldn't make sense,
   since these exceptions are faults and the exception cause must be cured
   to continue execution. This can't be done by a real-mode interrupt handler.
   
   If a client is terminated, a register dump is displayed and HDPMI will
   ask whether to terminate the client or the server. The first option
   will execute an int 21h, ax=4CFFh in ring 3 protected mode, which gives
   the client a chance to clean up things. This usually works better than 
   trying to terminate the server, which may result in DOS memory blocks
   not being freed and/or IVT vectors not being restored.

 
 6.4 Stacks

   When a client is running the host will switch among 4 stacks:

    the protected mode stack (PMS), which is the stack the DPMI
     client uses. It can switch these stacks as it likes and there
     are no special requirements about it.

    the locked protected mode stack (LPMS). The DPMI host switches
     the client application to this stack when
     - a hardware interrupt (IRQ) has occured
     - an interrupt is reflected from real mode (mostly IRQs, but
       also software interrupts 1Ch, 23h and 24h.
     - the DPMI client executes a real mode callback
     - the server notifies the client about an exception
     There exists 1 LPMS only and its size must be at least 4 KB.
     Once it is "in use" the host will no longer switch stacks until
     the LPMS is free again.

    the real mode stack (RMS). Usually this stack is located in the
     memory block the DPMI client has to deliver to the server on its
     initial switch to protected mode. This stack's size will be at
     least 200h bytes. It is used when there is a reflection from protected
     mode interrupts to real mode. If protected-mode is reentered (by a
     real-mode callback, a raw jump or a harware IRQ), the RMS is in use
     and HDPMI will then use the real mode SS:SP of the last entry to
     protected mode as current real-mode stack.

    the ring 0 stack. This stack is invisible to the client, it is
     used by the dpmi host. For HDPMI this stack is 2 kB in size, and
     it is located in conventional memory. The host uses this stack
     for it's normal processing and to save the client's segment register
     values.


 6.5 Client Initialization/Termination
 
   Clients running on the same instance of HDPMI will share address space,
   IDT and LDT. On client initialization HDPMI will do:
   
   - save the current IDT
   - save the current LDT
   - save other client resources, among which are
     + real-mode callbacks
     + ring 3 interrupt vectors
     + ring 3 exception vectors
   
   These resources are saved, but not initialized, that is, a new client
   will inherit the state of the previous client.
   
   On client termination, HDPMI will do:

   - free memory handles the client has allocated
   - restore the IDT to the previous state
   - restore the LDT to the previous state
   - restore other resources to the previous state

   So there is no need for a client to free memory or LDT selectors before
   terminating. Conventional DOS memory blocks and file handles will be 
   released by DOS, but any real-mode interrupt vectors which were modified
   must be restored by the client.
   
 
 6.6 DPMI API

   HDPMI fully supports DPMI version 0.9.

   Additionally, the following DPMI v1.0 features are supported:

   Int AX    comment
   -----------------------------------------------------------------
   2F  168A  get vendor-specific API entry point
   31  000E  get multiple descriptors
   31  000F  set multiple descriptors
   31  0210  get protected-mode extended exception handler
   31  0212  set protected-mode extended exception handler
   31  0401  get DPMI capabilities, Vendor is "HDPMI". This is the
             recommended way to detect that HDPMI is present.
  *31  0504  allocate linear memory block
  *31  0505  resize linear memory block
  *31  0506  get page attributes
  *31  0507  modify page attributes
  *31  0508  map device in memory block
  *31  0509  map conventional memory in memory block
  *31  050A  get memory block size and base
  *31  050B  get memory information
   31  0801  unmap physical region
   31  0E00  get coprocessor status
   31  0E01  set coprocessor emulation

  * support for these functions can be disabled by commandline parameter
    or setting environment variable HDPMI.

   So most DPMI V1.0 features are implemented, what's missing are:
   
   - 0211h + 0213h, get/set handler for real-mode exceptions
   - 0C00h + 0C01h, DPMI TSRs
   - 0D00h - 0D03h, shared memory

   Additionally, some privileged opcodes are emulated:
   
   - HLT (F4) 
   - MOV reg,CRx (0F 20 xx) - using ESP for <reg> will not work!
   - MOV CRx,reg (0F 22 xx) - using ESP for <reg> will not work!


 6.7 DOS API Translation

   HDPMI supports DOS-API translation, both in 16-bit mode and in
   32-bit mode. For translation purposes, HDPMI allocates a static
   translation buffer of 8 KB. For the important read/write functions
   HDPMI will try to allocate a temporary 64k buffer, if the size of
   the i/o-operation exceeds the size of the static translation buffer.

   Supported DOS extended INT 21h functions in detail:

    AH  Comment  
    -----------------------------------------------------------
    00  close current PSP without terminating client
    09  Write String DS:E/DX to Standard Output
    0A  Buffered Input into DS:E/DX
    0C  AL=0A, Flush Buffer and read Standard Input into DS:E/DX
    11  Find First File using FCB in DS:E/DX
    12  Find Next File using FCB in DS:E/DX
    13  Delete File using FCB in DS:E/DX
    1A  Set Disk Transfer Area to DS:E/DX
    1B  Get Allocation Information for Default Drive in DS:E/BX
    1C  Get Allocation Information for Specific Drive in DS:E/BX
    1F  Get Drive Parameter Block for Default Drive in DS:E/BX
    25  Set Interrupt Vector in DS:E/DX
    29  Parse Filename in DS:E/SI into FCB in ES:E/DI
    2F  Get Disk Transfer Area in ES:E/BX
    32  Get Drive Parameter Block for Specific Drive in DS:E/BX
    34  Get Address of InDOS Flag in ES:E/BX
    35  Get Interrupt Vector in ES:E/BX
    38  DX!=FFFF, Get Country-Specific Information in DS:E/DX
    39  Create Subdirectory DS:E/DX
    3A  Remove Subdirectory DS:E/DX
    3B  Set Directory DS:E/DX
    3C  Create File DS:E/DX 
    3D  Open File DS:E/DX
    3F  Read E/CX bytes from File to DS:E/DX
    40  Write E/CX bytes from DS:E/DX to File 
    41  Delete File DS:E/DX
    43  Get/Set File DS:E/DX Attributes
    44  AL=02 Read from Char Device Control Channel into buffer DS:E/DX
    44  AL=03 Write to Char Device Control Channel from buffer DS:E/DX
    44  AL=04 Read from Block Device Control Channel into buffer DS:E/DX
    44  AL=05 Write to Block Device Control Channel from buffer DS:E/DX
    44  AL=0D Generic Block Device Request, parameter block in DS:E/DX
    47  Get Directory Path into DS:E/SI
    48  Allocate Memory Block E/BX paragraphs
    49  Free Memory Block in ES
    4A  Resize Memory Block ES, new size in E/BX
    4B  AL=00 - Load and Execute Program DS:E/DX, exec parm ES:E/BX
    4C  terminate client
    4E  Search for First Filename Match, DS:E/DX=file spec
    50  Set current PSP to BX (selector)
    51  Get current PSP in BX (selector)
    52  Get List of Lists in ES:E/BX
    53  Translate BPB in DS:E/SI to DPB in ES:E/BP
    55  Create Child PSP from DX (selector)
    56  Rename File DS:E/DX to ES:E/DI
    5A  Create temporary File DS:E/DX 
    5B  Create new File DS:E/DX 
    5D  AL=06 Get Address of DOS Swappable Data Area in DS:E/SI
    5D  AL=0A Set extended error information from DS:E/DX
    5E  AL=00 Get Machine Name into DS:E/DX
    60  Canonicalize Filename or Path in DS:E/SI to ES:E/DI
    62  Get current PSP in BX (selector)
    63  AL=00 Get DBCS table in DS:E/SI
    65  AL=00 Set extended Country Information from ES:E/DI
    65  AL=01-07 Get extended Country Information into ES:E/DI
    65  AL=21|22|A1|A2 capitalize string in DS:E/DX
    69  Get/Set disk serial number in DS:E/DX 
    6C  Extended Open/Create, file name in DS:E/SI 
   *71  AL=39|3A|3B LFN subdirectory functions DS:E/DX
   *71  AL=41 LFN delete file DS:E/DX
   *71  AL=43 LFN get/set file attributes DS:E/DX
   *71  AL=47 LFN get current directory DS:E/SI
   *71  AL=4E LFN get first file DS:E/DX into ES:E/DI
   *71  AL=4F LFN get next file into ES:E/DI
   *71  AL=56 LFN rename file DS:E/DX to ES:E/DI
   *71  AL=60 LFN get canonical/short/long path DS:E/SI to ES:E/DI
   *71  AL=6C LFN open file DS:E/SI
   *71  AL=A0 LFN get volume info DS:E/DX, return file sys into ES:E/DI
   *71  AL=A6 LFN get file info by handle into DS:E/DX
   *71  AL=A7 LFN filetime DS:E/SI to dostime - dostime to filetime ES:E/DI
   *71  AL=A8 LFN generate short filename from DS:E/SI to ES:E/DI 
   *71  AL=AA LFN create SUBST DS:E/DX, query SUBST DS:E/DX
    73  AL=02 Get extended DPB into ES:E/DI
    73  AL=03 Get extended free space into ES:E/DI
    73  AL=04 Set DPB for formatting in ES:E/DI
    73  AL=05 Extended absolute disk read/write with params in DS:E/BX

   * LFN (AH=71h) API translation only works if LFN is installed in 
     real-mode DOS. Usually this requires a driver to be installed (DOSLFN).


 6.8 Other API Translation Support

   Int Function Comment
   ---------------------------------------------------------------------
   10  ax=1002h set all palette registers ES:E/DX
   10  ax=1009h get all palette registers ES:E/DX
   10  ax=1012h set DAC registers ES:E/DX
   10  ax=1017h get DAC registers ES:E/DX
   13  ah=02h   disk read into buffer ES:E/BX
   13  ah=03h   disk write from buffer ES:E/BX
   13  ah=08h   for FD return drive parameter table in ES:E/DI
   15  ah=C0h   read configuration into ES:E/BX
   15  ax=C207h set pointing device event proc ES:E/BX
   25           absolute disk read buffer in DS:E/BX
   26           absolute disk write buffer in DS:E/BX
   2F  ax=168Ah supports vendor "MS-DOS" and "VIRTUAL SUPPORT" 
                callback for "MS-DOS" supports function 100h (LDT sel)
   33  ax=0009h define graphics cursor ES:E/DX
   33  ax=000Ch define interrupt subroutine ES:E/DX
   33  ax=0012h define large graphics cursor ES:E/DX
   33  ax=0014h exchange interrupt subroutine ES:E/DX
   33  ax=0016h save driver state ES:E/DX
   33  ax=0017h restore driver state ES:E/DX
   33  ax=0018h set alternate mouse user handler ES:E/DX


 6.9 Debug Support

   a) Support in Protected Mode

   HDPMI supports Int 41h processing in protected mode. HDPMI provides
   that ring 0 Int 41h calls are not reflected in ring 3. HDPMI also
   provides for no Int 41h call be reflected to real mode.

   HDPMI itself issues three Int 41h calls, all in ring 0 (and therefore
   only of use for kernel debuggers):

     - on initialization of the server
     - a breakpoint if a new DPMI clients starts
     - on termination of the server
     
   Furthermore, there are enough free entries left in the GDT to allow
   HDPMI itself being debugged by Qualitas' debugger 386SWAT. Requires
   GDT in extended memory, so switch HDPMI=512 must not be set for this
   to work.
   

   b) Support in Real Mode

   Kernel debuggers such as WDEB386.EXE start in real mode and before any
   DPMI server is active. That's why they need some support from the
   DPMI server to get a chance to do their protected mode initialization,
   (to modify IDT vectors they want to hook or set GDT descriptors).
   For this reason HDPMI supports WDEB386's real-mode Int 68h API.

   c) Other Debug Support

   - great care has been taken to not loose the trace flag during mode
     switches. The switch from real mode to protected mode has been
     made "debug aware", so that there is no risk a debugger traces into
     nontracable code, thereby crashing the system.

   - if HDPMI detects a kernel debugger, its output is send to the debugger.
     If an exception occurs, the debugger will be notified as well,
     giving it a chance to stop execution.


 6.10 Nested Execution of several DPMI Clients

   As already mentioned, if two or more clients share one instance of
   HDPMI, they have to share address space, IDT and LDT. For most clients
   this is no problem at all. But on certain conditions it may be necessary
   to not share these resources among clients. HDPMI does not support 
   the DPMI V1.0 "Virtual Machine" concept, but it is possible to start
   several instances of HDPMI. Such instances will only share DOS specific
   resources (address space 0-10FFFFh, files, IVT vectors) and (physical)
   extended memory. 


 6.11 Other Features of HDPMI
   
    in protected mode Clients run in CPL 3, IOPL is 3, so instructions
     like STI, CLI, PUSHF(D), POPF(D), IN or OUT are executed in real time.
    during ring 0 processing NMIs are ignored.
    HDPMI's ring 0 ESP will always have its hiword cleared. This is because
     of a design weakness in Intel CPUs, which don't touch the Hiword of ESP
     on a switch to a lower privilege level if the D bit of the destination
     ring SS descriptor is not set (16-bit stack). Some 32-bit DPMI clients 
     which (temporarily) use a 16-bit stack aren't aware of this potential
     problem, among these are apps written with the DOS4G extender.


 7. Restrictions of current Version

   If no XMS host is found, HDPMI must switch the A20 gate on its own. Only
    standard AT (keyboard controller) and PS/2 (bit 1 of port 92h) methods
    are supported. The gate is enabled once on server initialization.
   A client can allocate up to 16 real-mode callbacks. 
   Int 25h/26h (and Int 21h, ax=7305h for FAT32) translation services:
    the amount of bytes to read/write per call is limited to the size of
    the static translation buffer, which is 8 kB.
   There is no code in HDPMI to detect exceptions 11h-1Fh. This may be
    a problem if the alignment check has been activated on 80585+ cpus.
    If an exception 11h occurs it will most likely terminate the client
    and/or server.


 8. Known Problems / Hints
 
   Some versions of DOS4G/W require environment variable HDPMI=1 to be
    set. Generally, setting this option should be the first thing to do
    if a client doesn't run with HDPMI.

   Some programs don't expect system tables (GDT, IDT, LDT) being located
    at very high linear addresses, as it is the case with HDPMI by default.
    To make HDPMI compatible with such programs, environment variable
    HDPMI=512 has to be set before HDPMI is loaded. The SoundBlaster 16
    emulation for SB-PCI or SB-Live sound cards (SBINIT.COM/SBEINIT.COM)
    may belong to these kind of programs. 

   Some clients may require to disable HDPMI's support for DPMI V1.0
    memory functions (apps built with DJGPP v2, for example, because of
    the NULL pointer protection problem). This can be achieved by starting
    HDPMI with parameter -m or by setting environment switch HDPMI=1024.
                      
   Some combinations of DOS, HDPMI32 and Borland's 32RTM.EXE will only
    work with environment switch HDPMI=2048. This is due to a bug in
    32RTM.EXE.
                      
   Some clients are incompatible with HDPMI if it hasn't been installed
    with option -r. Usually this is because they try to restore real-mode
    interrupt vector 2Fh too late (after HDPMI has done its cleanup).
    PMODE/W and DOS32A applications may belong to these type of programs.
    [PMODE/W apps will only use HDPMI if they are setup (with tool PMWSETUP)
    to prefer DPMI over VCPI.]
  
   To run a 16-bit client while HDPMI32 is installed requires to install
    HDPMI16 before HDPMI32. The best thing to do if both types of clients
    are to be executed is to run first HDPMI16, then HDPMI32, both with
    option -r.

   Some DPMI clients refuse to run if amount of free memory is too *large*
    (for example the game 'System Shock'). The HX runtime contains a 
    DPMI test program called DPMI.EXE, which can be used to reduce the
    amount of memory the host reports. It should work with any host. Start
    DPMI.EXE with option -? to see how this can be done.
  
   If the machine reboots on certain actions it's not unlikely that this
    is due to a real-mode stack overflow. What sometimes may help then is:
    - set STACKS=9,512 in CONFIG.SYS (may introduce new problems though)
    - try to load another mouse/network/sound driver

  
 9. Compatibility List

   the following applications/DOS extenders are verified to run with HDPMI:

   - DOS4/GW Rational/Tenberry DOS extender applications
   - PMODE/W DOS extender applications
   - CauseWay DOS extender applications
   - DOS/32 Advanced DOS extender applications
   - Borland 16-Bit/32-Bit (Powerpak) DPMI applications
   - WDOSX extender applications 
   - RSX DOS extender applications 
   - RAW32 extender applications
   - Pharlab TNT DOS extender applications (i.e. MS VC 1.52)
   - DJGPP applications.
   - MS Windows 3.1 (standard mode)
   - MS Windows for Workgroups 3.11 (standard mode)
   - MS DOSX16/DOSX32 applications (Codeview for DOS, MS C++ 7.0)
   - MicroFocus COBOL applications (16 and 32 bit)
   - kernel debugger WDEB386.EXE/WDEB98.EXE/DEBUGGER.EXE

   HDPMI itself has been tested to run under the following emulators:
   
   - Bochs
   - Qemu
   - VMWare
   - DosBox

   HDPMI has also been tested to run with the following VCPI hosts:

   - MS-DOS Emm386 (V7.x, V6.x, V5.0)
   - FreeDOS Emm386 (V2.0x)
   - Quarterdeck Qemm386 (V6, V8, V9)
   - Qualitas 386Max (V6.02, V7.02)


 10. History

  15.05.2006, version 3.05

   bugfix: int 31h, ax=0101h may have caused an exception if selector of  
    memory block to free was contained in DS.
   bugfix: in previous versions the real-mode DTA was set permanently to the
    hosts's PSP+80h. This apparently was a problem for some clients not using
    the host's DOS translation services (F-PROT.EXE).
   bugfix: if int 31h, ax=101h|102h did not fail it still returned with a
    modified AX register
   bugfix: int 21h, AH=4Ah returned with modified AX register.
   bugfix: int 31h, AX=050Bh returned 0 in "maximum locked bytes" field. Now
    the "free" bytes are returned.
   bugfix: int 31h, ax=0507h didn't work with ECX=0 in versions 3.02-3.04
    (32RTM.EXE does such a call and expects it to succeed)
   bugfix: cmdline option -u didn't work if environment variable HDPMI=1
    was set and HDPMI run as VCPI client.
   bugfix: raw mode switch to protected mode may have enabled interrupts
    one instruction too early, which caused a GPF if a IRQ occured.
   CR4 now displayed by default exception handler
   default exception handler no longer makes assumptions about value of SS
    if an exception occured in ring 0.
   some free entries in GDT added which is required by 386SWAT to debug
    VCPI clients.
  
  02.05.2006, version 3.04
  
   bugfix: in Int15/raw mode only part of physical memory was used
   bugfix: HDPMI installed with option -r and DOS memory included in
    page pool (HDPMI=2) didn't work reliably.
   bugfix: translation for Int 33h, ax=0016h (save driver state) didn't
    work.
   bugfix: freeing a real-mode callback which was already free didn't
    set the carry flag.
   bugfix: total physical memory reported by Int 31h, ax=0500h was too low
    after more than 1 XMS memory block was allocated.
   bugfix: free pages reported  by Int 31h, ax=0500h now are the true
    free physical pages. Previously it was just the same value as in field
    "max unlocked page allocation". 
   XMS memory handles (except the first one) now released if a resident
    installed HDPMI enters idle state (no client running).
   CR0 no longer saved/restored when a client starts/exits, just the
    FPU bits are maintained on the client level (to support Int 31h, 
    ax=0E0xh). CR0 MP bit is no longer reset on initialization. 
    Meaning of cmdLine option -t changed to "don't touch NE bit", 
    previously it was "do reset NE bit".
   in Int 31h, ax=0500h VCPI host was called if no free XMS pages exist
    anymore. This is a problem with at least one popular VCPI host and
    should therefore be avoided.
   now flags are saved/restored in Int 15h/2Fh real-mode hook procs
   new value for environment variable HDPMI:
    4096: make pages for GDT, IDT, LDT readonly
    
  21.04.2006, version 3.03

   bugfix: in V3.02 API translation Int 21h ah=29h didn't work for 16-bit
    clients.
   bugfix: in V3.02 routing interrupts 78h - FFh to real-mode didn't work
   bugfix: client initialization errors (out of memory or selectors) 
    may have left the system unstable.
   bugfix: low memory conditions on host initialization may have left the
    system unstable.
   in previous versions HDPMI needed some pages to be temporarily mapped
    in page table 0 on startup, which may cause a problem in VCPI mode
    if there are no free PTEs left. Now this temporary mapping is no longer 
    needed.
   command line option -b added to further reduce DOS memory usage.
   missing LFN translations (ax=71A7h, 71A8h and 71AAh) added.
   DPMI v1.0 functions to get/set multiple descriptors (int 31h, 
    ax=000Eh/000Fh) implemented
   DPMI v1.0 functions to get/set exception handlers for protected-mode
    (int 31h, ax=0210h/0212h) implemented
   DPMI v1.0 "exception restartability" supported.
  
  12.04.2006, version 3.02

   bugfix: internal function to alloc XMS memory was unable to detect
    a XMS host failure in V3.01.
   bugfix: change in V1.87 caused the critical error interrupt (INT 24h)
    to not work reliably.
   bugfix: resize linear memory block (Int 31h, ax=0505h) did always
    commit the added pages (ignored bit 0 of edx).
   GDT now moved to extended memory (unless switch HDPMI=512 is set).
   rest of missing DPMI v1.0 memory functions implemented:
    ax=505h: segment descriptor update now supported
    ax=508h: map device in memory block
    ax=509h: map conventional memory in memory block
    ax=50Ah: get memory block size and base
    ax=50Bh: get memory information
   API translation Int 33h, ax=0016h and ax=0017h wasn't documented.
   new value for environment variable HDPMI:
    2048: clear hiword of ESI/EDI on client's initial switch to protected
          mode.
  
  07.04.2006, version 3.01
  
   bugfix: int 21h, ah=4F (find next file) in v3.0 may have caused
    data corruption.
   some more data moved into extended memory to free conventional DOS
    memory.
   new value for environment variable HDPMI:
    1024: disable support for DPMI v1.0 memory functions
    
  04.04.2006, version 3.0
  
   HDPMI32 and HDPMI16 will share a TLB, which reduces conventional
    memory consumption by 8 kB if both hosts are loaded residently.
   host code running in protected mode moved to extended memory.
    This reduces HDPMI's conventional DOS memory usage from about
    32 kB to 14-15 kB (including a 8 kB TLB).
   host protected-mode code now runs in a 32-bit code segment.
   use VCPI memory allocation if no XMS host found.
   new values for environment variable HDPMI:
    128: disable LFN API translation
    256: enable HMA mapping in protected mode if HDPMI runs as VCPI client
    512: allocate IDT and LDT in client address space (SBPCI problem)
    
  21.03.2006, version 2.07
  
   bugfix: internal function to call a real-mode interrupt cleared
    the carry flag before calling the INT. This caused troubles with
    LFN functions on MS-DOS < 7 and DR-DOS.
   bugfix: trying to terminate a client if Ctrl-Alt-Del was pressed
    didn't work for HDPMI16.
  
  20.03.2006, version 2.06
  
   Exception 05 is no longer routed to real-mode. It is still routed
    to protected mode Int 05, though. To real-mode is will only be routed
    if it is a programmed INT 05, else the client will be terminated.
   bugfix: default exception handler didn't display a register dump.
   small code size reduction.
    
  18.03.2006, version 2.05
  
   bugfix: strings displayed with int 21h, ah=9 weren't checked if their
    size exceeds size of TLB.
   debug exceptions now detected by examining DR6, not by content
    of cs:eip or trace flag.
   added a test in raw mode if size of extended memory between 1 MB and 16 MB
    as returned by Int 15h, ax=e801, does not exceed 15360. Else this function
    is regarded as 'not implemented' (required for DosBox in raw mode).
   test if vector is 0000:0000 before calling Int 68h in real-mode.
    This makes HDPMI compatible with DosBox (tested with DosBox V0.63).
   bugfix: int 31h, ax=090xh didn't work in HDPMI16.
   int 31h entry in IDT now directly jumps into the host's int 31h
    handler, which improves this int's speed (especially useful for virtual
    interrupt functions, which are now 4 times faster than before). 
  
  06.02.2006, version 2.04
  
   HDPMI16 and HDPMI32 now both may be installed resident concurrently.
   ES, FS and GS selectors caches now updated after int 31h, ax=000Ch
    has modified a descriptor.
  
  22.01.2006, version 2.03

   check if VCPI host has remapped PICs. Exit with error 6 if this
    is true.
   supply some extra bytes of stack space to make HDPMI run
    with QEMM V8+V9 VCPI hosts.
    
  29.12.2005, version 2.02 

   bugfix: freeing memory (int 31h, ax=502h) or setting page
    attributes (int 31h, ax=506h) did not invalidate the TLB
    entries. This may have caused problems on some conditions.
    
  18.11.2005, version 2.01

   small size reduction
    
  30.10.2005, version 2.00
 
   default exception handler now sends an EOI to slave PIC if
    any interrupt is in service.
    
  15.10.2005, version 1.99
 
   default exception handler now sends an EOI to master PIC if
    any interrupt is in service.
    
  27.09.2005, version 1.98
 
   functions int 31h, ax=506h and ax=507h now accept ecx=0
    (number of pages) to make 32rtm.exe not complain about
    insufficient extended memory.
   bugfix: versions 1.89-1.97 of HDPMI32.EXE may have caused
    a stack exception on 80386 + 80486 cpus when client has
    just switched to protected mode. HDPMI32 used a 16-bit
    IRET to return to the client, but this may have trashed
    hiword of ESP.
              
  16.09.2005, version 1.97
 
   if HDPMI is resident real-mode vectors are now restored after last client
    has terminated. Previously it was done when HDPMI was uninstalled.
   new switch HDPMI=64 implemented.
   bugfix: Unsupp\HDPMI16.EXE had a bug in int 2Fh, ax=1684h
    making it unable to run windows 3.1.
   bugfix: if int 31h, ax=504h, ebx=0 failed it returned with modified EBX.
   bugfix: using DOS memory for the page pool (HDPMI=2) didn't
    take into account a bug in many DOS versions where a failed
    call to resize a memory block made this block as large as possible.
   bugfix: allocating linear memory with int 31h, ax=504h, ebx!=0
    may have failed, but Carry flag wasn't set. This occured if a
    memory block was allocated previously with a higher linear address.
              
  06.09.2005, version 1.96
 
   exc 09 checks disabled if cpu is 80486+.
  
  18.08.2005, version 1.95
 
   flag for RMS usage implemented. This allows in raw jump to
    protected mode to not touch current RMS if it is not in use.
    (the win9x dpmi host has problems with this constellation).
              
  13.08.2005, version 1.94
 
   bugfix: a mode switch may have changed values of the FPU emulation bits
    in CR0. Now all bits of CR0 except PE and PG are copied between modes.
   translation for int 21h, ah=69h added. Previously calling this function
    failed with an error message displayed.
              
  30.07.2005, version 1.93
 
   mov CRx,reg now emulated. This feature (mov CR0, reg) is required by
    some clients (MS C v7.0 [16-bit]).
   XMS handles are now released after HDPMI has finally switched to
    real-mode. The previous behaviour seemed to cause problems with
    Bochs/Qemu running HDPMI.
   documentation of HDPMI error codes 8 and 9 was wrong
   new switch HDPMI=32 implemented
   bugfix: environment switch HDPMI=16 didn't work
   owner psp of dyn TLB memory block set to psp of current client. This
    may avoid memory leaks if Ctrl-C is pressed while reading the console
    with int 21h, ah=3Fh.
   previous versions of the 16-bit host HDPMI16 used 286-interrupt gates
    to switch from ring-3 to ring-0 protected mode, thus loosing HIWORD of
    the client's ESP. Now such transfers are done thru 386-interrupt gates
    and the client's ESP remains untouched. This finally makes IR41.DLL 
    (16-bit Intel Indeo video codec for Windows 3.1) work with HDPMI16.
              
  20.07.2005, version 1.92
 
   bugfix: HDPMI may have frozen the machine on initialization
    errors (low memory)
   bugfix: in raw mode switch 'real-mode to protected mode' now the
    real-mode ss:sp is stored as current real-mode stack, because
    the previous stack cannot be used anymore, it is "busy".
   bugfix: int 31h, ax=0401h didn't return the correct host
    minor version number.
   bugfix: translation of int 25h/26 (absolute disk read/write)
    may have overwritten 2 bytes in the host's code segment.
   bugfix: dpmi functions int 31h, ax=0301h/0302h didn't work
    in version 1.91 if stack parameters had to be copied.
   new environment flag HDPMI=16, which prevents HDPMI from
    using a 64 kB dynamic TLB.
              
  15.07.2005, version 1.91
 
   bugfix: when shutting down HDPMI marked PTEs as notpresent
    which were owned by VCPI host. This caused 386MAX and FreeDOS
    EMM386 to crash.
   bugfix: uninstalling a resident instance of HDPMI (option -u)
    may have overwritten dos memory due to the usage of a real-mode
    stack which was no longer valid.
              
  10.07.2005, version 1.90
 
   bugfix: now *all* files are closed before going resident.
    Previously files 0-2 were left open, which may have been a
    problem if they have been redirected.
   int 21h API translator didn't set Carry flag before calling
    real-mode dos int 21h (HDPMI32 with LFN support only). This
    caused problems with DR-DOS.
              
  04.07.2005, version 1.89
 
   code modified to use a static task state buffer, which
    simplified the raw mode switching code.
   bugfix: raw mode switch to real-mode didn't clear FS and GS
   display of open real-mode callbacks in default exception
    handler rearranged.
   bugfix: int 31h, ax=0300h, 0301h, 0302h didn't save/restore
    client's real-mode segments. So the values in the RMCS became
    the client's new real-mode segments.
   standard real-mode callbacks (used for IRQs, int 1Ch, 23h, 24h)
    did save real-mode segment registers on the real-mode stack, but
    didn't update the client state. So if the dpmi client called
    a real-mode proc from inside the callback, it didn't get
    the true client real-mode segments. Don't know if this could
    be a problem, but other hosts don't behave this way, so it
    has been changed.
   some small changes to reduce size of binary
  
  22.06.2005, version 1.88
 
   bugfix: initialization errors caused garbage to be displayed
   bugfix: making HDPMI stay resident using both options -R + -L
    was hazardous
   default exception handler code partly rewritten so it becomes
    readable again.
              
  12.06.2005, version 1.87
 
   CR0 NE bit now is set as default. Makes command line option -n
    superfluous. New command line option -t will reset CR0 NE bit
    instead.
   execute FNINIT in default exception 10h handler. 
   bugfix: an int 10h handler may have been called as if an
    exception 10h had occured, that is, onto the locked stack.
              
  17.05.2005, version 1.86
 
   "mov reg,crX" is fully emulated now (opcode 0F 20 xx), except reg == ESP.              
   clear TS bit in CR0 on startup.
   translation of int 21h, ah=38h now documented
  
  14.05.2005, version 1.85
 
   bugfix: default exception handler may have ignored key strokes
   emulation of "mov eax,cr0" and "mov eax,cr2" reactivated
  
  13.12.2004, version 1.84
 
   translation for int 21h, ax=71A0h added
   exception 07 default handler now routes exception to protected
    mode int 07. It is not routed to real-mode, though.
   command line switches -d and -e added
   command line switch -l (=enviroment switch HDPMI=8) added
   dos memory functions now return error codes 8011h and 8022h
   dos memory alloc for 16-bit: selector tiling modified to
    exactly match dpmi specs
   internal: task state restored before server terminates
  
  01.12.2004, version 1.83
 
   switched to Digital Mars C++ linker to reduce size of HDPMI
   DR7 now cleared on client termination as specified in DPMI V1.0
   bugfix: special registers DR7 and CR0 are no longer accessed in
    V86 mode when HDPMI terminates (VCPI mode only).
   bugfix: a GPF occured if client exited int 23h with RETF
    instead of RETF 4
   CR0 MP flag now saved and restored as are EM + NE
   command line switch -n added
   locked protected mode stack selector now in LDT. Required
    by WIN87EM.DLL of windows 3.1 which tries to create a code
    alias for LPMS selector (found in Netscape 4.08).
   bugfix: int 15h mouse event proc had wrong stack parameters
   bugfix: int 33h mouse event proc caused GPF on RETF
  
  24.11.2004, version 1.82
 
   bugfix: TF was lost when save/restore task state was called in real mode
   translation for int 21h, ax=6521h, 6522h, 65A1h, 65A2h added
   translation for int 21h, ax=5D0Ah added (set ext error info)
   bugfix: exc 0D with EIP > limit(CS) caused an exc 0D in ring 0
  
  07.11.2004, version 1.81
 
   bugfix: int 21h, ax=440Dh, minor codes 40h,41h,61h did use
    ds:dx for 32bit clients, not ds:edx
              
  10.10.2004, version 1.80
 
   bugfix: address space allocation may not have worked in all
    cases if HDPMI was installed with option -r (resident)
   bugfix: pressing Ctrl-C during console read may have caused
    a fatal dos memory error (asw.exe).
              
  02.10.2004, version 1.79
 
   bugfix: function 0503h may have modified ES register
  
  25.09.2004, version 1.78
 
   new command line switch -m to disable DPMI 1.0 memory functions
   function 401h, AX now has WRITE-PROTECT CLIENT bit set.
   bugfix: function 0401h modified E/DI.
  
  17.09.2004, version 1.77
 
   API translation for int 21h, ax=71A6 added (LFN version only)
   bugfix: there was still a problem with releasing XMS memory,
    though it worked better than in v1.75
              
  12.09.2004, version 1.76
 
   bugfix: HDPMI v1.75 crashed on exit if more than 1 XMS handle
    had to be released. 
              
  11.09.2004, version 1.75
 
   bugfix: int 23h/24h traps did work for 1. client only 
   command line switches -r and -u added, to install/uninstall
    HDPMI as a TSR.
   bugfix: int 31h, ax=507h may have caused memory leaks
   DOS API translation AX=6300 added (get DBCS table)
  
  29.08.2004, version 1.74
 
   unsupported version with LFN API translation released
  
  10.06.2004, version 1.73
 
   client CS:EIP stored on top of locked protected-mode stack
   HLT now executed, not simulated
  
  05.06.2004, version 1.72
 
   bugfix: int 21h, ah=49h: if memory to free was in conv. memory,
    ES may have been released even if dos function failed.
   function 0503h no longer fails if a block which contains
    uncommitted pages has to be moved
   bugfix: function 0503h (resize memory) has lost HIWORD
    of EBX in some cases.
   bugfix: exception 01 handler wasn't called if TF wasn't set,
    i.e. cleared by an IRET. INT 01 handler was called in any case.
   bugfix: redirection IRQs from real-mode to protected-mode
    didn't work properly
   bugfix: dos api translation AH=65h, AL>0 now works
   terminating client after an exception now uses LPMS
   waiting for a keystroke after exception dump now works better
   bugfix: failure of phys address mapping didn't set carry flag
  
  12.05.2004, version 1.71
 
   bugfix: HDPMI v1.70 didn't work with VCPI!
   bugfix: TLB cache is now cleared after system tables have
    been moved high. Because of this bug HDPMI versions 1.62-1.70 
    may not run in non-VCPI modes on 80486 and 80586 cpus.
   (re)set real-mode DTA when client calls int 21h, ah=1ah
  
  10.05.2004, version 1.70
 
   bugfix: reset DTA after int 21h, ax=4b00h
   bugfix: int 31h, ax=0002 sometimes didn't recognize
    an already returned selector for a real-mode segment
   bugfix: environment for 16-bit clients in int 21h, ax=4b00h
    exec parameter block now used if != 0
   count of raw switches deleted
   if trace flag set on raw mode switch to protected mode,
    now halt on first instruction, not the second one
   bugfix: when a client other than the first one terminated,
    int 21h, ah=4ch was called with host stack, which could cause
    problems in some circumstances.
   API translation support for int 33h, ax=0009h,ax=0016h,ax=0017h
   bugfix: restrict DOS AH=0Ch API translation to subfunction 0Ah 
   bugfix: tool DPMIRS16 didn't load HDPMI16.EXE 
   switch HDPMI=4 added (return V1.0 server version)
  
  10.04.2004, version 1.67
 
   now int 15h in real mode is modified in raw mode only
   function 0505h (resize linear memory block) added
   set CR4 OSXMM flag (200h) on server entry
  
  18.03.2004, version 1.66
 
   understands vendor "VIRTUAL SUPPORT" for 32RTM.EXE support
   emulate 'mov eax,crx' and 'mov crx, eax'
   bugfix: int 31, ah=507h was unable to commit a page
   bugfix: int 2f, ax=168ah, vendor MS-DOS, returned function
    address for 32bit didnt clear HIWORD(edi)
   bugfix: int 31, ax=506h didnt return read/write attribute
   bugfix: int 21, ah=00h wrongly expected current PSP in bx
  
  29.02.2004, version 1.65
 
   bugfix: int 31, ax=604h returned a wrong page size
  
  24.01.2004, version 1.64
 
   int 21, ah=71h (LFN) no longer routed to DOS if LFN translation
    service deactivated (which is default)
   bugfix: linear address returned by function 0800h had always bits
    0-11 zeroed
   functions 0600h/0601h now return C if memory region is invalid
    (not allocated) 
              
  05.01.2004, version 1.63
 
   in psp kill function (int 21, ah=0) the psb isn't touched
    any more after real mode dos call returned
   translation support for long filenames (AH=71h), optional
   bug fixed for translation of int 21h, AX=7305h
  
  29.12.2003, version 1.62
 
   now pagedir in sysarea 0, user addr space now 4088 MB
   bugfixes for AllocSpecAddrSpace + FreeMem
   page tables now mapped in last page table, thus
    increasing user address space to 4084 MB (really)
   DPMI 1.0 function 0801h (unmap phys region) impl.
    max mem block in func 0500 now limited to largest free
    addr space region.
              
  21.12.2003, version 1.61
 
   DPMI 1.0 functions 0401h (get capabilities), 0504h
    (uncommitted memory) and 0507h (set page attributes)
    implemented.
   HDPMI environment variable read before real mode initialization
  
  11.12.2003, version 1.56
 
   release part of int15 memory if an app is launched.
    this allows multiple instances of HDPMI in int15 mode.
   HDPMI properly terminates if initialization fails (low memory)
   As default DOS memory is no longer in memory pool
   no more FFFF pages limit for memory allocation
   check es, fs, gs if a selector is freed by int31, ax=1
   pressing ctrl-alt-del now executes int21, ax=4c00
   exceptions in ring0 will now stop in kernel debugger
   DPMI 1.0 function 0506h (get page attributes) impl.
   int 3 in ring 0 is ignored now
   bugfix: scan for HDPMI looped if another var beginning
    with H occured in environment
   now using current environment block for int 21h, 4b00h
   total/free address space now handled correctly.
    no crash anymore if server runs out of address space
   bugfix: map physical memory was limited to FFFF pages,
    but returned no error otherwise.
              
  30.11.2003, version 1.55
 
   use int 15h, ax=e801h to get extended memory > 64 MB
  
  27.11.2003, version 1.54
 
   new switch HDPMI=4 restricts reporting of available
    memory to max. block size for I31, ax=0500h
   bugfix: a 8 kB memory block wasn't released if a task
    other than the first one has terminated.
   bugfix: for exceptions in ring 0 pressing (c)lient didn't work
  
  24.11.2003, version 1.53
 
   kernel debugger is now called for ring 0 exceptions as well
  
  20.05.2003, version 1.52
 
   kernel debug support wasn't activated in release version
  
  17.05.2002, version 1.51
 
   bugfix: reallocate memory (I31, AX=502h) didn't work in all cases
   memory handle is equal to base address for memory allocations
   system area moved to ff800000h, leaving 4084 MB for client
   some enhancements for kernel debugger support
   environment variable HDPMI implemented
   bugfix: wrong query for XMS host 3.0
    bugfix: memory request for 0 bytes will fail now
   i31swt: reset trace flag (call rm int)
   bug fixed in a20 server (xms gate 20 status)
  
  28.08.1999, version 1.50
 
   support of FAT32 API translation (Int21,AX=73xx)
  
  08.01.1998, version 1.40
 
   support for kernel debugger
   server now is in .EXE fromat (formerly .OVL)
   INT 96h in real mode to prevent debuggers stepping
    into server code.
   guard page 0 for IVT modifications
   temporary 64kb TLB for int 21 3F/40
   save/restore RMS now handled correctly
              
  14.05.1996, version 1.30
 
   reset NT-Flag in raw mode switch
   reset NT-Flag in real mode callbacks
   fixed bug in stack manipulation
   real mode int21 is saved and restored on exit
   for exception exit send EOI to kbd if necessary
   restore PM register for real-mode callbacks
   recognize 586 cpu
   recognize 486 cpu
  
  06.11.1994, version 1.20
 
   IRQs occuring in real mode now routed to protected mode
  
  06.06.1994, version 1.10
 
   many changes, clients now run in ring 3
  
  01.10.1993, version 1.00
 
   clients running in ring 0


 11. Copyright

   HDPMI is part of HX DOS extender runtime, which is freeware. It may be
   used for any purpose. Copyright Japheth 1993-2006.

   mail: mail@japheth.de
   web: http://www.japheth.de

