//////////////////////////////////////////////////////////////////////////////
/ /
/ HDPMI - DPMI Server (Version 3.17) /
/ /
//////////////////////////////////////////////////////////////////////////////
0. Contents
1. About HDPMI
2. Requirements
3. Commandline Options
4. Environment Settings
5. Returncodes and Messages
6. Implementation 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 VDS API
6.8 DOS API Translation
6.9 Other API Translation Support
6.10 Debug Support
6.11 Nested Execution of DPMI Clients
6.12 Other Features of HDPMI
7. Restrictions of current Version
8. Known Problems/Hints
9. Compatibility List
10. License
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
about segmented memory models and use the simple "flat" model.
■ 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:
■ real-mode interrupt translation services, thus allowing the client
to use DOS Int 21h calls which use pointers, for example. HDPMI
has such services implemented, see below.
■ 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.
■ "virtual machines". This is not supported, but optionally HDPMI allows
to run clients in their own address contexts. Conventional memory
(address space 0-10FFFFh) always is shared, though.
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 72 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 (version >= 3.3). FreeDOS or DR-DOS (version >= 5.0) 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:
-a: run clients in separate address contexts. This is similar to
environment switch HDPMI=32.
-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!
-d: disable the last installed instance of HDPMI
-e: reenable a disabled instance of HDPMI
-h: display HDPMI help screen. It will not install as TSR.
-i: watch direct access to the IVT to ensure hardware interrupts are
always routed to protected mode. This is similar to environment
switch HDPMI=1.
-k: if a register dump is to be displayed, make sure that the screen
is in text mode. Versions prior to 3.13 did this in any case.
-l: TLB will be allocated in low DOS memory. Useful if DOS UMBs
are slow or not accessible by DMA.
-m: disables support for DPMI 1.0 memory functions (AX >= 0504h).
-n: report clients a smaller amount of free physical pages. This is
necessary for clients which assume this amount is safe to use.
-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 (*).
-s: 'safe' mode. Prevents client from modifying system tables. This
is similar to environment switch HDPMI=4096.
-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.
Similar to environment switch HDPMI=32768.
-u: this switch will uninstall a running instance of HDPMI.
-v: if both XMS and VCPI hosts were detected, use VCPI memory allocation
and ignore XMS host.
-y: use extended memory not managed by XMS host. Usually a "modern"
XMS host can handle all extended memory, but old ones may handle
63 or 255 MB only. Then setting this option may be useful. For
XMS V3 hosts the implementation of function AH=89h must return
in ECX the true highest physical address managed by the host.
This value is sometimes wrong, in which case this option shouldn't
be set (some security checks are implemented, but it isn't
fool-proved). If in doubt run tool DPMI.EXE to see if the value
is reasonable.
(*) 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 behavior. 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. Same effect as
command line option -i.
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
option -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: run clients in separate address contexts. This option may be
needed to allow nested execution of clients which cannot share
an address space. The conventional memory region 0-10FFFFh
is still shared, though. Furthermore, setting this switch will
increase the client's DOS memory consumtion, since most parts
of the host's DOS memory usage must then be client specific.
Same effect as command line option -a.
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 these
tables are allocated in HDPMI's reserved space above linear
address FF800000h, but some programs seem to not expect them
at such high addresses. 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 option -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: 'safe' mode. Don't allow client to write to GDT, IDT and LDT.
HDPMI=8192: stop in debugger after client's initial switch to protected
mode.
HDPMI=16384: 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=32768: prevents HDPMI from modifying CR0 NE bit. Same effect as
command line option -t.
5. Returncodes and Messages
If HDPMI is launched by a program, 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 isn't 3.3 or higher
09 error: CPU not 80386 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 modified 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. Implementation 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. HDPMI
will detect and use XMS v3 hosts, which may allow to alloc
up to 4 GB of physical memory. The memory blocks allocated
are released when HDPMI terminates. If HDPMI has been
installed permanently with option -r, the blocks (except
the first one) are released when the server enters idle state,
that is, no client is running.
VCPI-Mode: If a XMS-Host is available in this mode, HDPMI prefers to
allocate memory through this host, because some VCPI host's
memory allocation API is pretty slow. So this API will be
used only if no XMS host is found (which should be a very
rare constellation) or cmdline option -v has been entered.
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 behavior 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
Paging will always be enabled with HDPMI. It reserves the last 8 MB of
the 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 feature is activated by setting environment variable HDPMI=1
or command line option -i). 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-11 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 hardware 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
Usually 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.
If HDPMI has been told to give each client its own address context, things
are different of course. Address space, IDT and LDT are no longer shared,
and the client will get "clean" copies of IDT and LDT. On termination, the
client's resources are just thrown away.
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 VDS API
The following VDS functions (Int 4Bh, AH=81h) are supported in
protected-mode:
AL Function Comment
-----------------------------------------------------------------------
03 lock region routed to v86-mode with translation of ES:E/DI
04 unlock region routed to v86-mode with translation of ES:E/DI
05 scatter/gather lock handled by HDPMI. ES:E/DI must point to a EDDS.
06 scatter/gather unlock handled by HDPMI. Indeed it is mostly a No-Op,
just the parameters are checked for validity.
07 request DMA buffer routed to v86-mode with translation of ES:E/DI
08 release DMA buffer routed to v86-mode with translation of ES:E/DI
09 copy into DMA buffer routed to v86-mode with translation of ES:E/DI
0A copy out of DMA buffer routed to v86-mode with translation of ES:E/DI
VDS functions 02 and 0Bh-0Ch are routed to real/v86-mode without
translation.
Implementation of function 05 will allow linear-to-physical address
translation for any valid linear address. If an address space contains
uncommitted pages, bit 6 of DX must be set to return PTEs, else the call
will fail.
Functions which are routed to v86-mode with ES:E/DI translation will not
be able to handle linear addresses managed by HDPMI, that is, they might
work for address space 0-110000h only.
Please be aware that if DOS is running in real-mode (no EMM is loaded),
then calling functions other than 05-06 most likely will fail. Therefore
bit 5 at 40h:007Bh should be checked if VDS is available.
6.8 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.9 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.10 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. It's also
ensured that no Int 41h call will 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
Environment switch HDPMI=8192 will cause HDPMI to set the client's
trace flag on its initial switch to protected-mode. This should work
with any DPMI-aware debugger.
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
- the value of the trace flag is preserved if a mode switch occurs.
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.11 Nested Execution of several DPMI Clients
As already mentioned, usually if two or more clients share one instance
of HDPMI, they also 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. Therefore HDPMI optionally allows
to run each client in its own address context. Thus the clients will only
share DOS specific resources (address space 0-10FFFFh, files, IVT vectors)
and (physical) extended memory.
6.12 Other Features of HDPMI
■ clients run with CPL 3, and IOPL is 3. This means, instructions like
STI, CLI, 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.
■ A client can allocate up to 16 real-mode callbacks.
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.
■ 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.
■ Exceptions >= 12h aren't supported/detected.
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 DOS extenders will prefer to use a VCPI host over DPMI and thus
ignore an installed copy of HDPMI. Usually there is a way to make them
change their mind:
- CauseWay: set environment variable "CAUSEWAY=DPMI"
- PMODE/W: use tool PMWSETUP to set switch "prefer DPMI over VCPI"
- DOS/32A: set environment variable "DOS32A=/DPMITST:1" or run SS.EXE
■ 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 (examples: 1. apps built with DJGPP v2 because of
the NULL pointer protection problem. 2. the game "Inner Worlds").
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 DOS/32A applications may belong to these type of programs.
■ If HDPMI is loaded and a client refuses to run and tells that it doesn't
like to run in a Win9x DOS box, try to set HDPMI=16384 before HDPMI is
loaded.
■ 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.
■ if HDPMI is loaded residently and the Watcom debugger WD is launched
to debug a protected mode application it may display a message that
it cannot do that on a DPMI 0.9 host. Then set environment variable
HDPMI=36. This will report a DPMI 1.0 host to WD and separate the
debugger's and debuggee's address space.
■ Some clients refuse to run if the 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.
■ Some clients regard the amount of free physical pages as safe to
allocate. This may work ok for hosts which use a swapfile, but HDPMI
doesn't and therefore the request is likely to fail. Option -n might
make such clients work (example: "Blood" game).
■ 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
- PMODE/W DOS extender
- CauseWay DOS extender
- DOS/32 Advanced DOS extender
- Borland Powerpack (16 + 32-bit)
- WDOSX extender
- RSX DOS extender
- RAW32 DOS extender
- X-32 DOS extender (Digital Mars)
- Pharlab TNT DOS extender (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 + 32-bit)
- kernel debugger WDEB386.EXE/WDEB98.EXE/DEBUGGER.EXE
- 386SWAT, Qualitas' ring 0 debugger
HDPMI itself has been tested to run under the following emulators:
- Bochs
- Qemu
- VMWare
- VirtualBox
- DosBox (version must be >= 0.70)
Wth Virtual PC 2007 the standard HDPMI binary will not work. However,
there is a modified HDPMI32.EXE available which might work and can be
found at https://www.japheth.de/hx.html.
HDPMI has also been tested to run with the following VCPI hosts:
- MS-DOS Emm386 (V7.x, V6.x, V5.0)
- Jemm
- FreeDOS Emm386 (V2.x)
- Quarterdeck Qemm386 (V6, V8, V9)
- Qualitas 386Max (V6.02, V7.02)
10. License
HDPMI is part of the HX DOS extender runtime, which is freeware. It may
be used for any purpose. Copyright Japheth 1993-2009.
Japheth ( https://www.japheth.de )