7723 lines
160 KiB
Plaintext
7723 lines
160 KiB
Plaintext
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|