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

0. Contents

   1.    About DPMI
   2.    About HDPMI
   3.    Commandline Options
   4.    Environment Settings
   5.    Returncodes and Messages
   6.    Technical Details
    6.1  Memory Management
    6.2  Interrupt Handling
    6.3  Stack Handling
    6.4  DPMI API
    6.5  DOS API Support
    6.6  Other API Translation Support
    6.7  Debug Support
    6.8  Nested Execution of DPMI Clients
    6.9  Other Features of HDPMI
   7.    Restrictions of current Version
   8.    Applications known to run with HDPMI
   9.    History
  10.    Copyright

1. About DPMI

   DPMI was defined in 1989-1990. It was most popular in the days of
   Windows 3.X and its OS core VMM, which was in fact a DPMI server (with
   some extensions). This OS structure was inherited by Win9x, with some
   extensions to be able to execute Win32 programs. Windows NT (and its
   successors Win2k/WinXP) still support DPMI, but there it is "emulated"
   because the real mode DOS core doesn't exist anymore.
   
   A DPMI server's purpose is to execute DPMI clients, which are DOS
   programs running in protected mode. Such apps break the DOS
   640 KB memory limitation and may run in 32-bit flat protected mode,
   thus avoiding segmented memory models. The DPMI server will
   manage all resources specific to protected mode. Besides that the
   server forwards all software and hardware interrupts from protected
   mode to real mode, thus allowing the application to use standard Int
   21h calls, for example.

   Extended features of a DPMI server are:

   - Support of a swapfile to increase available memory by hard disk
     space. HDPMI does not support a swapfile.
   - Support of multitasking through "virtual machines". HDPMI does
     not support this feature, but allows to launch multiple instances
     of the server.

   Reasons to implement an application as DPMI client may be:

     - DPMI is widely supported. For every target platform except native
       DOS the DPMI API is implemented. With DPMI, native DOS is also
       supported. That means, your application may run everywhere.

     - A DPMI application may use the well known DOS and BIOS API as well
       as direct i/o. To port a real mode DOS application to DPMI may
       be as simple as to relink it.

     - In native DOS and with HDPMI, your application can run with IOPL=3.
       So I/O instructions are executed in real time. Interrupt latency
       is virtually nonexistant compared with popular multitasking
       environments.

     - large private address space. For example with HDPMI a client app
       may allocate up to 4088 MB (4 GB - 8 MB) address space.

   To read the following, you should be familiar to a certain degree with
   DPMI and intel cpus.



2. About HDPMI

   HDPMI is a DPMI server which conforms to DPMI specification v0.9,
   but supports a subset of DPMI v1.0 as well.

   HDPMI exists in two versions called HDPMI16.EXE and HDPMI32.EXE.
   The first will execute 16-bit DPMI clients, the latter executes
   32-Bit DPMI clients.

   HDPMI is a DOS TSR program, usually actived simply by typing its name
   at the command line. In this mode HDPMI will wait until a DOS application
   requires DPMI services and will remove itself from memory when the
   application terminates.



3. Commandline Options

   HDPMI accepts the following options entered in the command line:
   
     -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.
     -t: resets NE bit in CR0. So floating point errors will not cause
         an exception 0x10. Previously defined option -n, which set
         the NE bit, is now the default.
     -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.



4. Environment Settings

   HDPMI will recognize environment variable "HDPMI". By setting this
   variable one may modify HPMI's behaviour. It is interpreted as bit
   values, so one may set any combination of the following values:
   
   HDPMI=1: access to page 0 will be checked for IVT modifications.
            This may slow down an application and should be set
            only if an app doesn't run with standard settings.
   HDPMI=2: DOS memory is included in standard memory page pool.
            This option should be set only on machines with very
            little physical ram.
            NOTE: the meaning of this option has been changed
            compared to previous releases, in which HDPMI=2 has
            EXCLUDED dos memory from page pool (which is now the
            default setting).
   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 a subset of V1.0, such apps may
            work with this switch set.
   HDPMI=8: allocate TLB in low DOS memory. Same effect as command line
            switch -l.



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 DOS memory for initialization
   05   error: A20 cannot be enabled
   07   error: CPU in V86 mode, but no VCPI or DPMI host found
   08   error: CPU not 80486 or later
   09   error: DOS version not 4.01 or later
   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 management of HDMI depends on the configuration found
     at startup. HDPMI may find the following environments:

     - CPU is in real mode and no XMS-Host (like HIMEM.SYS), no VCPI-Host
       (like EMM386.EXE) and no DPMI-Server is running. HDPMI gets active
       in so-called "Int15"" or "Raw" mode.

     - CPU is in real mode and a XMS-Host is running. HDPMI becomes active
       in "XMS-Mode".

     - CPU is in v86 mode and a VCPI-Host is running. HDPMI gets active in
       "VCPI-Mode".

     - in all other cases HDPMI cannot gain control and terminates without
       further message.


   b) Physical Memory Management

   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 is released when the server terminates.

   VCPI-Mode:   If a XMS-Host is available in this mode, HDPMI prefers to 
                allocate memory through this host, for it seems to be 
                significantly faster. If XMS reports no more free memory,
                HDPMI tries to allocate memory through VCPI. In "modern" 
                implementations with a shared memory pool for XMS and VCPI,
                there will be no more memory available in VCPI if XMS is
                "empty".

   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 usage is optional
   because there is a chance that this behaviour may cause problems (that is, if 
   an application allocates all of reported available memory, there will be no more 
   conventional memory available afterwards).


   c) Address Space Management

   HDPMI reserves the last 8 MB of address space for its tables (IDT, LDT,
   paging). The rest is left for the client, so 4088 MB address space is
   available in the range 0 - FF7FFFFFh.

   d) Virtual Memory

   HDPMI doesn't support a swap file and therefore no virtual memory is supplied.


6.2 Interrupt Handling

   Hardware interrupts (IRQs) in a DPMI system should always be first
   handled by the protected mode handler, even if the IRQ occured in
   real mode or v86 mode. HDPMI executes in ring 0 protected mode, the
   client executes either in ring 3 protected mode, in real mode in
   Int15-/XMS-mode (which is implicitely ring 0) or in v86 mode in
   VCPI mode. IRQs occuring in protected mode are no problem, but IRQs
   in real mode/v86 mode require some special handling by the server.

   In real mode there is no automatic switch to protected mode
   when an IRQ occurs. In v86-mode there is, but HDPMI does not
   switch to v86-mode itself, it uses the VCPI server for the switch.
   That means, the IDT at the time when IRQ occurs is owned by the VCPI-host,
   which gets these IRQs first. The VCPI host reflects the IRQs to v86-mode
   and here is the point where HDPMI gets in. It switches to protected
   mode if a DPMI client has installed a protected mode handler for this
   IRQ (if not, HDPMI just calls the previous real mode handler).
   If the client protected mode handler calls the previous handler, it may
   be the IRQ will be launched back to real mode, but HDPMI takes care
   that there will be no loop. Anyway, there are a lot of mode switches,
   especially in VCPI-mode, if an IRQ occurs in real mode.
    To avoid these many mode switches, a DPMI server could always execute
   real mode code in v86-mode by switching to v86-mode by itself. If the
   DPMI server follows this strategy, it must take care of some things:

     - if there is a VCPI host installed, it is a problem to switch
       to v86 mode itself. The VCPI host offers some services to
       the real mode software, EMS, for example. EMS may nowadays not
       be used widely, but there are other problems. Any real mode
       software may want to switch to protected mode (a disk cache, for
       example), and its likely that the system crashes if the switch to
       v86-mode hasn't been handled by the VCPI host itself.
     - even if no VCPI host is installed, there may be some problems
       with software, which does not take into account a switch from
       the cpu mode from real mode to v86 mode.

   There exist solutions for these problems, for Windows exactly follows
   this strategy. HDPMI does not, but I think, there is no real penalty,
   and the system after starting HDPMI remains mostly in the same state
   as before, except that there is now DPMI available. I/O operations
   are in all cases faster in real mode than in v86 mode.

   The lack of the automatic switch to protected mode if an IRQ occurs
   should make no problem, one could think. If the server takes care of,
   the "manual" switching is a save thing to do. But unfortunately there
   are some very popular DPMI clients which get in the way. They try to
   switch to protected mode by itself if an IRQ in real mode occurs,
   for that purpose manipulating the real mode interrupt vector table
   and then using a real mode callback or raw mode switch services to jump
   temporarily to protected mode, handle the IRQ and jump back. This would
   nevertheless be ok, but it is handled faulty and thus causes the system
   to crash. What's more, they manipulate the real mode interrupt table
   directly, not through DPMI services, so that it is difficult to
   tame these programs. For this reason, HDPMI can be persuaded to guard 
   all accesses to page 0 in protected mode ring 3. This is done by setting
   environment variable "HDPMI=1". This will slow down the client application
   a bit, so only set it if the application in question don't run otherwise.


6.3 Stack Handling

   The management of stacks in DPMI is an area where there are significant
   differences among existing DPMI servers. Often these differences are
   the cause why one application works under the first server but crashes
   under the second. But first an overview:

   Under DPMI, there normally exist 4 stacks. These are:

     - 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 server 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 only 1 LPMS and its size is 4 KB.

     - the real mode stack (RMS). This stack is normally located in
       the memory block the DPMI client has to deliver to the server
       when it switches to protected mode the first time. This stack
       should be at least 200h Bytes. It is used when there is a
       reflection from protected mode interrupts to real mode.

     - the ring 0 stack. This stack is internal to the server, the client
       application does not see it. The server uses it to save segment
       register values during mode switches and for its normal processing.


   There is a problem with the LPMS. The application can switch away
   from the LPMS and enable interrupts. Then it is possible for a
   routine to be called recursively. But the LPMS cannot be used until
   the first routine terminates. HDPMI in this case simply remains or
   switches to the PMS. Because HDPMI installs no swap file, the PMS
   needn't be locked.

   With the real mode stack there is a similar problem. Once used, it
   can only be used again when the original routine terminates. But
   from real mode there can be a jump to protected mode through a
   real mode callback or through IRQ reflection.Then, in protected
   mode, the original RMS is still in use and therefore cannot be used
   again. HDPMI uses in such cases the real mode SS:SP from the last
   entry to protected mode as temporary RMS. This is by far the best
   solution, but there exist some DPMI clients which use the real mode
   SS:SP in protected mode. This is especially the case in real mode
   callbacks, where the DPMI client gets a protected mode pointer in
   DS:(E)SI to the actual real mode stack.

   The ring 0 stack is used by HDPMI for normal work and for saving
   segment values during mode switches. It is not used when doing
   a switch from PMS to LPMS and back. For most DPMI applications this
   is a esoteric detail, but it allows the DPMI application to
   savely switch away from the LPMS during IRQ handling.


6.4 DPMI API

   HDPMI fully supports DPMI version 0.9.

   Some DPMI v1.0 features are supported as well. These are:

   Int AX    comment
   -----------------------------------------------------------------
   2F  168A  get vendor-specific API entry point
   31  0401  get DPMI capabilities, Vendor is "HDPMI"
   31  0504  allocate linear memory block (committed/uncommitted)
   31  0505  resize linear memory block (NO support for descriptor update)
   31  0506  get page attributes
   31  0507  modify page attributes
   31  0801  unmap physical region
   31  0E00  get coprocessor status
   31  0E01  set coprocessor emulation

   Privileged opcodes emulated:
   
   - HLT (F4) 
   - MOV reg,CRx (0F 20 xx) - using ESP for reg will not work!


6.5 DOS API Support

   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  Terminate, kills 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
    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
    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
    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=03 Extended absolute disk read/write with params in DS:E/BX

   *LFN (AH=71h) API translation is deactivated in the standard version,
    since there is no support for this feature in plain DOS. 
    The server will not route LFN calls to real mode DOS, but return with
    ax=7100h and carry flag set. This is to ensure that tools like LFNDOS
    cannot do harm due to untranslated parameters.
    In directory Unsupp there is a version of HDPMI32 which has the LFN
    API translation activated.


6.6 Other API Translation Support

   Int Function Comment
   ---------------------------------------------------------------------
   10  ax=1003h set palette registers
   10  ax=1009h get palette registers
   10  ax=1012h set DAC registers
   10  ax=1017h get DAC registers
   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=0018h set alternate mouse user handler ES:E/DX


6.7 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

   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 extra support by the
   DPMI server to get a chance to do some protected mode initialization,
   especially to change some IDT vectors or allocate some GDT entries.
   For this reason HDPMI supports Int 68h in real mode. Kernel debuggers
   should therefore work with HDPMI although you might not expect
   many sophisticated "dot" commands.

   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.8 Nested Execution of several DPMI Clients

   HDPMI does not support "virtual machines", but it is possible to
   start several instances of HDPMI. A preassumption to support this
   feature is for the server to not grap all of available extended
   memory, so there is some left for the new instance to start. This
   is true for HDPMI in any case. 

   If two or more clients share one instance of HDPMI, they have to
   share address space, IDT and LDT. HDPMI will always save the IDT
   and LDT when a new client starts and restore them when the client
   has terminated, so most clients shouldn't cause problems when 
   sharing a server instance.


6.9 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.


7. Restrictions of current Version

   -  do not switch on the alignment check, HDPMI cannot recognize
      exceptions 11-1F, they will crash the system.
   -  If you are using Int15-mode, HDPMI must switch A20 line itself. Only
      standard AT and PS/2 (through port 92h) are supported.
   -  HDPMI doesn't allow to have more than 16 real mode callbacks active
      at the same time.
   -  Int 25/26 translation service: you should only read/write small amounts
      of bytes through this method, if you try to read/write more than 8 KB,
      the function will fail.


8. Applications known to run with HDPMI

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

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


9. History

Ver  Date     Text
-------------------------------------------------------------------------------
1.87 12.06.05 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.
     12.06.05 execute FNINIT in default exception 10h handler. 
     11.06.05 bugfix: an int 10h handler may have been called as if an
              exception 10h had occured, that is, onto the locked stack.
1.86 17.05.05 "mov reg,crX" is fully emulated now (opcode 0F 20 xx),
              except reg == ESP.              
     16.05.05 clear TS bit in CR0 on startup.
     14.05.05 translation of int 21h, ah=38h now documented
1.85 14.05.05 bugfix: default exception handler may have ignored key strokes
     19.01.05 emulation of "mov eax,cr0" and "mov eax,cr2" reactivated
1.84 13.12.04 translation for int 21h, ax=71A0h added
     07.12.04 exception 07 default handler now routes exception to protected
              mode int 07. It is not routed to real-mode, though.
     06.12.04 command line switches -d and -e added
     04.12.04 command line switch -l (=enviroment switch HDPMI=8) added
     03.12.04 dos memory functions now return error codes 8011h and 8022h
     03.12.04 dos memory alloc for 16-bit: selector tiling modified to
              exactly match dpmi specs
     03.12.04 internal: task state restored before server terminates
1.83 01.12.04 switched to Digital Mars C++ linker to reduce size of HDPMI
     01.12.04 DR7 now cleared on client termination as specified in DPMI V1.0
     29.11.04 bugfix: special registers DR7 and CR0 are no longer accessed in
              V86 mode when HDPMI terminates (VCPI mode only).
     29.11.04 bugfix: a GPF occured if client exited int 23h with RETF
              instead of RETF 4
     27.11.04 CR0 MP flag now saved and restored as are EM + NE
     27.11.04 command line switch -n added
     26.11.04 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).
     26.11.04 bugfix: int 15h mouse event proc had wrong stack parameters
     25.11.04 bugfix: int 33h mouse event proc caused GPF on RETF
1.82 24.11.04 bugfix: TF was lost when save/restore task state was called
              in real mode
     21.11.04 translation for int 21h, ax=6521h, 6522h, 65A1h, 65A2h added
     20.11.04 translation for int 21h, ax=5D0Ah added (set ext error info)
     20.11.04 bugfix: exc 0D with EIP > limit(CS) caused an exc 0D in ring 0
1.81 07.11.04 bugfix: int 21h, ax=440Dh, minor codes 40h,41h,61h did use
              ds:dx for 32bit clients, not ds:edx
1.80 10.10.04 bugfix: address space allocation may not have worked in all
              cases if HDPMI was installed with option -r (resident)
     08.10.04 bugfix: pressing Ctrl-C during console read may have caused
              a fatal dos memory error (asw.exe).
1.79 02.10.04 bugfix: function 0503h may have modified ES register
1.78 25.09.04 new command line switch -m to disable DPMI 1.0 memory functions
     25.09.04 function 401h, AX now has WRITE-PROTECT CLIENT bit set.
     25.09.04 bugfix: function 0401h modified E/DI.
1.77 17.09.04 API translation for int 21h, ax=71A6 added (LFN version only)
     13.09.04 bugfix: there was still a problem with releasing XMS memory,
              though it worked better than in v1.75
1.76 12.09.04 bugfix: HDPMI v1.75 crashed on exit if more than 1 XMS handle
              had to be released. 
1.75 11.09.04 bugfix: int 23h/24h traps did work for 1. client only 
     10.09.04 command line switches -r and -u added, to install/uninstall
              HDPMI as a TSR.
     10.09.04 bugfix: int 31h, ax=507h may have caused memory leaks
     09.09.04 DOS API translation AX=6300 added (get DBCS table)
1.74 29.08.04 unsupported version with LFN API translation released
1.73 10.06.04 client CS:EIP stored on top of locked protected-mode stack
     10.06.04 HLT now executed, not simulated
1.72 05.06.04 bugfix: int 21h, ah=49h: if memory to free was in conv. memory,
              ES may have been released even if dos function failed.
     04.06.04 function 0503h no longer fails if a block which contains
              uncommitted pages has to be moved
     03.06.04 bugfix: function 0503h (resize memory) has lost HIWORD
              of EBX in some cases.
     02.06.04 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.
     30.05.04 bugfix: redirection IRQs from real-mode to protected-mode
              didn't work properly
     16.05.04 bugfix: dos api translation AH=65h, AL>0 now works
     16.05.04 terminating client after an exception now uses LPMS
     15.05.04 waiting for a keystroke after exception dump now works better
     12.05.04 bugfix: failure of phys address mapping didn't set carry flag
1.71 12.05.04 bugfix: HDPMI v1.70 didn't work with VCPI!
     12.05.04 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.
     12.05.04 (re)set real-mode DTA when client calls int 21h, ah=1ah
1.70 10.05.04 bugfix: reset DTA after int 21h, ax=4b00h
     09.05.04 bugfix: int 31h, ax=0002 sometimes didn't recognize
              an already returned selector for a real-mode segment
     07.05.04 bugfix: environment for 16-bit clients in int 21h, ax=4b00h
              exec parameter block now used if != 0
     06.05.04 count of raw switches deleted
     06.05.04 if trace flag set on raw mode switch to protected mode,
              now halt on first instruction, not the second one
     22.04.04 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.
     13.04.04 API translation support for int 33h, ax=0009h,ax=0016h,ax=0017h
     13.04.04 bugfix: restrict DOS AH=0Ch API translation to subfunction 0Ah 
     12.04.04 bugfix: tool DPMIRS16 didn't load HDPMI16.EXE 
     12.04.04 switch HDPMI=4 added (return V1.0 server version)
1.67 10.04.04 now int 15h in real mode is modified in raw mode only
     23.03.04 function 0505h (resize linear memory block) added
     21.03.04 set CR4 OSXMM flag (200h) on server entry
1.66 18.03.04 understands vendor "VIRTUAL SUPPORT" for 32RTM.EXE support
     13.03.04 emulate 'mov eax,crx' and 'mov crx, eax'
     12.03.04 bugfix: int 31, ah=507h was unable to commit a page
     07.03.04 bugfix: int 2f, ax=168ah, vendor MS-DOS, returned function
              address for 32bit didnt clear HIWORD(edi)
     07.03.04 bugfix: int 31, ax=506h didnt return read/write attribute
     01.03.04 bugfix: int 21, ah=00h wrongly expected current PSP in bx
1.65 29.02.04 bugfix: int 31, ax=604h returned a wrong page size
1.64 24.01.04 int 21, ah=71h (LFN) no longer routed to DOS if LFN
              translation service deactivated (which is default)
     14.01.04 bugfix: linear address returned by function 0800h had always
              bits 0-11 zeroed
     13.01.04 functions 0600h/0601h now return C if memory region is
              invalid (not allocated) 
1.63 05.01.04 in psp kill function (int 21, ah=0) the psb isn't touched
              any more after real mode dos call returned
     03.01.04 translation support for long filenames (AH=71h), optional
     30.12.03 bug fixed for translation of int 21h, AX=7305h
1.62 29.12.03 now pagedir in sysarea 0, user addr space now 4088 MB
     28.12.03 bugfixes for AllocSpecAddrSpace + FreeMem
     27.12.03 page tables now mapped in last page table, thus
              increasing user address space to 4084 MB (really)
     24.12.03 DPMI 1.0 function 0801h (unmap phys region) impl.
              max mem block in func 0500 now limited to largest free
              addr space region.
1.61 21.12.03 DPMI 1.0 functions 0401h (get capabilities), 0504h
              (uncommitted memory) and 0507h (set page attributes)
              implemented.
     12.12.03 HDPMI environment variable read before real mode initialization
1.56 11.12.03 release part of int15 memory if an app is launched.
              this allows multiple instances of HDPMI in int15 mode.
     11.12.03 HDPMI properly terminates if initialization fails (low memory)
     11.12.03 As default DOS memory is no longer in memory pool
     11.12.03 no more FFFF pages limit for memory allocation
     10.12.03 check es, fs, gs if a selector is freed by int31, ax=1
     10.12.03 pressing ctrl-alt-del now executes int21, ax=4c00
     10.12.03 exceptions in ring0 will now stop in kernel debugger
     09.12.03 DPMI 1.0 function 0506h (get page attributes) impl.
     08.12.03 int 3 in ring 0 is ignored now
     08.12.03 bugfix: scan for HDPMI looped if another var beginning
              with H occured in environment
     07.12.03 now using current environment block for int 21h, 4b00h
     06.12.03 total/free address space now handled correctly.
              no crash anymore if server runs out of address space
     06.12.03 bugfix: map physical memory was limited to FFFF pages,
              but returned no error otherwise.
1.55 30.11.03 use int 15h, ax=e801h to get extended memory > 64 MB
1.54 27.11.03 new switch HDPMI=4 restricts reporting of available
              memory to max. block size for I31, ax=0500h
     25.11.03 bugfix: a 8 kB memory block wasn't released if a task
              other than the first one has terminated.
     24.11.03 bugfix: for exceptions in ring 0 pressing (c)lient didn't work
1.53 24.11.03 kernel debugger is now called for ring 0 exceptions as well
1.52 20.05.03 kernel debug support wasn't activated in release version
1.51 17.05.02 bugfix: reallocate memory (I31, AX=502h) didn't work in all cases
     17.05.02 memory handle is equal to base address for memory allocations
     16.05.02 system area moved to ff800000h, leaving 4084 MB for client
     10.05.02 some enhancements for kernel debugger support
     04.05.02 environment variable HDPMI implemented
     15.04.02 bugfix: wrong query for XMS host 3.0
              bugfix: memory request for 0 bytes will fail now
     22.08.00 i31swt: reset trace flag (call rm int)
     xx.09.99 bug fixed in a20 server (xms gate 20 status)
1.50 28.08.99 support of FAT32 API translation (Int21,AX=73xx)
1.40 08.01.98 bug fix
     3x.12.97 support for kernel debugger
     xx.11.97 big changes:
              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
1.30 14.05.96 reset NT-Flag in raw mode switch
     14.05.96 reset NT-Flag in real mode callbacks
     01.05.96 fixed bug in stack manipulation
     01.05.96 real mode int21 is saved and restored on exit
     01.05.96 for exception exit send EOI to kbd if necessary
     01.05.96 restore PM register for real-mode callbacks
     25.03.96 recognize 586 cpu
     10.02.96 recognize 486 cpu
     12.08.95 bug fixed?
     09.04.95 bug fixed?
1.20 06.11.94 IRQ's occured in real mode now reflected in protected mode
1.10 06.06.94 many changes, clients now run in ring 3
1.00 01.10.93 first version running, clients running in ring 0


10. Copyright

   HDPMI is part of HX DOS extender runtime, which is freeware. It may be
   used for any purpose. 

   mail: mail@japheth.de
   To get the newest version view http://www.japheth.de

   Copyright Japheth 1993-2004

