-
Notifications
You must be signed in to change notification settings - Fork 19
DPMI 0.9 Specs
Maximilien Noal edited this page Oct 8, 2023
·
1 revision
DOS PROTECTED MODE INTERFACE (DPMI)
SPECIFICATION
Protected Mode API For DOS Extended Applications
Version 0.9
Printed July 26, 1990
TABLE OF CONTENTS
1. Introduction............................................1
2. General Notes for Protected Mode Programs...............4
2.1 Virtual DOS Environments...........................5
2.1.1 No Virtualization............................5
2.1.2 Partial Virtualization.......................5
2.1.3 Complete Virtualization......................5
2.2 Descriptor Management..............................6
2.3 Interrupt Flag Management..........................7
2.4 Interrupts.........................................8
2.4.1 Hardware Interrupts..........................8
2.4.2 Software Interrupts..........................9
2.5 Virtual Memory and Page Locking...................10
3. Mode and Stack Switching...............................11
3.1 Stacks and Stack Switching........................12
3.1.1 Protected Mode Stack........................12
3.1.2 Locked Protected Mode Stack.................12
3.1.3 Real Mode Stack.............................12
3.1.4 DPMI Host Ring 0 Stack......................12
3.2 Default Interrupt Reflection......................13
3.3 Mode Switching....................................14
3.4 State Saving......................................15
4. Error Handling.........................................16
5. Loading DPMI Clients and Extended Applications.........17
5.1 Obtaining the Real to Protected Mode Switch Entry
Point.................................................18
5.2 Calling the Real to Protected Mode Switch Entry
Point.................................................19
6. Terminating A Protected Mode Program...................22
7. Mode Detection.........................................23
8. LDT Descriptor Management Services.....................24
8.1 Allocate LDT Descriptors..........................25
8.2 Free LDT Descriptor...............................26
8.3 Segment to Descriptor.............................27
8.4 Get Next Selector Increment Value.................28
8.5 Reserved Subfunctions.............................29
8.6 Get Segment Base Address..........................30
8.7 Set Segment Base Address..........................31
8.8 Set Segment Limit.................................32
8.9 Set Descriptor Access Rights......................33
8.10 Create Code Segment Alias Descriptor.............35
8.11 Get Descriptor...................................36
8.12 Set Descriptor...................................37
8.13 Allocate Specific LDT Descriptor.................38
9. DOS Memory Management Services.........................39
9.1 Allocate DOS Memory Block.........................40
9.2 Free DOS Memory Block.............................41
9.3 Resize DOS Memory Block...........................42
10. Interrupt Services....................................43
10.1 Get Real Mode Interrupt Vector...................44
10.2 Set Real Mode Interrupt Vector...................45
10.3 Get Processor Exception Handler Vector...........46
10.4 Set Processor Exception Handler Vector...........47
10.5 Get Protected Mode Interrupt Vector..............50
10.6 Set Protected Mode Interrupt Vector..............51
11. Translation Services..................................52
11.1 Simulate Real Mode Interrupt.....................55
11.2 Call Real Mode Procedure With Far Return Frame...56
11.3 Call Real Mode Procedure With Iret Frame.........57
11.4 Allocate Real Mode Call-Back Address.............58
11.5 Free Real Mode Call-Back Address.................62
11.6 Get State Save/Restore Addresses.................63
11.7 Get Raw Mode Switch Addresses....................65
12. Get Version...........................................66
13. Memory Management Services............................67
13.1 Get Free Memory Information......................68
13.2 Allocate Memory Block............................70
13.3 Free Memory Block................................71
13.4 Resize Memory Block..............................72
14. Page Locking Services.................................73
14.1 Lock Linear Region...............................74
14.2 Unlock Linear Region.............................75
14.3 Mark Real Mode Region as Pageable................76
14.4 Relock Real Mode Region..........................77
14.5 Get Page Size....................................78
15. Demand Paging Performance Tuning Services.............79
15.1 Reserved Subfunctions............................80
15.2 Mark Page as Demand Paging Candidate.............81
15.3 Discard Page Contents............................82
16. Physical Address Mapping..............................83
17. Virtual interrupt State Functions.....................84
17.1 Get and Disable Virtual Interrupt State..........85
17.2 Get and Enable Virtual Interrupt State...........86
17.3 Get Virtual Interrupt State......................87
18. Get Vendor Specific API Entry Point...................88
19. Debug Register Support................................89
19.1 Set Debug Watchpoint.............................90
19.2 Clear Debug Watchpoint...........................91
19.3 Get State of Debug Watchpoint....................92
19.4 Reset Debug Watchpoint...........................93
20. Other APIs............................................94
21. Notes For DOS Extenders...............................95
21.1 Initialization of Extenders.....................96
21.2 Installing API Extensions........................96
21.3 Loading the Application Program..................96
21.4 Providing API Extensions.........................97
1. INTRODUCTION
The DOS Protected Mode Interface (DPMI) was defined to allow
DOS programs to access the extended memory of PC
architecture computers while maintaining system protection.
DPMI defines a specific subset of DOS and BIOS calls that
can be made by protected mode DOS programs. It also defines
a new interface via software interrupt 31h that protected
mode programs use to allocate memory, modify descriptors,
call real mode software, etc. Any operating system that
currently supports virtual DOS sessions should be capable of
supporting DPMI without affecting system security.
Some DPMI implementations can execute multiple protected
mode programs in independent virtual machines. Thus, DPMI
applications can behave exactly like any other standard DOS
program and can, for example, run in the background or in a
window (if the environment supports these features).
Programs that run in protected mode also gain all the
benefits of virtual memory and can run in 32-bit flat model
if desired.
Throughout this document, the term "real mode" software is
used to refer to code that runs in the low 1 megabyte
address space and uses segment:offset addressing. Under
many implementations of DPMI, so called real mode software
is actually executed in virtual 8086 mode. However, since
virtual 8086 mode is a very close approximation of real
mode, we will refer to it as real mode in this document.
DPMI services are only available to protected mode programs.
Programs running in real mode can not use these services.
Protected mode programs must use the service described on
page 20 to enter protected mode before calling Int 31h
services.
All Int 31h functions will modify flags and the AX register.
All other registers will be preserved unless they are
specified as return values. Unsupported calls will return
with the carry flag set. Since Int 31h is set up as a trap
gate, the interrupt flag will not be modified by any Int 31h
calls except for memory management and interrupt flag
management calls. All memory management calls may enable
interrupts. Interrupt flag management calls will modify the
interrupt flag as specified by the call. All Int 31h
services are reentrant.
Some implementations of DPMI can run 32-bit 80386 specific
programs. DPMI functions that take pointers as parameters
will use the extended 32-bit registers for offsets (for
example, ES:EDI instead of ES:DI) when running 32-bit mode
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 1
programs. The high word of the 32-bit registers will be
ignored when running 16-bit protected mode programs.
DPMI services are provided by what will be referred to as
the DPMI host program. The program(s) that use DPMI
services are called DPMI clients. Generally, DPMI clients
are two categories:
o Extended Applications
o Applications that use DPMI directly
It is believed that most DPMI applications will be extended
applications. Extended applications are bound with an
extender that is the actual DPMI client and the application
calls extender services that then are translated by the
client into DPMI calls. The advantage of an extended
application over one that calls DPMI services directly is
that generally an extender will support more than just DPMI.
In fact it is recommended that extenders look for extension
services in the following order:
o DPMI
o VCPI/EMS
o XMS
o Top-down (Int 15h)
An extender can provide a single set of APIs to the actual
application and then translate them to the services that are
provided. Where the host extension services are "lacking"
in a particular function the extender must provide that
function for the application.
Figure 1 on page 3 shows a picture of how this works. The
application code sits on top of a set of base extender
functions and APIs. The extender then has separate modules
for each type of extension service and code to "fill in the
slack" where services are lacking. An example of a typical
extender service is protected mode program loading. The
actual shipped application is the application code bound in
with the extender and all of its styles of client support.
The host support is generally an extension of the base OS
functions or a device driver used to extend the base OS
functions.
This document is intended to provide a definition of the
DPMI services that a DPMI host would be required to
implement and that a DPMI client would use.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 2
Figure 1. Application/Extender/Client/Host/OS structure
+----------------------------------------------------------+
| |
| +----------------------------------------------------+ |
| | | |
| | Application Code | |
| | | |
| +----------------------------------------------------+ |
| |
| +----------------------------------------------------+ |
| | Extender Base (including APIs) | |
| | -------------------------------------------------- | |
| | DPMI | |
| | client | |
| +------------+ | |
| | VCPI | |
| | client | |
| +------------+ | |
| | XMS | |
| | client | |
| +------------+ | |
| | Top-down | |
| | client | |
| +-------------+ |
| |
+----------------------------------------------------------+
+------------+
| |
| |
| |------------+
| | |
| DPMI | |
| host | VCPI |------------+
| | | |
| | | |
| |------------| XMS |-------------+
| | EMS | | Top-down |
| | | | (Int 15h) |
+----------------------------------------------------+
+----------------------------------------------------+
| |
| Operating System (e.g. DOS) |
| |
+----------------------------------------------------+
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 3
2. GENERAL NOTES FOR PROTECTED MODE PROGRAMS
There are a few basic differences between real mode and
protected mode that need to be addressed to convert a real
mode program to run in protected mode.
Programs run at a protection level that prevents them from
executing privileged instructions such as lgdt, lidt, etc.
The DPMI interface is the only method application programs
have for modifying system structures such as descriptors.
While DPMI defines a specific set of functions that will be
supported by all implementations, there may be minor
differences in individual implementations. Programmers
should refer to the notes for their DPMI implementation for
documentation on detecting the presence of and calling
vendor specific extensions. However, any application that
is written to adhere only to standard DPMI calls should work
correctly under all implementations of DPMI.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 4
2.1 Virtual DOS Environments
Many DPMI implementations are simulated "virtual DOS"
sessions. In other words, the DOS interface and environment
presented to the program are not actually the native
interface of the operating system. Hardware interrupts,
I/O, and processor exceptions will be virtualized by the
operating system. This means, for example, that a DPMI
program may receive a simulated keyboard interrupt and read
simulated I/O from the keyboard controller ports.
In these environments, actual hardware interrupts will be
handled by the operating system. The physical interrupts
will be invisible to the DPMI application program. If the
operating system so chooses, it may reflect a virtual
interrupt to the DPMI program. The DPMI program does not
need to know, nor should it care, if this is the case. From
the program's point of view, the interrupt looks exactly
like a "real" interrupt. The operating system will also
virtualize I/O to the interrupt controller ports and any
other simulated devices.
There are basically three levels of virtualization that DPMI
implementations can provide:
2.1.1 No Virtualization
In general, stand-alone single tasking DPMI implementations
will not virtualize any hardware devices. These hose
extension programs will execute as standard DOS real mode
drivers or programs. Extenders which use the services
provided by these DPMI host drivers will translate protected
mode DOS calls to real mode DOS calls. Normally these
extenders will invoke DPMI services to return the processor
to real mode (instead of virtual 8086 mode) when calling
DOS.
2.1.2 Partial Virtualization
Some environments that execute under DOS will virtualize
hardware devices, provide virtual memory, or provide other
services that require virtualization of some hardware
devices. Under these environments, DPMI applications will
always run at a non-privileged ring (usually ring 3). Some
or all hardware interrupts will be virtualized, some or all
I/O will be virtualized, and virtual memory may be
supported. Under these implementations, page locking
services usually must be used to lock interrupt and
exception handling code.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 5
2.1.3 Complete Virtualization
These environments provide a completely simulated DOS
environment. The native operating system is something other
than MS-DOS. Under these implementations of DPMI, all
devices will be virtualized to some extent. Normally, page
locking services will be ignored by these implementations
since all physical device interrupt and I/O handling will be
performed by the operating system. Programs will always run
at a non-privileged ring.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 6
2.2 Descriptor Management
Protected mode code segments can not be modified. This
requires programs to allocate an alias data descriptor if
they need to store data in a code segment.
Segment arithmetic that works in real mode does not work in
protected mode.
Some calls will return a range of descriptors. For example,
if a 16-bit mode program allocates a block of memory larger
than 64K, the call will allocate several, contiguous
descriptors. Each descriptor will have a 64K limit except
for the final descriptor which will have a limit that
contains the remainder of the block. The call will return
the first selector in the array. To get to the next
selector, your program must add the value returned by Int
31h call 0003h (see page 32).
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 7
2.3 Interrupt Flag Management
The popf and iret instructions may not modify the state of
the interrupt flag since most DPMI implementations will run
programs with IOPL < DPL. Programs must execute cli or sti
to modify the interrupt flag state.
This means that the following code sequence will leave
interrupts disabled:
;
; (Assume interrupts are enabled at this point)
;
pushf
cli
.
.
popf ; Interrupts are still OFF!
Note that since some implementations of DPMI will maintain a
virtual interrupt state for protected mode DOS programs, the
current value of the interrupt flag may not reflect the
current virtual interrupt state. Protected mode programs
should use the virtual interrupt state services to determine
the current interrupt flag state (see page 99).
Since cli and sti are privileged instructions, they will
cause a protection violation and the DPMI provider will
simulate the instruction. Because of the overhead involved
in processing the exception, cli and sti should be used as
little as possible. In general, you should expect either of
these instructions to require at least 300 clocks.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 8
2.4 Interrupts
Protected mode programs can hook both hardware and software
interrupts using the DPMI get and set protected mode
interrupt vector functions (see page 56). All interrupts
from hardware devices such as the timer or keyboard
controller will always be reflected to the protected mode
interrupt handler first. If the protected mode handler
jumps to or calls the previous interrupt handler then the
interrupt will be reflected to real mode.
As in real mode, interrupt procedures can either service the
interrupt and iret or they can chain to the next handler in
the interrupt chain by executing pushf/call or by jumping to
the next handler. The final handler for all protected mode
interrupts will reflect the interrupt to real mode.
When an interrupt is reflected to real mode, the EAX, EBX,
ECX, EDX, ESI, EDI, EBP registers, and flags will all be
passed from protected to real mode unaltered. The segment
registers will contain undefined values unless an API
translator (such as a DOS or BIOS translator) explicitly
sets a real mode segment register. DPMI will automatically
provide a real mode stack for interrupts that are reflected
to real mode.
2.4.1 Hardware Interrupts
The interrupt controllers are mapped to the system's default
interrupts. On an IBM AT-compatible system, for example,
the master interrupt controller is programmed with a base
interrupt of 8 and the slave controller has a base of 70h.
The virtualized interrupt controllers can be reprogrammed;
the base setting may be examined in protected mode with Int
31h function 0400h.
Hardware interrupt procedures and all of their data must
reside in locked memory. All memory that is touched by
hardware interrupt hooks must be locked. The handler will
always be called on a locked stack. See page 12 for more
details.
As in real mode, hardware interrupt handlers are called with
interrupts disabled. Since iret will not restore the
interrupt flag, hardware interrupt hooks must execute an sti
before executing iret or else interrupts will remain
disabled.
Protected mode hardware interrupt handlers will always be
called even for interrupts that occur in real mode. The
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 9
last hook on the protected mode interrupt chain will reflect
the interrupt to real mode.
Protected mode hardware interrupt handlers that need to call
software running in real mode must either be sure that the
real mode software that they are calling will not modify
segment registers or they must use the state save service
(see page 74) to save and restore the real mode segment
registers. However, any interrupt handler that executes
completely in protected mode, or uses translation services
0300h, 0301h, or 0302h does not need to save the real mode
register state. Therefore, this is not an issue for most
interrupt handlers.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 10
For compatibility with older systems, computers with two
interrupt controllers have the BIOS redirect one of the
interrupts from the slave controller into the range of the
master controller. For example, devices jumpered for IRQ 2
on IBM AT-compatible computers actually interrupt on IRQ 9
(interrupt 71h). In real mode, the BIOS on these systems
will convert interrupt 71h to Int 0Ah and EOI the slave
controller. A protected mode program that needs access to
the redirected interrupt may use variations on either of
these techniques:
1. Hook the target interrupt in real mode. This
takes advantage of the built in redirection. This
is robust on systems where other software has
reprogrammed the interrupt controllers, or where
the slave interrupt controller may be absent.
2. Hook the actual interrupt in both real and
protected mode. In this case, the program must
EOI both the slave and master interrupt
controllers since the BIOS will not get control.
This is more efficient in that there will not be
any unnecessary switches to real mode.
2.4.2 Software Interrupts
Most software interrupts executed in real mode will not be
reflected to the protected mode interrupt hooks. However,
some software interrupts are also reflected to protected
mode programs when they are called in real mode. These are:
INT DESCRIPTION
1Ch BIOS timer tick interrupt
23h DOS Ctrl+C interrupt
24h DOS critical error interrupt
Programs should not terminate during interrupts that were
reflected from real mode. Terminating the program at this
point may prevent the DPMI host from cleaning up properly.
Of all software interrupts, only Ints 00h-07h will be called
with virtual interrupts disabled. For these interrupts, the
handler should return with interrupts enabled. All other
interrupts will not modify the interrupt flag state.
Since most software interrupts that are executed in real
mode are not reflected to protected mode interrupt hooks,
programs would be required to install a real mode interrupt
hook to monitor these interrupts.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 11
2.5 Virtual Memory and Page Locking
Many implementations of DPMI support virtual memory. In
these environments, it will be necessary to lock any memory
that can be touched while executing inside of DOS. This is
necessary because it may not be possible for the operating
system to demand load a page if DOS is busy.
Some DPMI implementations will not call DOS to read or write
virtual memory to disk and under these implementations the
page locking services may be ignored. Since the entire DPMI
session is virtualized, a page fault can be handled at any
point while executing the program. However, under all
implementations, DPMI applications should lock interrupt
code and data. The lock calls will always return success
under implementations that ignore these calls.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 12
3. MODE AND STACK SWITCHING
This section contains an overview of how DPMI hosts switch
between protected and real mode and handle stack switching.
It is important to understand the host maintains the state
of the client to prevent overwriting stack data or modifying
segment registers.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 13
3.1 Stacks and Stack Switching
Every DPMI task runs on four different stacks: An
application ring protected mode stack, a locked protected
mode stack, a real mode stack, and a DPMI host ring 0 stack.
The protected mode stack is the one the DPMI client was
running on when it switched into protected mode by calling
the protected mode entry point (although the client can
switch to another protected mode stack if desired). The
locked protected mode stack is provided by the DPMI server
and is used for simulating hardware interrupts and
processing real mode call-backs. The DPMI host provides the
real mode stack, which is usually located in the data area
provided by the client. The ring 0 stack is only accessible
by the DPMI host. However, this stack may contain state
information about the currently running program.
3.1.1 Protected Mode Stack
This is the stack that the client uses for normal execution
in protected mode. The protected mode stack of a DPMI
client can be unlocked if desired. Software interrupts
executed in protected mode will be reflected on this stack.
3.1.2 Locked Protected Mode Stack
During hardware interrupts, Int 1Ch, Int 23h, Int 24h,
exceptions, and real mode call-back handling in protected
mode, the DPMI will host automatically switch to a locked
protected mode stack. When the interrupt or call returns,
the host will return to the original protected mode stack.
Note that there is only one, 4K, locked stack provided by
the host. The stack will be switched onto the first time an
interrupt or call is reflected to protected mode, and will
be switched away from when the client returns. Subsequent
nested interrupts or calls will not cause a stack switch.
Software interrupts do not automatically switch stacks.
3.1.3 Real Mode Stack
The DPMI host will provide the client with a real mode stack
that is at least 200h bytes in size and will always be
locked. Interrupts that are reflected into real mode, as
well as calls made using the translation services, will be
reflected on this stack. DPMI hosts will not automatically
switch stacks for hardware interrupt processing in real mode
since DOS performs this function automatically.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 14
3.1.4 DPMI Host Ring 0 Stack
DPMI hosts will normally have a stack associated with each
DPMI task. The DPMI client will not be able to access this
stack in any way -- it is used by the host for execution at
ring 0 to handle interrupts and exceptions. This stack will
sometimes be used to store state information while switching
modes. For example, the original SS:ESP of the protected
mode program could be saved on the ring 0 stack while the
DPMI host switches onto the locked protected mode stack.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 15
3.2 Default Interrupt Reflection
DPMI hosts provide interrupt vectors for all 100h (256
decimal) interrupts for protected mode clients. When the
DPMI client initializes, all interrupt vectors will point to
code that will automatically reflect the interrupt to real
mode (except for Int 31h and Int 21h, AH=4Ch). When a
default interrupt reflection handler is executed it will
switch to real mode, preserving the EAX, EBX, ECX, EDX, ESI,
EDI, and EBP registers and flags, and reflect the interrupt
in real mode. When the real mode interrupt returns, the
default interrupt reflection code will switch back to
protected mode and return with the modified values of EAX,
EBX, ECX, EDX, ESI, EDI, EBP, and flags. Segment registers
and the stack pointer will not be passed between modes.
Therefore, any API that passes pointers or information in
segment registers will need to be translated by a DOS
extender.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 16
3.3 Mode Switching
There are three different ways a client can force a mode
switch between protected and real mode:
o Execute the default interrupt reflection handler
o Use the translation services to call real mode
code
o Use a real mode call-back to switch from real to
protected mode
o Use the raw mode switch functions
All mode switches except for the raw mode switches will save
some information on the DPMI host's ring 0 stack. This
means that programs should not terminate while in nested
mode switches unless they are using the raw mode switching
services. However, even programs that use raw mode switches
should not attempt to terminate from a hardware interrupt or
exception handler since the DPMI host performs automatic
mode and stack switching to provide these services.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 17
3.4 State Saving
Because DPMI hosts switch stacks automatically across mode
switches, it is sometimes necessary to use the state
save/restore functions while using the raw mode switch
services. The host will maintain information on the "other"
mode's current state. This information will include the
CS:(E)IP, SS:(E)SP, and segment register values. Since the
DPMI client has no way to directly access these values, it
will need to call the state saving functions when performing
nested mode switches.
For example, during hardware interrupts, the DPMI host will
preserve the real mode's segment registers, CS:EIP, and
SS:ESP on the ring 0 stack. However, they are not pushed on
any stack in the VM -- They are only visible at ring 0.
When the raw mode switch functions are called they will
overwrite the information saved by the host. At this point,
the program would return to the wrong address when the
interrupt returned. For more information on state saving,
refer to the documentation on page 74.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 18
4. ERROR HANDLING
Most Int 31h calls can fail. The DPMI 0.9 specification
does not specify error return codes for most calls. When a
call fails it will set the carry flag and return with the
value in AX unmodified unless otherwise specified. However,
future DPMI implementations will return error codes in the
AX register. All specific error codes will have the high
bit (bit 15) set. If a function returns with carry set and
the high bit of AX clear, it should be treated as a general
failure. Specific error codes will allow programs running
under future DPMI implementations to take appropriate
corrective action in some cases.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 19
5. LOADING DPMI CLIENTS AND EXTENDED APPLICATIONS
All DPMI applications begin execution in real mode. An
application must run first as a standard real mode DOS
program but it can switch to protected execution by making a
few simple calls.
DPMI does not define an executable file format for protected
mode programs. Instead, programs must provide their own
mechanism for loading and fixing up protected mode code.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 20
5.1 Obtaining the Real to Protected Mode Switch Entry
Point
This function can be called in real mode to detect the
presence of DPMI services and to obtain an address that
can be used to begin execution in protected mode.
To Call
AX = 1687h
Execute an Int 2Fh (not an Int 31h)
Returns
If function was successful:
AX = 0
BX = Flags
Bit 0 = 1 if 32-bit programs are supported
CL = Processor type
02h = 80286
03h = 80386
04h = 80486
DH = DPMI major version number
DL = DPMI minor version number
SI = Number of paragraphs required for DPMI host
private data (may be 0)
ES:DI = Address of procedure to call to enter protected
mode
If function was not successful:
AX != 0
Programmer's Notes
o This function does not perform the actual
transition into protected mode. You need to call
the address returned in ES:DI, after allocating
the private data area for the DPMI host, to
perform the actual real to protected mode switch.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 21
5.2 Calling the Real to Protected Mode Switch Entry Point
After using Int 2Fh function 1687h, to obtain the
protected mode entry point, the DPMI client must call
the entry point address as described in this section.
To Call
AX = Flags
Bit 0 = 1 if program is a 32-bit application
ES = Real mode segment of DPMI host data area. This
must be the size of the data area returned in SI
from the previous function. ES will be ignored if
the required data size is zero.
Call the address returned in ES:DI by the previous
function
Returns
If function was successful:
Carry flag is clear.
Program is now executing in protected mode.
CS = 16-bit selector with base of real mode CS and a
64K limit
SS = Selector with base of real mode SS and a 64K limit
DS = Selector with base of real mode DS and a 64K limit
ES = Selector to program's PSP with a 100h byte limit
FS and GS = 0 (if running on an 80386 or 80486)
If the program is a 32-bit application the high word of
ESP will be 0
All other registers are preserved
If function was not successful:
Carry flag is set.
Program is executing in real mode
Programmer's Notes
o Once in protected mode, all Int 31h calls that are
supported by DPMI can be called.
o To terminate the program, execute an Int 21h with
AH=4Ch and AL=Error code. This is the standard
DOS exit function. Do not use any other DOS
termination call -- Only AH=4Ch is supported under
DPMI.
o Under different implementations of DPMI the
privilege ring of a program will change. Programs
should make no assumptions about the ring at which
they will run. When creating descriptors,
programs should set the DPL of the descriptor to
the same ring as their initial code segment. Use
the lar instruction to determine the protection
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 22
ring of your program's code segment. All
descriptors created by your program should be set
to the same protection level.
o Programs that specify that they are 32-bit
applications will initially run with a 16-bit code
segment. Stack and data selectors for 32-bit
programs will be 32-bit (the Big bit will be set).
However, all Int 31h calls will require 48-bit
pointers even though the program is running in a
16-bit code segment.
o Unless you have explicitly enabled the A20 address
line through the XMS interface, do not assume that
memory from 1Mb to 1Mb+64K-16 (the High Memory
Area) is addressable once your program is running
in protected mode. If you want to be able to
access the HMA then you must enable the A20
through XMS before entering protected mode. XMS
calls are not supported in protected mode. Note
that this restriction is only important for
software that wishes to access the HMA. Under all
implementations of DPMI the physical A20 address
line will always be enabled while executing
protected mode code. However, some 80386 specific
DPMI implementations simulate 1Mb address wrap for
compatibility reasons. Under these DPMI
implementations, the HMA will not be accessible
unless the A20 is enabled through the XMS
interface.
o The environment pointer in the current program's
PSP will automatically be converted to a
descriptor. If you want to free the program's
environment memory, you must do so before entering
protected mode. In this case, the environment
pointer descriptor will point to garbage and
should not be used. The DPMI client may change
the environment pointer in the PSP after entering
protected mode but it must restore it to the
selector created by the DPMI host before
terminating.
o The caller is allowed to modify or free the DS,
SS, and CS descriptors allocated by this call.
You may not modify the PSP descriptor or
environment pointer descriptor in the PSP. See
page 30 for information on freeing descriptors.
o Note that if DS=SS on entry to this call then only
one descriptor will be allocated for both DS and
SS. In this case, for example, if you changed the
base of the DS descriptor you would also change
the base of the stack segment.
o For some hosts it may be a good idea for protected
mode programs to use some or all of the real mode
memory allocated to the real mode program by DOS
for protected mode code or data. Protected mode
programs that use memory in the first 1Mb should
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 23
mark the memory as pageable using Int 31h 0602h.
See page 90 for details.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 24
Example Code
;
; Get the entry point address and save it
;
mov ax, 1687h
int 2Fh
test ax, ax
jnz Cant_Enter_PMode
mov [PMode_Entry_Seg], es
mov [PMode_Entry_Off], di
;
; Allocate memory for use by DOS extender if necessary
; NOTE: This code assumes that the program has already
; shrunk its memory block so that the DOS
; memory allocation call will work
;
test si, si
jz Enter_PMode_Now
mov bx, si
mov ah, 48h
int 21h
jc Cant_Enter_PMode
mov es, ax
;
; Enter protected mode as a 16-bit program
;
Enter_PMode_Now:
xor ax, ax
call DWORD PTR [PMode_Entry_Off]
jc Cant_Enter_PMode
;
; The program is running in protected mode now!
; Protected mode initialization code would go here.
; Mark program's real mode memory as pageable, etc.
;
.
.
.
;
; Quit the program and return to real mode DOS
;
mov ax, 4C00h
int 21h
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 25
6. TERMINATING A PROTECTED MODE PROGRAM
To terminate a protected mode program execute an Int 21h
with AH=4Ch in protected mode. You can return an error code
in the AL register. This is the standard DOS terminate API
but it must be executed in protected mode to allow the DPMI
host to clean up any data structures associated with the
protected mode program.
Programs should not be terminated from a hardware interrupt,
exception handler, or real mode call-back. Programs should
only be terminated from their main thread of execution to
allow the DPMI host to clean up properly. However, DOS
extenders that use the raw mode switch services for all mode
transitions can execute the terminate call after switching
from real to protected mode.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 26
7. MODE DETECTION
It is possible to write a program or library that can run in
either real or protected mode. This function is supplied so
that bimodal code can detect at run time whether it is
running under protected mode. Code that only runs in
protected mode does not need to perform this test.
To Call
AX = 1686h
Execute an Int 2Fh (not an Int 31h)
Returns
If executing in protected mode under DPMI:
AX = 0
If executing in real mode or not under DPMI then:
AX != 0
Programmer's Notes
o This call will return AX = 0 when the caller is
running in protected mode. It will return AX non-
zero even when running under environments that
support DPMI if the caller is in real (virtual
8086) mode. See page 20 for information on
entering protected mode.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 27
8. LDT DESCRIPTOR MANAGEMENT SERVICES
The LDT descriptor management services provide interfaces
for allocating, freeing, creating, locking and unlocking
protected mode descriptors in the current task's Local
Descriptor Table (LDT).
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 28
8.1 Allocate LDT Descriptors
This function is used to allocate one or more
descriptors from the task's Local Descriptor Table
(LDT). The descriptor(s) allocated must be initialized
by the application.
To Call
AX = 0000h
CX = Number of descriptors to allocate
Returns
If function was successful:
Carry flag is clear.
AX = Base selector
If function was not successful:
Carry flag is set.
Programmer's Notes
o If more than one descriptor was requested, AX will
contain the first of a contiguous array of
descriptors. You should add the value returned by
function 0003h (see page 32) to get to the next
selector in the array.
o The descriptor will be set to present data type,
with a base and limit of zero.
o It is up to the caller to fill in the descriptors.
o The privilege level of descriptors will match the
application's code segment privilege level. When
modifying descriptors, always set the DPL to the
same privilege ring as your program's code
segment. Use the lar instruction to determine the
privilege of a descriptor.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 29
8.2 Free LDT Descriptor
This function is used to free descriptors that were
allocated through the Allocate LDT Descriptors
function.
To Call
AX = 0001h
BX = Selector to free
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o Arrays of descriptors are freed by calling this
function for each of the individual descriptors.
o It is valid to free the descriptors allocated for
the program's initial CS, DS, and SS. Other
descriptors that were not allocated by function
0000h should never be freed by this function
unless otherwise specified.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 30
8.3 Segment to Descriptor
This function is used to convert real mode segments
into descriptors that are addressable by protected mode
programs.
To Call
AX = 0002h
BX = Real mode segment address
Returns
If function was successful:
Carry flag is clear.
AX = Selector mapped to real mode segment
If function was not successful:
Carry flag is set.
Programmer's Notes
o Multiple calls to this function with the same
segment will return the same selector.
o Descriptors created by this function should never
be modified or freed. For this reason, you should
use this function sparingly. If your program
needs to examine various real mode addresses using
the same selector you should allocate a descriptor
and change the base using the Set Segment Base
Address function instead of using this function.
o The descriptor's limit will be set to 64K.
o The intent of this function is to allow programs
easy access to commonly used real mode segments
such as 40h and A000h. Do not use this service to
obtain descriptors to private data areas.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 31
8.4 Get Next Selector Increment Value
Some functions such as allocate LDT descriptors and
allocate DOS memory can return more than one
descriptor. You must call this function to determine
the value that must be added to a selector to access
the next descriptor in the array.
To Call
AX = 0003h
Returns
Carry flag clear (this function always succeeds)
AX = Value to add to get to next selector
Programmer's Notes
o Do not make any assumptions about the value this
function will return.
o The increment value returned will be a power of
two.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 32
8.5 Reserved Subfunctions
Functions 0004h and 0005h are reserved and should not be
called.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 33
8.6 Get Segment Base Address
This function returns the 32-bit linear base address of
the specified segment.
To Call
AX = 0006h
BX = Selector
Returns
If function was successful:
Carry flag is clear.
CX:DX = 32-bit linear base address of segment
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 34
8.7 Set Segment Base Address
This function changes the 32-bit linear base address of
the specified selector.
To Call
AX = 0007h
BX = Selector
CX:DX = 32-bit linear base address for segment
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid.
o Your program should only modify descriptors that
were allocated through the Allocate LDT
Descriptors function.
o The high 8 bits of the base address (contained in
CH) will be ignored by 16-bit implementations of
DPMI. This is true even when running on 80386
machines.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 35
8.8 Set Segment Limit
This function sets the limit for the specified segment.
To Call
AX = 0008h
BX = Selector
CX:DX = 32-bit segment limit
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid or the specified limit could not
be set. 16-bit DPMI implementations can not set
segment limits greater than 0FFFFh (64K) so CX
must be zero when calling this function under
these implementations of DPMI.
o Segment limits greater than 1 meg must be page
aligned. That is, limits greater than one
megabyte must have the low 12 bits set.
o Your program should only modify descriptors that
were allocated through the Allocate LDT
Descriptors function.
o To get the limit of a segment you should use the
instruction lsl (load segment limit) which is
supported on 80286 and 80386 machines. Note that
on 80386 machines you will need to use the 32-bit
form of lsl if the segment has a limit greater
than 64K.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 36
8.9 Set Descriptor Access Rights
This function allows a protected mode program to modify
the access rights and type fields of a descriptor.
To Call
AX = 0009h
BX = Selector
CL = Access rights/type byte
CH = 80386 extended access rights/type byte (32-bit
DPMI implementations only)
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid.
o Your program should only modify descriptors that
were allocated through the Allocate LDT
Descriptors function.
o To examine the access rights of a descriptor you
should use the instruction lar (load access
rights) which is supported on 80286 and 80386
machines.
o The access rights/type byte passed in CL has the
following format:
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 37
+-------------------------------+
| P | DPL | 1 |C/D|E/C|W/R| A |
+-------+-----------------------+
| | | | | | +- 0=>Not Accessed
| | | | | | 1=>Accessed
| | | | | +-- Data: 0=>Read,
1=>R/W
| | | | | Code: Must
be 1 (readable)
| | | | +-- Data: 0=>Exp-up, 1=>Exp-
dn
| | | | Code: Must be 0
(non-conform)
| | | +-- 0=>Data, 1=>Code
| | |
| | +-- Must be 1
| |
| +-- Must equal caller's CPL
|
+- 0=>Absent, 1=>Present
A parameter which does not meet the above
requirements is invalid, and causes the function
to return with the carry flag set.
o 16-bit DPMI implementations will ignore the
extended access rights/type byte passed in CH even
if it is running on an 80386 system. 32-bit DPMI
implementations interpret the CH parameter as
follows:
+-------------------------------+
| G |B/D| 0 |Avl| Reserved |
+-----------------------+-------+
| | | | +-- Ignored
| | | +-- Can be 0 or 1
| | +-- Must be 0
| +-- 0=>Default 16-bit, 1=>Default 32-bit
+- 0=>Byte Granular, 1=>Page Granular
A parameter which does not meet the above
requirements is invalid, and causes the function
to return with the carry flag set.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 38
8.10 Create Code Segment Alias Descriptor
This function will create a data descriptor that has
the same base and limit as the specified code segment
descriptor.
To Call
AX = 000Ah
BX = Code segment selector
Returns
If function was successful:
Carry flag is clear.
AX = New data selector
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is not a code segment or is invalid.
o Use the Free LDT Descriptor function to deallocate
the alias descriptor.
o The code segment alias descriptor will not track
changes to the code descriptor. In other words,
if an alias descriptor is created, and then the
base or limit of the code segment is changed, the
alias descriptor's base or limit would not change.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 39
8.11 Get Descriptor
This function copies the descriptor table entry for a
specified descriptor into an eight byte buffer.
To Call
AX = 000Bh
BX = Selector
ES:(E)DI = Pointer to an 8 byte buffer to receive copy
of descriptor
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Pointer to buffer that contains descriptor
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid or unallocated.
o 32-bit programs must use ES:EDI to point to the
buffer. 16-bit programs should use ES:DI.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 40
8.12 Set Descriptor
This function copies an eight byte buffer into the LDT
entry for a specified descriptor.
To Call
AX = 000Ch
BX = Selector
ES:(E)DI = Pointer to an 8 byte buffer that contains
descriptor
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is invalid.
o Your program should only modify descriptors that
were allocated through the Allocate LDT
Descriptors function.
o 32-bit programs must use ES:EDI to point to the
buffer. 16-bit programs should use ES:DI.
o The type byte (byte 5) follows the same format and
restrictions as the access rights/type parameter
(in CL) to Set Descriptor Access Rights. The
extended type byte (byte 6) follows the same
format and restrictions as the extended access
rights/type parameter (in CH) to Set Descriptor
Access Rights, except the limit field may have any
value, except the low order 4 bits (marked
"reserved") are used to set the upper 4 bits of
the descriptor's limit.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 41
8.13 Allocate Specific LDT Descriptor
This function attempts to allocate a specific LDT
descriptor.To Call
AX = 000Dh
BX = Selector
Returns
If function was successful:
Carry flag is clear.
Descriptor has been allocated
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function will fail if the selector specified
in BX is in use or is not an LDT selector.
o Use function 0001h to free the descriptor.
o The first 10h (16 decimal) descriptors must be
reserved for this function and may not be used by
the host.
o If another application has already loaded then
some of these descriptors may be in use.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 42
9. DOS MEMORY MANAGEMENT SERVICES
Some applications require the ability to allocate memory in
the real mode addressable 1 megabyte region. These services
allow protected mode applications to allocate and free
memory that is directly addressable by real mode software
such as networks and DOS device drivers. Often, this memory
is used in conjunction with the API translation services to
call real mode software that is not directly supported by
DPMI.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 43
9.1 Allocate DOS Memory Block
This function will allocate a block of memory from the
DOS free memory pool. It returns both the real mode
segment and one or more descriptors that can be used by
protected mode applications to access the block.
To Call
AX = 0100h
BX = Number of paragraphs (16 byte blocks) desired
Returns
If function was successful:
Carry flag is clear.
AX = Initial real mode segment of allocated block
DX = Selector for allocated block
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as
requested
BX = Size of largest available block in paragraphs
Programmer's Notes
o If the size of the block requested is greater than
64K bytes (BX > 1000h) then contiguous descriptors
will be allocated. To access the next descriptor
for the memory block add the value return by
function 0003h (see page 32) to the base selector.
If more than one descriptor is allocated under 32-
bit DPMI implementations, the limit of the first
descriptor will be set to the size of the entire
block. All subsequent descriptors will have a
limit of 64K except for the final descriptor which
will have a limit of Block size MOD 64K. 16-bit
DPMI implementations will always set the limit of
the first descriptor to 64K even when running on
an 80386.
o Your program should never modify or deallocate any
descriptors allocated by this function. The Free
DOS Memory Block function will deallocate the
descriptors automatically
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 44
9.2 Free DOS Memory Block
This function frees memory that was allocated through
the Allocate DOS Memory Block function.
To Call
AX = 0101h
DX = Selector of block to free
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
09h incorrect memory segment specified
Programmer's Notes
o All descriptors allocated for the memory block are
automatically freed and therefore should not be
accessed once the block is freed by this function.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 45
9.3 Resize DOS Memory Block
This function is used to grow or shrink a memory block
that was allocated through the Allocate DOS Memory
Block function.
To Call
AX = 0102h
BX = New block size in paragraphs
DX = Selector of block to modify
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as
requested
09h incorrect memory segment specified
BX = Maximum block size possible in paragraphs
Programmer's Notes
o Growing a memory block is often likely to fail
since other DOS block allocations will prevent
increasing the size of the block. Also, if the
size of a block grows past a 64K boundary then the
allocation will fail if the next descriptor in the
LDT is not free. Therefore, this function is
usually only used to shrink a block.
o Shrinking a block may cause some descriptors that
were previously allocated to the block to be
freed. For example shrinking a block from 140K to
120K would cause the third allocated descriptor to
be freed since it is no longer valid. The initial
selector will remain unchanged, however, the
limits of the remaining two descriptors will
change: the first to 120K and the second to 56k.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 46
10. INTERRUPT SERVICES
These services allow protected mode applications to
intercept real and protected mode interrupts and hook
processor exceptions.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 47
10.1 Get Real Mode Interrupt Vector
This function returns the value of the current task's
real mode interrupt vector for the specified interrupt.
To Call
AX = 0200h
BL = Interrupt number
Returns
Carry flag is clear.
CX:DX = Segment:Offset of real mode interrupt handler
Programmer's Notes
o The address returned in CX is a segment, not a
selector. Therefore you should not attempt to
place the value returned in CX into a segment
register in protected mode or a general protection
fault may occur.
o Note all 100h (256 decimal) interrupt vectors must
be supported by the DPMI host.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 48
10.2 Set Real Mode Interrupt Vector
This function sets the value of the current task's real
mode interrupt vector for the specified interrupt.
To Call
AX = 0201h
BL = Interrupt number
CX:DX = Segment:Offset of real mode interrupt handler
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o The address passed in CX must be a real mode
segment, not a selector.
o If the interrupt being hooked is a hardware
interrupt then you must lock the segment that the
interrupt handler runs in as well as any memory
the handler may touch at interrupt time.
o The address contained in CX:DX must be a real mode
segment:offset, not a selector:offset. This means
that the code for the interrupt handler must
either reside in DOS addressable memory or you
must use a real mode call-back address. Refer to
the section on DOS memory management services on
page 43 for information on allocating memory below
1 megabyte. Information on real mode call back
addresses can be found on page 68.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 49
10.3 Get Processor Exception Handler Vector
This function returns the CS:(E)IP of the current
protected mode exception handler for the specified
exception number.
To Call
AX = 0202h
BL = Exception/fault number (00h-1Fh)
Returns
If function was successful:
Carry flag is clear.
CX:(E)DX = Selector:Offset of exception handler
If function was not successful:
Carry flag is set.
The value passed in BL was invalid.
Programmer's Notes
o The value returned in CX is a valid protected mode
selector, not a real mode segment.
o 32-bit mode programs will be returned a 32-bit
offset in the EDX register.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 50
10.4 Set Processor Exception Handler Vector
This function allows protected mode applications to
intercept processor exceptions that are not handled by
the DPMI environment. Programs may wish to handle
exceptions such as not present segment faults which
would otherwise generate a fatal error.
Every exception is first examined by the protected mode
operating system. If it can not handle the exception
it then reflects it through the protected mode
exception handler chain. The final handler in the
chain may either reflect the exception as an interrupt
(as would happen in real mode) or it may terminate the
current program.
To Call
AX = 0203h
BL = Exception/fault number (00h-1Fh)
CX:(E)DX = Selector:Offset of exception handler
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
The value passed in BL was invalid.
Programmer's Notes
o The value passed in CX must be a valid protected
mode code selector, not a real mode segment.
o 32-bit mode programs must supply a 32-bit offset
in the EDX register. If your handler chains to
the next exception handler it must do so using a
32-bit interrupt stack frame.
o The handler should return using a far return
instruction. The original SS:(E)SP, CS:(E)IP and
flags on the stack, including the interrupt flag,
will be restored.
o All fault stack frames have an error code.
However, the error code is only valid for
exceptions 08h, 0Ah, 0Bh, 0Ch, 0Dh, and 0Eh.
o The handler must preserve and restore all
registers.
o The exception handler will be called on a locked
stack with interrupts disabled. The original SS,
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 51
(E)SP, CS, and (E)IP will be pushed on the
exception handler stack frame.
o The handler must either return from the call by
executing a far return or jump to the next handler
in the chain (which will execute a far return or
chain to the next handler).
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 52
o The procedure can modify any of the values on the
stack pertaining to the exception before
returning. This can be used, for example, to jump
to a procedure by modifying the CS:IP on the
stack. Note that the procedure must not modify
the far return address on the stack -- it must
return to the original caller. The caller will
then restore the flags, CS:(E)IP and SS:(E)SP from
the stack frame.
o If the DPMI client does not handle an exception,
or jumps to the default exception handler, the
host will reflect the exception as an interrupt
for exceptions 0, 1, 2, 3, 4, 5, and 7.
Exceptions 6, and 8-1Fh will be treated as fatal
errors and the client will be terminated.
o Exception handlers will only be called for
exceptions that occur in protected mode.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 53
Call-Back Stack Frames
Stack frame for 16-bit programs:
15 0
SS
SP
Flags
CS
IP
Err Code
Return
CS
Return
IP
<-- SS:SP
Stack frame for 32-bit programs:
31 0
SS
ESP
EFlags
CS
EIP
Error Code
Ret CS
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 54
Return EIP
<-- SS:ESP
Shaded fields should not be modified. Other fields can
be modified before returning from the exception
handler.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 55
10.5 Get Protected Mode Interrupt Vector
This function returns the CS:(E)IP of the current
protected mode interrupt handler for the specified
interrupt number.
To Call
AX = 0204h
BL = Interrupt number
Returns
Carry flag is clear.
CX:(E)DX = Selector:Offset of exception handler
Programmer's Notes
o The value returned in CX is a valid protected mode
selector, not a real mode segment.
o 32-bit mode programs will be returned a 32-bit
offset in the EDX register.
o All 100h (256 decimal) interrupt vectors must be
supported by the DPMI host.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 56
10.6 Set Protected Mode Interrupt Vector
This function sets the address of the specified
protected mode interrupt vector.
To Call
AX = 0205h
BL = Interrupt number
CX:(E)DX = Selector:Offset of exception handler
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o The value passed in CX must be a valid protected
mode code selector, not a real mode segment.
o 32-bit mode programs must supply a 32-bit offset
in the EDX register. If your handler chains to
the next exception handler it must do so using a
32-bit interrupt stack frame.
o Note all 100h (256 decimal) interrupt vectors must
be supported by the DPMI host.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 57
11. TRANSLATION SERVICES
These services are provided so that protected mode programs
can call real mode software that DPMI does not support
directly. The protected mode program sets up a data
structure that contains the values for every register. The
data structure is defined as:
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 58
Offset Register
00h EDI
04h ESI
08h EBP
0Ch Reserved by system
10h EBX
14h EDX
18h ECX
1Ch EAX
20h Flags
22h ES
24h DS
26h FS
28h GS
2Ah IP
2Ch CS
2Eh SP
30h SS
You will notice that all of the fields are dwords so that 32
bit registers can be passed to real mode. Most real mode
software will ignore the high word of the extended
registers. However, you can write a real mode procedure
that uses 32-bit registers if you desire. Note that 16-bit
DPMI implementations may not pass the high word of 32-bit
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 59
registers or the FS and GS segment registers to real mode
even when running on an 80386 machine.
Any interrupt handler or procedure called must return with
the stack in the same state as when it was called. This
means that the real mode code may switch stacks while it is
running but it must return on the same stack that it was
called on and it must pop off the entire far return/iret
structure.
After the call or interrupt is complete, all real mode
registers and flags except SS, SP, CS, and IP will be copied
back to the real mode call structure so that the caller can
examine the real mode return values.
Remember that the values in the segment registers should be
real mode segments, not protected mode selectors.
The translation services will provide a real mode stack if
the SS:SP fields are zero. However, the stack provided is
relatively small. If the real mode procedure/interrupt
routine uses more than 30 words of stack space then you
should provide your own real mode stack.
It is possible to pass parameters to real mode software on
the stack. The following code will call a real mode
procedure with 3 word parameters:
Protected_Mode_Code:
push Param1
push Param2
push Param3
(Set ES:DI to point to call structure)
mov cx, 3 ; Copy 3 words
mov ax, 0301h ; Call real mode proc
int 31h ; Call the procedure
add sp, 6 ; Clean up stack
The real mode procedure would be called with the following
data on the real mode stack:
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 60
Param1
Param2
Param3
Return
CS
Return
IP
<-- Real mode SS:SP
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 61
If your program needs to perform a series of calls to a real
mode API it is sometimes more convenient to use the
translation services to call a real mode procedure in your
own program. That procedure can then issue the API calls in
real mode and then return to protected mode. This also
avoids the overhead of a mode switch for each API call.
There is also a mechanism for protected mode software to
gain control from real mode via a real mode call-back
address. Real mode call-backs can be used to hook real mode
interrupts or to be called in protected mode by a real mode
driver. For example, many mouse drivers will call a
specified address whenever the mouse is moved. This service
allows the call-back to be handled by software running in
protected mode.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 62
11.1 Simulate Real Mode Interrupt
This function simulates an interrupt in real mode. It
will invoke the CS:IP specified by the real mode
interrupt vector and the handler must return by
executing an iret.
To Call
AX = 0300h
BL = Interrupt number
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
Programmer's Notes
o The CS:IP in the real mode call structure is
ignored by this service. The appropriate
interrupt handler will be called based on the
value passed in BL.
o If the SS:SP fields are zero then a real mode
stack will be provided by the DPMI host.
Otherwise, the real mode SS:SP will be set to the
specified values before the interrupt handler is
called.
o The flags specified in the real mode call
structure will be pushed on the real mode stack
iret frame. The interrupt handler will be called
with the interrupt and trace flags clear.
o When the Int 31h returns, the real mode call
register structure will contain the values that
were returned by the real mode interrupt handler.
o It is up to the caller to remove any parameters
that were pushed on the protected mode stack.
o 32-bit programs must use ES:EDI to point to the
real mode call structure. 16-bit programs should
use ES:DI.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 63
o The flag to reset the interrupt controller and A20
line is ignored by DPMI implementations that run
in Virtual 8086 mode. It causes DPMI
implementations that return to real mode to set
the interrupt controller and A20 address line
hardware to its normal real mode state.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 64
11.2 Call Real Mode Procedure With Far Return Frame
This function calls a real mode procedure. The called
procedure must execute a far return when it completes.
To Call
AX = 0301h
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
Programmer's Notes
o The CS:IP in the real mode call structure
specifies the address of the real mode procedure
to call.
o The real mode procedure must execute a far return
when it has completed.
o If the SS:SP fields are zero then a real mode
stack will be provided by the DPMI host.
Otherwise, the real mode SS:SP will be set to the
specified values before the procedure is called.
o When the Int 31h returns, the real mode call
structure will contain the values that were
returned by the real mode procedure.
o It is up to the caller to remove any parameters
that were pushed on the protected mode stack.
o 32-bit programs must use ES:EDI to point to the
real mode call structure. 16-bit programs should
use ES:DI.
o The flag to reset the interrupt controller and A20
line is ignored by DPMI implementations that run
in Virtual 8086 mode. It causes DPMI
implementations that return to real mode to set
the interrupt controller and A20 address line
hardware to its normal real mode state.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 65
11.3 Call Real Mode Procedure With Iret Frame
This function calls a real mode procedure. The called
procedure must execute an iret when it completes.
To Call
AX = 0302h
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
Programmer's Notes
o The CS:IP in the real mode call structure
specifies the address of the real mode procedure
to call.
o The real mode procedure must execute an iret when
it has completed.
o If the SS:SP fields are zero then a real mode
stack will be provided by the DPMI host.
Otherwise, the real mode SS:SP will be set to the
specified values before the procedure is called.
o When the Int 31h returns, the real mode call
structure will contain the values that were
returned by the real mode procedure.
o The flags specified in the real mode call
structure will be pushed the real mode stack iret
frame. The procedure will be called with the
interrupt and trace flags clear.
o It is up to the caller to remove any parameters
that were pushed on the protected mode stack.
o 32-bit programs must use ES:EDI to point to the
real mode call structure. 16-bit programs should
use ES:DI.
o The flag to reset the interrupt controller and A20
line is ignored by DPMI implementations that run
in Virtual 8086 mode. It causes DPMI
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 66
implementations that return to real mode to set
the interrupt controller and A20 address line
hardware to its normal real mode state.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 67
11.4 Allocate Real Mode Call-Back Address
This service is used to obtain a unique real mode
SEG:OFFSET that will transfer control from real mode to
a protected mode procedure.
At times it is necessary to hook a real mode interrupt
or device call-back in a protected mode driver. For
example, many mouse drivers call an address whenever
the mouse is moved. Software running in protected mode
can use a real mode call-back to intercept the mouse
driver calls.
To Call
AX = 0303h
DS:(E)SI = Selector:Offset of procedure to call
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
CX:DX = Segment:Offset of real mode call address
If function was not successful:
Carry flag is set.
Call-Back Procedure Parameters
Interrupts disabled
DS:(E)SI = Selector:Offset of real mode SS:SP
ES:(E)DI = Selector:Offset of real mode call structure
SS:(E)SP = Locked protected mode API stack
All other registers undefined
Return from Call-Back Procedure
Execute an IRET to return
ES:(E)DI = Selector:Offset of real mode call structure
to restore (see note)
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 68
Programmer's Notes
o Since the real mode call structure is static, you
must be careful when writing code that may be
reentered. The simplest method of avoiding
reentrancy is to leave interrupts disabled
throughout the entire call. However, if the
amount of code executed by the call-back is large
then you will need to copy the real mode call
structure into another buffer. You can then
return with ES:(E)DI pointing to the buffer you
copied the data to -- it does not have to point to
the original real mode call structure.
o The called procedure is responsible for modifying
the real mode CS:IP before returning. If the real
mode CS:IP is left unchanged then the real mode
call-back will be executed immediately and your
procedure will be called again. Normally you will
want to pop a return address off of the real mode
stack and place it in the real mode CS:IP. The
example code in the next section demonstrates
chaining to another interrupt handler and
simulating a real mode iret.
o To return values to the real mode caller you must
modify the real mode call structure.
o Remember that all segment values in the real mode
call structure will contain real mode segments,
not selectors. If you need to examine data
pointed to by a real mode seg:offset pointer you
should not use the segment to selector service to
create a new selector. Instead, allocate a
descriptor during initialization and change the
descriptor's base to 16 times the real mode
segment's value. This is important since
selectors allocated though the segment to selector
service can never be freed.
o DPMI hosts should provide a minimum of 16 call-
back addresses per task.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 69
Example Code
The following code is a sample of a real mode interrupt
hook. It hooks the DOS Int 21h and returns an error
for the delete file function (AH=41h). Other calls are
passed through to DOS. This example is somewhat silly
but it demonstrates the techniques used to hook a real
mode interrupt. Note that since DOS calls are
reflected from protected mode to real mode, the
following code will intercept all DOS calls from both
real mode and protected mode.
;******************************************************
; This procedure gets the current Int 21h real mode
; Seg:Offset, allocates a real mode call-back address,
; and sets the real mode Int 21h vector to the call-
; back address.
;******************************************************
Initialization_Code:
;
; Create a code segment alias to save data in
;
mov ax, 000Ah
mov bx, cs
int 31h
jc ERROR
mov ds, ax
ASSUMES DS,_TEXT
;
; Get current Int 21h real mode SEG:OFFSET
;
mov ax, 0200h
mov bl, 21h
int 31h
jc ERROR
mov [Orig_Real_Seg], cx
mov [Orig_Real_Offset], dx
;
; Allocate a real mode call-back
;
mov ax, 0303h
push ds
mov bx, cs
mov ds, bx
mov si, OFFSET My_Int_21_Hook
pop es
mov di, OFFSET My_Real_Mode_Call_Struc
int 31h
jc ERROR
;
; Hook real mode int 21h with the call-back address
;
mov ax, 0201h
mov bl, 21h
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 70
int 31h
jc ERROR
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 71
;******************************************************
;
; This is the actual Int 21h hook code. It will return
; an "access denied" error for all calls made in real
; mode to delete a file. Other calls will be passed
; through to DOS.
;
; ENTRY:
; DS:SI -> Real mode SS:SP
; ES:DI -> Real mode call structure
; Interrupts disabled
;
; EXIT:
; ES:DI -> Real mode call structure
;
;******************************************************
My_Int_21_Hook:
cmp es:[di.RealMode_AH], 41h
jne Chain_To_DOS
;
; This is a delete file call (AH=41h). Simulate an
; iret on the real mode stack, set the real mode
; carry flag, and set the real mode AX to 5 to indicate
; an access denied error.
;
cld
lodsw ; Get real mode ret IP
mov es:[di.RealMode_IP], ax
lodsw ; Get real mode ret CS
mov es:[di.RealMode_CS], ax
lodsw ; Get real mode flags
or ax, 1 ; Set carry flag
mov es:[di.RealMode_Flags], ax
add es:[di.RealMode_SP], 6
mov es:[di.RealMode_AX], 5
jmp My_Hook_Exit
;
; Chain to original Int 21h vector by replacing the
; real mode CS:IP with the original Seg:Offset.
;
Chain_To_DOS:
mov ax, cs:[Orig_Real_Seg]
mov es:[di.RealMode_CS], ax
mov ax, cs:[Orig_Real_Offset]
mov es:[di.RealMode_IP], ax
My_Hook_Exit:
iret
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 72
11.5 Free Real Mode Call-Back Address
This function frees a real mode call-back address that
was allocated through the allocate real mode call-back
address service.
To Call
AX = 0304h
CX:DX = Real mode call-back address to free
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o Real mode call-backs are a limited resource. Your
code should free any break point that it is no
longer using.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 73
11.6 Get State Save/Restore Addresses
When a program uses the raw mode switch services (see
page 77) or issues DOS calls from a hardware interrupt
handler, it will need to save the state of the current
task before changing modes. This service returns the
addresses of two procedures used to save the state of
the current task's registers. For example, the real
mode address is used to save the state of the protected
mode registers. The protected mode address is used to
save the state of the real mode registers. This can be
used to save the state of the alternate mode's
registers before they are modified by the mode switch
call. The current mode's registers can be saved by
simply pushing them on the stack.
Note: It is not necessary to call this service if
using the translation services 0300h, 0301h or 0302h.
It is provided for programs that use the raw mode
switch service.
To Call
AX = 0305h
Returns
If function was successful:
Carry flag is clear
AX = Size of buffer in bytes required to save state
BX:CX = Real mode address used to save/restore state
SI:(E)DI = Protected mode address used to save/restore
state
If function was not successful:
Carry flag is set
Parameters To State-Save Procedures
Execute a far call to the appropriate address (real or
pmode) with:
ES:(E)DI = Pointer to state-save buffer
AL = 0 to save state
AL = 1 to restore state
Programmer's Notes
o Some implementations of DPMI will not require the
state to be saved. In this case, the buffer size
returned will be zero. However, it is still valid
to call the addresses returned, although they will
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 74
just return without performing any useful
function.
o The save/restore functions will not modify any
registers.
o The address returned in BX:CX must only be called
in real mode. The address returned in SI:(E)DI
must only be called in protected mode.
o 16-bit programs should call the address returned
in SI:DI to save the real mode state. 32-bit
programs should call the address returned in
SI:EDI.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 75
Example Code
The following code is a sample protected mode timer
interrupt handler that saves the state of the real mode
registers, issues DOS calls, and restores the state.
This code assumes that the Int 31h function 0305h has
been executed and that the call address and buffer size
have been saved in local variables.
Sample_Timer_Code:
pushf
call FAR PTR cs:[Next_Timer_Handler]
sti
;
; Save protected mode registers
;
push ds
push es
pusha
;
; Save real mode registers
;
mov ds, cs:[My_Local_DS]
mov ax, ss
mov es, ax
sub sp, [State_Save_Size]
mov di, sp
xor al, al
call [PM_Save_Restore_State]
;
; Raw mode switch here
;
.
.
.
;
; Restore real mode registers
;
mov ax, ss
mov es, ax
mov di, sp
mov al, 1
call [PM_Save_Restore_State]
add sp, [State_Save_Size]
;
; Restore protected mode registers and return
;
popa
pop es
pop ds
iret
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 76
11.7 Get Raw Mode Switch Addresses
This function returns addresses that can be jumped to
for low-level mode switching.To Call
AX = 0306h
Returns
If function was successful:
Carry flag is clear
BX:CX = Real -> Protected mode switch address
SI:(E)DI = Protected -> Real mode switch address
If function was not successful:
Carry flag is set
Parameters To State-Save Procedures
Execute a far jump to the appropriate address (real or
pmode) with:
AX = New DS
CX = New ES
DX = New SS
(E)BX = New (E)SP
SI = New CS
(E)DI = New (E)IP
The processor will be placed in the desired mode. The
DS, ES, SS, (E)SP, CS, and (E)IP will contain the
values specified. The (E)BP register will be preserved
across the call and so can be used as a pointer. The
values in (E)AX, (E)BX, (E)CX, (E)DX, (E)SI, and (E)DI
will be undefined. On an 80386 or 80486 the FS and GS
segment registers will contain zero after the mode
switch.
Programmer's Notes
o The address returned in BX:CX must only be called
in real mode to switch into protected mode. The
address returned in SI:(E)DI must only be called
in protected mode to switch into real mode.
o 16-bit programs should call the address returned
in SI:DI to switch from protected to real mode.
32-bit programs should call the address returned
in SI:EDI.
o It is up to the caller to save and restore the
state of the task when using this function to
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 77
switch modes. This usually requires using the
state save function (see page 74).
o The parameters must contain segment values
appropriate for the mode that is being switched
to. If invalid selectors are specified when
switching into protected mode, an exception will
occur.
o Applications may find functions 0300h, 0301h,
0302h, and 0304h more convenient to use than using
this type of mode switching.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 78
12. GET VERSION
Function 0400h returns the version of DPMI services
supported. Note that this is not necessarily the version of
any operating system that supports DPMI. It should be used
by programs to determine what calls are legal in the current
environment.
To Call
AX = 0400h
Returns
AH = Major version
AL = Minor version
BX = Flags
Bit 0 = 1 if running under an 80386 DPMI
implementation
Bit 1 = 1 if processor is returned to real mode
for reflected interrupts (as opposed to Virtual
8086 mode).
Bit 2 = 1 if virtual memory is supported
Bit 3 is reserved and undefined
All other bits are zero and reserved for later use
CL = Processor type
02 = 80286
03 = 80386
04 = 80486
DH = Current value of virtual master PIC base interrupt
DL = Current value of virtual slave PIC base interrupt
Carry flag clear (call can not fail)
Programmer's Notes
None
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 79
13. MEMORY MANAGEMENT SERVICES
These functions are provided to allocate linear address
space.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 80
13.1 Get Free Memory Information
This function is provided so that protected mode
applications can determine how much memory is
available. Under DPMI implementations that support
virtual memory, it is important to consider issues such
as the amount of available physical memory.
Note that since DPMI applications will often run in
multi-tasking environments, this function must be
considered only advisory.
To Call
AX = 0500h
ES:(E)DI = Selector:Offset of 30h byte buffer
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of buffer with the following
structure:
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 81
Offset Description
00h Largest available free block in
bytes
04h Maximum unlocked page allocation
08h Maximum locked page allocation
0Ch Linear addr space size in pages
10h Total number of unlocked pages
14h Number of free pages
18h Total number of physical pages
1Ch Free linear address space in pages
20h Size of paging file/partition in
pages
24h-2Fh Reserved
If function was not successful:
Carry flag is set.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 82
Programmer's Notes
o 32-bit programs must use ES:EDI to point to the
buffer. 16-bit programs should use ES:DI.
o DPMI implementations that do not support virtual
memory (returned in flags from Get Version call)
will only fill in the first field. This value
specifies that largest allocation that could be
made using function 0501h. Other fields will be
set to -1.
o Only the first field of this structure is
guaranteed to contain a valid value. All fields
that are not returned by the DPMI implementation
will be set to -1 (0FFFFFFFFh) to indicate that
the information is not available.
o The field at offset 00h specifies the largest
block of contiguous linear memory in bytes that
could be allocated if the memory were to be
allocated and left unlocked.
o The field at offset 04h specifies the number of
pages that could be allocated. This is the value
returned by field 00h / page size.
o The field at offset 08h specifies the largest
block of memory in pages that could be allocated
and then locked.
o The field at offset 0Ch specifies the size of the
total linear address space in pages. This
includes all linear address space that has already
been allocated.
o The field at offset 10h specifies the total number
of pages that are currently unlocked and could be
paged out. This value also contains any free
pages.
o The field at offset 14h specifies the number of
physical pages that currently are not in use.
o The field at offset 18h specifies the total number
of physical pages that the DPMI host manages.
This value includes all free, locked, and unlocked
physical pages.
o The field at offset 20h specifies the size of the
DPMI host's paging partition or file in pages.
o To determine the size of pages for the DPMI host
call the Get Page Size service (see page 93).
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 83
13.2 Allocate Memory Block
This function allocates and commits linear memory.
To Call
AX = 0501h
BX:CX = Size of memory block to allocate in bytes
Returns
If function was successful:
Carry flag is clear
BX:CX = Linear address of allocated memory block
SI:DI = Memory block handle (used to resize and free)
If function was unsuccessful:
Carry flag is set
Programmer's Notes
o This function does not allocate any selectors for
the memory block. It is the responsibility of the
caller to allocate and initialize any selectors
needed to access the memory.
o Under DPMI implementations that support virtual
memory the memory block will be allocated
unlocked. If some or all of the memory should be
locked you will need to use either the lock
selector function or the lock linear region
function.
o Under many implementations of DPMI, allocations
will be page granular. This means that an
allocation of 1001h bytes will result in an
allocation of 2000h bytes. Therefore it is best
to always allocate memory in multiples of 4K.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 84
13.3 Free Memory Block
This function frees a memory block that was allocate
through the allocate memory block function.
To Call
AX = 0502h
SI:DI = Handle of memory block to free
Returns
If function was successful:
Carry flag is clear
If function was unsuccessful:
Carry flag is set
Programmer's Notes
o Your program must also free any selectors that it
allocated to point to the memory block.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 85
13.4 Resize Memory Block
This function changes the size of a memory block that
was allocated through the allocate memory block
function.
To Call
AX = 0503h
BX:CX = New size of memory block to allocate in bytes
SI:DI = Handle of memory block to resize
Returns
If function was successful:
Carry flag is clear
BX:CX = New linear address of memory block
SI:DI = New handle of memory block
If function was unsuccessful:
Carry flag is set
Programmer's Notes
o This function may change the linear address of the
memory block and the memory handle. Therefore,
you will need to update any selectors that point
to the block after resizing it. You must use the
new handle instead of the old one.
o This function will generate an error if a memory
block is resized to 0 bytes.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 86
14. PAGE LOCKING SERVICES
These services are only useful under DPMI implementations
that support virtual memory. They will be ignored by 16-bit
DPMI implementations (although they will always return with
carry clear to indicate success).
Some implementations of DPMI may ignore these calls.
However, if the calls are ignored then the DPMI host will be
able to handle page faults at arbitrary points during the
application's execution including interrupt and exception
handler code.
Although memory ranges are specified in bytes, the actual
unit of memory that will be locked will be one or more
pages. Page locks are maintained as a count. When the
count is decremented to zero, the page is unlocked and can
be swapped to disk. This means that if a region of memory
is locked three times then it must be unlocked three times
before the pages will be unlocked.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 87
14.1 Lock Linear Region
This function locks a specified linear address range.
To Call
AX = 0600h
BX:CX = Starting linear address of memory to lock
SI:DI = Size of region to lock in bytes
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o If this function fails then none of the memory
will be locked.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be locked.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 88
14.2 Unlock Linear Region
This function unlocks a specified linear address range
that was previously locked using the Lock Linear Region
function.
To Call
AX = 0601h
BX:CX = Starting linear address of memory to unlock
SI:DI = Size of region to unlock in bytes
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o If this function fails then none of the memory
will be unlocked.
o An error will be returned if the memory was not
previously locked or if the specified region is
invalid.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be unlocked.
o Even if the function succeeds, the memory will
remain locked if the lock count is not decremented
to zero.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 89
14.3 Mark Real Mode Region as Pageable
Under some implementations of DPMI, all memory in
virtual 8086 mode is locked by default. If a protected
mode program is using memory in the first megabyte of
address space, it is a good idea to use this function
to turn off automatic page locking for regions of
memory that will not be touched at interrupt time.
Do not mark memory as pageable in regions that are not
owned by your application. For example, you should not
mark all free DOS memory as pageable since it may cause
a page fault to occur while inside of DOS (causing a
crash). Also, do not mark the DPMI host data area as
pageable.
It is very important to relock any real mode memory
using function 0603h before terminating a program.
Memory that remains unlocked after a program has
terminated could result in fatal page faults when other
software is executed in that address space.
Note that address space marked as pageable by this
function can be locked using function 0600h. This
function is just an advisory service to allow memory
that does not need to be locked to be paged out. This
function just disables any automatic locking of real
mode memory performed by the DPMI host.
To Call
AX = 0602h
BX:CX = Starting linear address of memory to mark as
pageable
SI:DI = Size of region to page in bytes
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o If this function fails then none of the memory
will be unlocked.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be not be marked as pageable.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 90
o When your program terminates it should call
function 0603h to relock the memory region.
o Unlike the lock and unlock calls, the pageability
of the real mode region is maintained as a binary
state, not a count. Therefore, do not call this
function multiple times for a given linear region.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 91
14.4 Relock Real Mode Region
This function is used to relock memory regions that
were marked as pageable by the previous function.
To Call
AX = 0603h
BX:CX = Starting linear address of memory to relock
SI:DI = Size of region to page in bytes
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o If this function fails then none of the memory
will be relocked.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be not be relocked.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 92
14.5 Get Page Size
This function returns the size of a single memory page
in bytes.
To Call
AX = 0604h
Returns
If function was successful:
Carry flag is clear
BX:CX = Page size in bytes
If function was not successful:
Carry flag is set
Programmers Notes
None
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 93
15. DEMAND PAGING PERFORMANCE TUNING SERVICES
Some applications will discard memory objects or will not
access objects for long periods of time. These services can
be used to improve the performance of demand paging.
Although these functions are only relevant for DPMI
implementations that support virtual memory, other
implementations will ignore these functions (it will always
return carry clear). Therefore your code can always call
these functions regardless of the environment it is running
under.
Since both of these functions are simply advisory functions,
the operating system may choose to ignore them. In any
case, your code should function properly even if the
functions fail.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 94
15.1 Reserved Subfunctions
Functions 0700h and 0701h are reserved and should not
be called.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 95
15.2 Mark Page as Demand Paging Candidate
This function is used to inform the operating system
that a range of pages should be placed at the head of
the page out candidate list. This will force these
pages to be swapped to disk ahead of other pages even
if the memory has been accessed recently. However, all
memory contents will be preserved.
This is useful, for example, if a program knows that a
given piece of data will not be accessed for a long
period of time. That data is ideal for swapping to
disk since the physical memory it now occupies can be
used for other purposes.
To Call
AX = 0702h
BX:CX = Starting linear address of pages to mark
SI:DI = Number of bytes to mark as paging candidates
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o This function does not force the pages to be
swapped to disk immediately.
o Partial pages will not be discarded.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 96
15.3 Discard Page Contents
This function discards the entire contents of a given
linear memory range. It is used after a memory object
that occupied a given piece of memory has been
discarded.
The contents of the region will be undefined the next
time the memory is accessed. All values previously
stored in this memory will be lost.
To Call
AX = 0703h
BX:CX = Starting linear address of pages to discard
SI:DI = Number of bytes to discard
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Programmer's Notes
o Partial pages will not be discarded.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 97
16. PHYSICAL ADDRESS MAPPING
Memory mapped devices such as network adapters and displays
sometimes have memory mapped at physical addresses that lie
outside of the normal 1Mb of memory that is addressable in
real mode. Under many implementations of DPMI, all
addresses are linear addresses since they use the paging
mechanism of the 80386. This service can be used by device
drivers to convert a physical address into a linear address.
The linear address can then be used to access the device
memory.
Some implementations of DPMI may not support this call
because it could be used to circumvent system protection.
This call should only be used by programs that absolutely
require direct access to a memory mapped device.
To Call
AX = 0800h
BX:CX = Physical address of memory
SI:DI = Size of region to map in bytes
Returns
If function was successful:
Carry flag is clear.
BX:CX = Linear address that can be used to access the
physical memory
If function was not successful:
Carry flag is set.
Programmer's Notes
o Under DPMI implementations that do not use the
80386 paging mechanism, the function will always
succeed and the address returned will be equal to
the physical address parameter passed into this
function.
o It is up to the caller to build an appropriate
selector to access the memory.
o Do not use this service to access memory that is
mapped in the first megabyte of address space (the
real mode addressable region).
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 98
17. VIRTUAL INTERRUPT STATE FUNCTIONS
Under many implementations of DPMI, the interrupt flag in
protected mode will always be set (interrupts enabled).
This is because the program is running under a protected
operating system that can not allow programs to disable
physical hardware interrupts. However, the operating system
will maintain a "virtual" interrupt state for protected mode
programs. When the program executes a cli instruction, the
program's virtual interrupt state will be disabled, and the
program will not receive any hardware interrupts until it
executes an sti to reenable interrupts (or calls service
0901h).
When a protected mode program executes a pushf instruction,
the real processor flags will be pushed onto the stack.
Thus, examining the flags pushed on the stack is not
sufficient to determine the state of the program's virtual
interrupt flag. These services enable programs to get and
modify the state of their virtual interrupt flag.
The following sample code enters an interrupt critical
section and then restores the virtual interrupt state to
it's previous state.
;
; Disable interrupts and get previous interrupt state
;
mov ax, 0900h
int 31h
;
; At this point AX = 0900h or 0901h
;
.
.
.
;
; Restore previous state (assumes AX unchanged)
;
int 31h
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 99
17.1 Get and Disable Virtual Interrupt State
This function will disable the virtual interrupt flag
and return the previous state of the virtual interrupt
flag.
To Call
AX = 0900h
Returns
Carry flag clear (this function always succeeds)
Virtual interrupts are disabled
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
Programmer's Notes
o AH will not be changed by this procedure.
Therefore, to restore the previous state, simply
execute an Int 31h.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 100
17.2 Get and Enable Virtual Interrupt State
This function will enable the virtual interrupt flag
and return the previous state of the virtual interrupt
flag.
To Call
AX = 0901h
Returns
Carry flag clear (this function always succeeds)
Virtual interrupts are enabled
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
Programmer's Notes
o AH will not be changed by this procedure.
Therefore, to restore the previous state, simply
execute an Int 31h.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 101
17.3 Get Virtual Interrupt State
This function will return the current state of the
virtual interrupt flag.
To Call
AX = 0902h
Returns
Carry flag clear (this function always succeeds)
AL = 0 if virtual interrupts are disabled
AL = 1 if virtual interrupts are enabled
Programmer's Notes
None
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 102
18. GET VENDOR SPECIFIC API ENTRY POINT
Some DOS extenders provide extensions to the standard set of
DPMI calls. This call is used to obtain an address which
must be called to use the extensions. The caller points
DS:(E)SI to a null terminated string that specifies the
vendor name or some other unique identifier to obtain the
specific extension entry point.
To Call
AX = 0A00h
DS:(E)SI = Pointer to null terminated string
Returns
If function was successful:
Carry flag is clear
ES:(E)DI = Extended API entry point
DS, FS, GS, EAX, EBX, ECX, EDX, ESI, and EBP may be
modified
If function was not successful:
Carry flag is set
Programmer's Notes
o Execute a far call to call the API entry point.
o All extended API parameters are specified by the
vendor.
o The string comparison used to return the API entry
point is case sensitive.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 103
19. DEBUG REGISTER SUPPORT
The 80386 processor supports special registers that are used
for debugging. Since the instructions to modify these
registers can only be executed by code running at privileged
level zero, protected mode debuggers running in DPMI
environments can not modify the registers directly. These
services provide mechanisms for setting and clearing debug
watchpoints and detecting when a watchpoint has caused a
fault.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 104
19.1 Set Debug Watchpoint
This function will set a debug watchpoint at a
specified linear address.
To Call
AX = 0B00h
BX:CX = Linear address of watchpoint
DL = Size of watchpoint (1, 2, or 4)
DH = Type of watchpoint
0 = Execute
1 = Write
2 = Read/Write
Returns
If function was successful:
Carry flag is clear
BX = Debug watchpoint handle
If function was not successful:
Carry flag is set
Programmer's Notes
None
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 105
19.2 Clear Debug Watchpoint
This function will clear a debug watchpoint that was
set using the Set Debug Watchpoint function.
To Call
AX = 0B01h
BX = Debug watchpoint handle
Returns
If function was successful:
Carry flag is clear
If function was not successful:
Carry flag is set
Programmer's Notes
o This call frees the debug watchpoint handle
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 106
19.3 Get State of Debug Watchpoint
This function returns the state of a debug watchpoint
that was set using the Set Debug Watchpoint function.
To Call
AX = 0B02h
BX = Debug Watchpoint Handle
Returns
If function was successful:
Carry flag is clear
AX = Status flags
Bit 0 = 1 if watch point has been executed
If function was not successful:
Carry flag is set
Programmer's Notes
o To clear the watchpoint state the caller must use
function 0B03h.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 107
19.4 Reset Debug Watchpoint
This function resets the state of a previously defined
debug watchpoint.
To Call
AX = 0B03h
BX = Debug Watchpoint Handle
Returns
If function was successful:
Carry flag is clear
If function was not successful:
Carry flag is set
Programmer's Notes
None
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 108
20. OTHER APIS
In general, any software interrupt interface that passes
parameters in the EAX, EBX, ECX, EDX, ESI, EDI, and EBP
registers will work as long as none of the registers
contains a segment value. In other words, if a software
interrupt interface is completely register based without any
pointers, segment register, or stack parameters, that API
could work under any DPMI implementation.
More complex APIs require the caller to use the translation
services described on page 58.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 109
21. NOTES FOR DOS EXTENDERS
Many programs that use DPMI will be bound to DOS extenders
so that they will be able to run under any DOS environment.
Existing DOS extenders support APIs that differ from the Int
31h interface. Usually, DOS extenders use an Int 21h
multiplex for their extended APIs.
Extenders that support DPMI will need to initialize
differently when they are run under DPMI environments. They
will need to enter protected mode using the DPMI real to
protected mode entry point, install their own API handlers,
and then load the DOS extended application program.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 110
21.1 Initialization of Extenders
DOS extenders should check for the presence of DPMI before
attempting to allocate memory or enter protected mode using
any other API. DOS extenders should check for APIs in the
following order:
DOS Protected Mode Interface
Virtual Control Program Interface
eXtended Memory Specification
Int 15h memory allocation
When DPMI services are detected, extenders that provide
interfaces that extend or are different from the basic DPMI
interface will switch into protected mode and initialize any
internal data structures. DPMI compatible extenders that
provide no API extensions should simply execute the
protected mode application in real mode.
21.2 Installing API Extensions
DOS extenders typically use Int 21h to implement API
extensions. Under DPMI, a DOS extender will need to install
an API translation library by hooking Int 21h via then get
and set protected mode interrupt vector functions (see page
56). The DOS extender library then gets to see every DOS
call executed by the application program. If the API does
not have any pointers then the interrupt can be reflected to
the original interrupt handler. The default handler will
pass the interrupt to real mode. Other APIs can be
explicitly mapped by the DOS extender.
WARNING: The translation library code should be in locked
memory to prevent page faults while DOS is in a critical
section. This could happen, for instance, if a program
called DOS reentrantly from an Int 24h (critical error).
21.3 Loading the Application Program
Once the API translation library has been initialized, the
DOS extender can load the application program using standard
DOS calls. Memory should be allocated using the DPMI memory
allocation services.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 111
21.4 Providing API Extensions
DPMI call 0A00h provides a standard mechanism for providing
vendor specific extensions to the standard APIs. To support
extensions under a DPMI environment, the translation library
should hook the Int 31h chain (using the DOS get/set vector
calls) and watch for call 0A00h. When this call is issued
with the proper string parameter, the Int 31h hook code
should modify ES:(E)DI, clear the carry flag on the stack,
and iret without passing the call down the Int 31h chain.
If the string passed in ES:(E)DI does not match the
extensions supported by the library then the call should be
passed down the Int 31h chain.
July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9 Page 112