add directory study

This commit is contained in:
gohigh
2024-02-19 00:25:23 -05:00
parent b1306b38b1
commit f3774e2f8c
4001 changed files with 2285787 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<h2>Obtain Real-to-Protected Mode Switch Entry Point
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
This function can be called in real mode only to test for
the presence of a DPMI host, and to obtain an address of a
mode switch routine that can be called to begin execution in
protected mode. <p>
<b>Call With</b><br>
<img src="r/ax.gif" alt="" width=245 height=59><br>
AX = 1687h <br clear>
<b>Returns</b><br>
<img src="r/ax+bx+cl+dh+dl+si+E+di.gif" alt="" width=245 height=59><br>
<i>If function successful</i><br>
AX = 0<br>
BX = flags
<blockquote><table border=1 cellspacing=0 cellpadding=4>
<tr><th>Bit</th><th>Significance</th></tr>
<tr><td rowspan=2 align=center>0</td><td align=left>0 = 32-bit programs are not supported</td></tr>
<tr><td align=left>1 = 32-bit programs are supported</td></tr>
<tr><td align=center>1-15</td><td align=left>not used</td></tr>
</table></blockquote>
CL = processor type
<blockquote><table border=1 cellspacing=0 cellpadding=4>
<tr><th>Value</th><th>Significance</th></tr>
<tr><td align=center>02H</td><td align=left>80286</td></tr>
<tr><td align=center>03H</td><td align=left>80386</td></tr>
<tr><td align=center>04H</td><td align=left>80486</td></tr>
<tr><td align=center>05H-FFH</td><td align=left>Reserved for future Intel processors</td></tr>
</table></blockquote>
DH = DPMI major version as a decimal number
(represented in binary)<br>
DL = DPMI minor version as a decimal number
(represented in binary)<br>
SI = number of paragraphs required for DPMI host
private data (may be 0)<br>
ES:DI = segment:offset of procedure to call to enter
protected mode<p>
<i>if function unsuccessful (no DPMI host present)</i><br>
AX = nonzero<p>
<h2>Notes</h2>
<ul>
<li>The entry point returned by <a href="2f1687.html">Int 2FH Function
1687H</a> is only called for the first switch to protected mode by a
DPMI client. For further details on the protocol for switching to
protected mode and the environment after switching to protected mode,
see <a href="../ch4.1.html">that page</a>.<p>
<li>Under DPMI hosts, the major version number is returned in DH and
the minor version number is returned in DL. There are two decimal
digits for the minor version number with the least-significant digit
representing the revision number of the minor version number. Under
DPMI version 0.9 hosts, DH is returned as 0, and DL is returned as
decimal 90 (5AH). In hypothetical DPMI version 2.3, DH would be
returned as 2 and DL would be returned as 30 (1EH).<p>
</ul>

View File

@@ -0,0 +1,81 @@
<h2>Allocate DOS Memory Block
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Allocates a block of memory from the DOS memory pool, i.e.
memory below the 1 MB boundary that is controlled by DOS.
Such memory blocks are typically used to exchange data with
real mode programs, TSRs, or device drivers. The function
returns both the real mode segment base address of the block
and one or more descriptors that can be used by protected
mode applications to access the block.<p>
<b>Call With</b><br>
<img src="r/ax+bx.gif" alt="" width=245 height=59><br>
AX = 0100H<br>
BX = number of (16-byte) paragraphs desired<p>
<b>Returns</b><br>
<img src="r/ax+bx+dx+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
AX = real mode segment base address of allocated
block<br>
DX = selector for allocated block<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>0007H</td><td>memory control blocks damaged (also returned by
DPMI 0.9 hosts)</td></tr>
<tr><td>0008H</td><td>insufficient memory (also returned by DPMI 0.9
hosts).</td></tr>
<tr><td>8011H</td><td>descriptor unavailable</td></tr>
</table>
BX = size of largest available block in paragraphs<p>
<h2>Notes</h2>
<ul>
<li>If the size of the block requested is greater than 64 KB (BX >
1000H) and the client is a 16-bit program, contiguous descriptors are
allocated and the base selector is returned. The consecutive
selectors for the memory block can be calculated using the value
returned by the Get Selector Increment Value function (<a
href="310003.html">Int 31H Function 0003H</a>). Each descriptor has a
limit of 64 KB, except for the last which has a limit of blocksize MOD
64 KB.<p>
<li>If the DPMI host is 32-bit, the client is 16-bit, and more than
one descriptor is allocated, the limit of the first descriptor will be
set to the size of the entire block. Subsequent descriptors have
limits as described in the previous Note. 16-bit DPMI hosts will
always set the limit of the first descriptor to 64 KB even when
running on an 80386 (or later) machine.<p>
<li>When the client is 32-bit, this function always allocates only one
descriptor.<p>
<li>Client programs should never modify or free any descriptors
allocated by this function. The Free DOS Memory Block function (<a
href="310101.html">Int 31H Function 0101H</a>) will deallocate the
descriptors automatically.<p>
<li>The DOS allocation function (Int 21H Function 48H) is used.<p>
<li>Refer to the rules for descriptor usage in <a href="../descriptor-rules.html">Appendix D</a>.<p>
</ul>

View File

@@ -0,0 +1,34 @@
<h2>Set Real Mode Interrupt Vector
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Sets the current virtual machine's real mode interrupt
vector for the specified interrupt.<p>
<b>Call With</b><br>
<img src="r/ax+bl+cx+dx.gif" alt="" width=245 height=59><br>
AX = 0201H<br>
BL = interrupt number<br>
CX:DX = segment:offset of real mode interrupt handler<p>
<b>Returns</b><br>
<img src="r/c.gif" alt="" width=245 height=59><br>
Carry flag = clear (this function always succeeds)<p>
<h2>Notes</h2><ul>
<li>The address passed in CX must be a real mode segment address, not
a selector. Consequently, the interrupt handler must either reside in
DOS memory (i.e. below the 1 MB boundary) or the client must allocate
a real mode callback address. See <a href="310100.html">Int 31H
Functions 0100H</a> and <a href="310303.html">0303H</a>.<p>
<li>If the interrupt being hooked is a hardware interrupt, the memory
that the interrupt handler uses must be locked.<p>
</ul>

View File

@@ -0,0 +1,64 @@
<h2>Set Processor Exception Handler Vector
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Sets the address of a handler for a CPU exception or fault, allowing a
protected mode application to intercept processor exceptions (such as
segment not present faults) that are not handled by the DPMI host and
would otherwise generate a fatal error. This function should be
avoided by DPMI 1.0 clients (see Notes).<p>
<b>Call With</b><br>
<img src="r/ax+bl+cx+edx.gif" alt="" width=245 height=59><br>
AX = 0203H<br>
BL = exception/fault number (00H-1FH)<br>
CX:(E)DX = selector:offset of exception handler<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8021H</td><td>invalid value (BL not in range 0-1FH)</td></tr>
<tr><td>8022H</td><td>invalid selector</td></tr>
</table>
<h2>Notes</h2><ul>
<li>The value passed in CX should be a valid protected mode code
(executable) selector, not a real mode segment address.<p>
<li>32-bit clients must supply a 32-bit offset in the EDX register.
If the client's handler chains to the next exception handler, it must
do so using a 32-bit interrupt stack frame.<p>
<li>Every exception is first examined by the DPMI host. If the host
does not handle the exception, it reflects the exception to the first
handler in the protected mode exception handler chain. See <a
href="../ch4.5.html">that page</a> for a complete discussion of the
environment and responsibilities of protected mode exception handlers
installed with this function.<p>
<li>Clients which run under DPMI 1.0 should use <a
href="310212.html">Int 31H Functions 0212H</a> and <a
href="310213.html">0213H</a> to set the addresses of exception
handlers. This function is supported by DPMI 1.0 hosts solely for
compatibility with DPMI 0.9.<p>
<li>Refer to the rules for descriptor usage in <a href="../descriptor-rules.html">Appendix D</a>.
</ul>

View File

@@ -0,0 +1,47 @@
<h2>Set Extended Processor Exception Handler Vector (Protected Mode)
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
Sets the address of the client's protected mode handler for
the specified protected mode exception.<p>
<b>Call With</b><br>
<img src="r/ax+bl+cx+edx.gif" alt="" width=245 height=59><br>
AX = 0212H<br>
BL = exception/fault number (00H-1FH)<br>
CX:(E)DX = selector:offset of exception handler<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8021H</td><td>invalid value (BL not in range 00H-1FH)</td></tr>
<tr><td>8022H</td><td>invalid selector</td></tr>
</table>
<h2>Notes</h2>
<ul>
<li>DPMI 1.0 clients should use this function in preference to <a
href="310203.html">Int 31H Function 0203H</a>.<p>
<li>The protected mode exceptions are sent to the protected mode
handler of the current client.<p>
<li>Refer to the rules for descriptor usage in <a href="../descriptor-rules.html">Appendix D</a>.<p>
</ul>

View File

@@ -0,0 +1,50 @@
<h2>Set Extended Processor Exception Handler Vector (Real Mode)
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
Sets the address of the client's protected mode handler for the
specified real mode exception.<p>
<b>Call With</b><br>
<img src="r/ax+bl+cx+edx.gif" alt="" width=245 height=59><br>
AX = 0213H<br>
BL = exception/fault number (00H-1FH)<br>
CX:(E)DX = selector:offset of exception handler<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8021H</td><td>invalid value (BL not in range 00H-1FH)</td></tr>
<tr><td>8022H</td><td>invalid selector</td></tr>
</table>
<h2>Notes</h2>
<ul>
<li>CX:(E)DX does not specify a real-mode segment:offset. The reason
is that this function allows a client to set the address of an
exception handler which will receive control in protected mode when
the specified exception occurs in real mode (i.e. the host will
provide an implied mode switch for the purposes of servicing the
exception, then return to real mode after the handler exits). <p>
<li>Real mode exceptions are sent to the primary client of the virtual
machine. (See Appendix A: Glossary for definition of primary
client.)<p>
<li>Refer to the rules for descriptor usage in <a href="../descriptor-rules.html">Appendix D</a>.
</ul>

View File

@@ -0,0 +1,62 @@
<h2>Allocate Real Mode Callback Address
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Returns a unique real mode segment:offset, known as a "real mode
callback," that will transfer control from real mode to a protected
mode procedure. Callback addresses obtained with this function can be
passed by a protected mode program to a real mode application,
interrupt handler, device driver, or TSR, so that the real mode
program can call procedures within the protected mode program or
notify the protected mode program of an event.<p>
<b>Call With</b><br>
<img src="r/ax+D+esi+E+edi.gif" alt="" width=245 height=59><br>
AX = 0303H<br>
DS:(E)SI = selector:offset of protected mode procedure to call<br>
ES:(E)DI = selector:offset of 32H-byte buffer for real mode register
data structure to be used when calling callback routine.<p>
<b>Returns</b><br>
<img src="r/ax+cx+dx+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
CX:DX = segment:offset of real mode callback<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8015H</td><td>callback unavailable</td></tr>
</table>
<h2>Notes</h2><ul>
<li>DPMI hosts must provide a minimum of 16 callback
addresses per client.<p>
<li>A descriptor may be allocated for each callback to hold the real
mode SS descriptor. Real mode callbacks are a limited system resource.
A client should use the Free Real Mode Callback Address function (<a
href="310304.html">Int 31H Function 0304H</a>) to release a callback
that it is no longer using.<p>
<li>For further information on writing real mode callback procedures,
see <a href="../ch4.6.html">that page</a>.<p>
<li>The contents of the real mode register data structure is
not valid after the function call, but only at the time
of the actual callback.<p>
</ul>

View File

@@ -0,0 +1,64 @@
<h2>Allocate Memory Block
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Allocates and commits a block of linear memory.<p>
<b>Call With</b><br>
<img src="r/ax+bx+cx.gif" alt="" width=245 height=59><br>
AX = 0501H<br>
BX:CX = size of block (bytes, must be nonzero)<p>
<b>Returns</b><br>
<img src="r/ax+bx+cx+si+di+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
BX:CX = linear address of allocated memory block<br>
SI:DI = memory block handle (used to resize and free
block)<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8012H</td><td>linear memory unavailable</td></tr>
<tr><td>8013H</td><td>physical memory unavailable</td></tr>
<tr><td>8014H</td><td>backing store unavailable</td></tr>
<tr><td>8016H</td><td>handle unavailable</td></tr>
<tr><td>8021H</td><td>invalid value (BX:CX = 0)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>The allocated block is guaranteed to have at least paragraph
alignment.<p>
<li>This function always creates committed pages.<p>
<li>This function does not allocate any descriptors for the memory
block. It is the responsibility of the client to allocate and
initialize any descriptors needed to access the memory with additional
DPMI function calls.<p>
<li>Under DPMI hosts that support virtual memory, the memory block
will be allocated unlocked. The client can lock some or all of the
memory after it is allocated with the Lock Linear Region function (<a
href="310600.html">Int 31H Function 0600H</a>).<p>
<li>Under many DPMI hosts, allocations by this function are page
granular. This means, for example, that if the DPMI host uses a page
size of 4 KB (1000H), an allocation of 1001H bytes will actually
result in an allocation of 2000H bytes. Therefore, it is best to
always allocate memory in multiples of the unit of granularity (under
DPMI 0.9, use 4K bytes), which can be obtained with <a
href="310604.html">Int 31H Function 0604H</a>.<p>
</ul>

View File

@@ -0,0 +1,75 @@
<h2>Allocate Linear Memory Block
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
Allocates a block of page-aligned linear address space. The
base address of the block may be specified by the client,
and pages within the block may be committed or uncommitted.<p>
<b>Call With</b><br>
<img src="r/ax+ebx+ecx+edx.gif" alt="" width=245 height=59><br>
AX = 0504H<br>
EBX = desired page-aligned linear address of memory
block,
or zero if linear address unspecified<br>
ECX = size of block (bytes, must be nonzero)<br>
EDX = flags
<blockquote><table border=1 cellspacing=0 cellpadding=4>
<tr><th>Bit</th><th>Significance</th></tr>
<tr><td align=center rowspan=2>0</td><td align=left>0 = create uncommitted pages</td></tr>
<tr><td align=left>1 = create committed pages</td></tr>
<tr><td align=center>1-31</td><td align=left>reserved, should be zero</td></tr>
</table></blockquote>
<b>Returns</b><br>
<img src="r/ax+ebx+esi+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
EBX = linear address of memory block<br>
ESI = handle for memory block<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8001H</td><td>unsupported function (16-bit host)</td></tr>
<tr><td>8012H</td><td>linear memory unavailable</td></tr>
<tr><td>8013H</td><td>physical memory unavailable</td></tr>
<tr><td>8014H</td><td>backing store unavailable</td></tr>
<tr><td>8016H</td><td>handle unavailable</td></tr>
<tr><td>8021H</td><td>invalid value (ECX = 0)</td></tr>
<tr><td>8025H</td><td>invalid linear address (EBX not page aligned)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>A DPMI 1.0 host that is 16-bit only will not support this
function.<p>
<li>A 16-bit client of a 32-bit DPMI 1.0 host can use this
function.<p>
<li>The allocated block is always page-aligned. If a specific linear
address is not requested (EBX = 0), the DPMI host allocates the memory
block at any available page-aligned linear address. If a specific
linear address is requested (EBX nonzero), the host either allocates
the block at the specified address or returns <a
href="errors.html">error code</a> 8012H (linear memory
unavailable).<p>
<li><a href="310501.html">Int 31H Function 0501H</a>, which can also
be used to allocate linear memory blocks, does not necessarily
page-align its blocks and does not have the ability to create
uncommitted pages or allocate a block at a specific linear
address. <p>
</ul>

View File

@@ -0,0 +1,96 @@
<h2>Map Device in Memory Block
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
Maps the physical addresses assigned to a device onto the linear
addresses of a memory block previously allocated with <a
href="310504.html">Int 31H Function 0504H</a>.<p>
<b>Call With</b><br>
<img src="r/ax+ebx+ecx+edx+esi.gif" alt="" width=245 height=59><br>
AX = 0508H<br>
ESI = memory block handle<br>
EBX = offset within memory block of page(s) to be
mapped (must be page-aligned)<br>
ECX = number of pages to map<br>
EDX = physical address of device (must be
page-aligned)<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8001H</td><td>unsupported function (Device Mapping</td></tr>
Capability not supported)
<tr><td>8003H</td><td>system integrity (invalid device address)</td></tr>
<tr><td>8023H</td><td>invalid handle (in ESI)</td></tr>
<tr><td>8025H</td><td>invalid linear address (specified range
is not within specified block or EBX/EDX
is not page-aligned)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>16-bit DPMI hosts will not support this function. A 16-bit client
of a 32-bit DPMI 1.0 host can use this function.<p>
<li>Support of this call by 32-bit DPMI hosts is optional.
Application programs or DOS Extenders which require this call in order
to run are not DPMI Compliant.<p>
<li>Any committed or mapped pages resided in the linear address range
that is being mapped into will be uncommitted or unmapped
automatically by the host.<p>
<li>All pages created by this call have the mapped bit (bit 2) set in
the attributes returned by the Get Page Attributes function (<a
href="310506.html">Int 31H Function 0506H</a>).<p>
<li>This function differs from the Create Physical Address Mapping
function (<a href="310800.html">Int 31H Function 0800H</a>) in that
this function supports mapping of physical devices within an existing
memory block, rather than at an arbitrary linear address. Use of an
existing memory block gives 32-bit programs the ability to access
physical devices with NEAR pointers, which is often highly desirable
for performance reasons.<p>
<li>Unlike <a href="310800.html">Int 31H Function 0800H</a>, this
function allows mapping of addresses below 1 MB that do not lie within
RAM available for use by programs; e.g. this function can be used to
map the refresh buffers of IBM-compatible display adapters.<p>
<li>If the DPMI host is not virtualizing the device, it must disable
any memory caching on the mapped pages; in particular, on the 486 or
later, the PCD (page cache disable) bit must be set in the page table
entries.<p>
<li>DPMI hosts that do not virtualize physical devices can support
this function by creating page table entries that map the physical
device. The page table entries must be marked as mapped so that the
host knows not to attempt freeing of physical memory for the pages
when the memory block is freed.<p>
<li>DPMI hosts are allowed to support this function for some physical
devices and not for others, because mapping of virtualized devices
requires page aliasing in the host - a complex task. DPMI hosts with
partial support for this function may fail the function call on
virtualized devices (such as displays), and allow the call on
non-virtualized devices (such as the Weitek coprocessors). Allowing
the client to map a physical device so that it can be accessed with
NEAR references, for example, may help the client achieve considerably
better performance.<p>
</ul>

View File

@@ -0,0 +1,100 @@
<h2>Map Conventional Memory in Memory Block
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
Aliases linear addresses below the 1 MB boundary onto the linear
addresses of a memory block previously allocated with <a
href="310504.html">Int 31H Function 0504H</a>.<p>
<b>Call With</b><br>
<img src="r/ax+ebx+ecx+edx+esi.gif" alt="" width=245 height=59><br>
AX = 0509H<br>
ESI = memory block handle<br>
EBX = offset within memory block of page(s) to be
mapped (must be page-aligned)<br>
ECX = number of pages to map<br>
EDX = linear address of conventional memory (must be
page-aligned)<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8001H</td><td>unsupported function (Conventional Memory
Mapping Capability not supported)</td></tr>
<tr><td>8003H</td><td>system integrity (invalid conventional
memory address)</td></tr>
<tr><td>8023H</td><td>invalid handle (in ESI)</td></tr>
<tr><td>8025H</td><td>invalid linear address (specified range
is not within specified block, or EBX/EDX
is not page aligned)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>16-bit DPMI hosts will not support this function. A 16-bit client
of a 32-bit DPMI 1.0 host can use this function.<p>
<li>Support of this call by 32-bit DPMI hosts is optional.
Application programs or DOS Extenders which require this call in order
to run are not DPMI Compliant.<p>
<li>Any committed or mapped pages resided in the linear address range
that is being mapped into will be uncommitted or unmapped
automatically by the host.<p>
<li>A client may only map conventional memory that it already owns;
i.e. memory which the client previously allocated with <a
href="310100.html">Int 31H Function 0100H</a> or by calling DOS's Int
21H Function 48H directly via the translation services.<p>
<li>All pages created by this call have the mapped bit (bit 2) set in
the attributes returned by the Get Page Attributes function (<a
href="310506.html">Int 31H Function 0506H</a>).<p>
<li>DPMI hosts that do not implement virtual memory can support this
function by simply copying page table entries. The entries must be
marked as mapped so that the host knows not to free up those physical
pages when the memory block is freed.<p>
<li>DPMI hosts that provide virtual memory must implement some form of
page aliasing in order to support this function.<p>
<li>The function can provide a large contiguous memory space without
virtual memory support. <p>
<li>Implementors of DPMI hosts which do not provide virtual memory are
encouraged to support this function. Without this function,
conventional memory may be inaccessible to a 32-bit nonsegmented
client, because the client may need contiguous linear memory for its
code and data. 32-bit clients can always guarantee that conventional
memory is not wasted with the following strategy:<ul>
<li>Call DOS to allocate any free conventional memory
<li>If the DPMI host supports virtual memory, call the Mark Real Mode
Region Pageable function (<a href="310602.html">Int 31H Function
0602H</a>) to ensure that the host has not locked down conventional
memory.
<li>If the host does not support virtual memory but supports the Map
Conventional Memory function (<a href="310509.html">Int 31H Function
0509H</a>), allocate a memory block with uncommitted pages, then use
<a href="310509.html">Function 0509H</a> to make the physical memory
allocated below 640 KB addressable in the memory block, and therefore
useable by the 32-bit application program. </ul><p>
</ul>

View File

@@ -0,0 +1,86 @@
<h2>Mark Real Mode Region as Pageable
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Advises the DPMI host that the specified memory below the 1 MB
boundary may be paged to disk.<p>
<b>Call With</b><br>
<img src="r/ax+bx+cx+si+di.gif" alt="" width=245 height=59><br>
AX = 0602H<br>
BX:CX = starting linear address of memory to mark as
pageable<br>
SI:DI = size of region to be marked (bytes)<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8002H</td><td>invalid state (region already marked as pageable)</td></tr>
<tr><td>8025H</td><td>invalid linear address (region is above 1 MB boundary)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>If the function returns an error, none of the memory has been
marked as pageable.<p>
<li>If the specified region overlaps part of a page at the beginning
or end of the region, the page(s) will not be marked as pageable.<p>
<li>Pageability information for a real mode region is maintained as a
binary state, not a count. Therefore, multiple calls to this function
for the same region have no effect.<p>
<li>For compatibility with DPMI version 0.9 hosts, a client must call
the Relock Real Mode Region function (<a href="310603.html">Int 31H
Function 0603H</a>) to relock the memory region before terminating.
Memory that remains unlocked after the client has terminated could
result in fatal page faults when another program is executed in the
same address space. DPMI 1.0 hosts automatically relock real mode
memory at client termination.<p>
<li>Under some DPMI hosts, all conventional memory may be locked by
default. If a protected mode program is using memory in the first
megabyte of address space, it is recommended that this function be
used to turn off automatic page locking for regions of memory that
will not be touched at interrupt time.<p>
<li>The client must not mark memory as pageable in regions that it
does not own; i.e. it may only mark as pageable memory that it has
previously allocated with <a href="310100.html">Int 31H Function
0100H</a> or by a direct call to DOS via the translation functions.
For example, marking all free DOS memory as pageable under some DPMI
hosts could cause a page fault to occur while inside of DOS, resulting
in a crash. Also, a client should not mark the DPMI host data area as
pageable.<p>
<li>Note that address space marked as pageable by this function can
still be locked using the Lock Linear Region function (<a
href="310600.html">Int 31H Function 0600H</a>). This function is just
an advisory service to allow memory that does not need to be locked to
be paged out; it disables any automatic locking of real mode memory
performed by the DPMI host.<p>
<li>This function is ignored by DPMI implementations that do not
support virtual memory; the function will return the Carry flag clear
to indicate success, but has no other effect. DPMI hosts which
support virtual memory may also choose to ignore this function, but
such hosts must be able to handle page faults transparently at
arbitrary points during a client's execution, including within
interrupt and exception handlers.<p>
</ul>

View File

@@ -0,0 +1,60 @@
<h2>Relock Real Mode Region
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Relocks a memory region that was previously declared as pageable with
the Mark Real Mode Region as Pageable function (<a
href="310602.html">Int 31H Function 0602H</a>).<p>
<b>Call With</b><br>
<img src="r/ax+bx+cx+si+di.gif" alt="" width=245 height=59><br>
AX = 0603H<br>
BX:CX = starting linear address of memory to relock<br>
SI:DI = size of region to relock (bytes)<p>
<b>Returns</b><br>
<img src="r/ax+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8002H</td><td>invalid state (region not marked as
pageable)</td></tr>
<tr><td>8013H</td><td>physical memory unavailable</td></tr>
<tr><td>8025H</td><td>invalid linear address (region is above 1
MB boundary)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>If the function returns an error, none of the memory has been
relocked.<p>
<li>If the specified region overlaps part of a page at the beginning
or end of the region, the page(s) will not be relocked.<p>
<li>This function is ignored by DPMI implementations that do not
support virtual memory; the function will return the Carry flag clear
to indicate success, but has no other effect. DPMI hosts which
support virtual memory may also choose to ignore this function, but
such hosts must be able to handle page faults transparently at
arbitrary points during a client's execution, including within
interrupt and exception handlers.<p>
<li>If <a href="310602.html">Function 0602H</a> is implemented as a
"no-operation" on a particular DPMI host, this function will likewise
do nothing. In other words, this function should not be used to lock
memory, but only to restore the default state of the host's
conventional memory locking.<p>
</ul>

View File

@@ -0,0 +1,91 @@
<h2>Physical Address Mapping
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Converts a physical address into a linear address. This function
allows device drivers running under DPMI hosts which use paging to
reach physical memory that is associated with their devices above the
1 MB boundary Examples of such devices are the Weitek numeric
coprocessor (usually mapped at 3 GB), buffers that hold scanner bit
maps, and high-end displays that can be configured to make display
memory appear in extended memory.<p>
<b>Call With</b><br>
<img src="r/ax+bx+cx+si+di.gif" alt="" width=245 height=59><br>
AX = 0800H<br>
BX:CX = physical address of memory<br>
SI:DI = size of region to map (bytes)<p>
<b>Returns</b><br>
<img src="r/ax+bx+cx+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
BX:CX = linear address that can be used to access the
physical memory<br>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8003H</td><td>system integrity (DPMI host memory
region)</td></tr>
<tr><td>8021H</td><td>invalid value (address is below 1 MB
boundary)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>It is the caller's responsibility to allocate and initialize a
descriptor for access to the memory.<p>
<li>This function should only be used by clients that absolutely
require direct access to a memory mapped device at physical addresses
above 1 MB. Clients should not use this function to access memory
below the 1 MB boundary (the real mode addressable region). See also
<a href="310200.html">Int 31H Functions 0002H</a>, <a
href="310508.html">0508H</a>, and <a href="310509.html">0509H</a>.<p>
<li>When this function is called, the DPMI host either creates page
table entries that directly map the physical addresses requested and
returns the linear address of the created page table entries, or else
just returns the linear address of the memory region that is already
used to map the requested device. For example, if the client attempts
to map a Weitek coprocessor and the host already has a linear region
set up to map the Weitek chip and virtualize it, it would simply
return the linear address of the existing region. If the host does
not virtualize the Weitek chip, it would create 16 page table entries
that map the 64 KB Weitek address space and return a linear address
corresponding to the new page table entries.<p>
<li>If the host is not virtualizing the device, it must disable any
memory caching on the mapped pages; in particular, on the 80486 the
host must set the PCD (page cache disable) bit in the page table
entries.<p>
<li>The host is permitted to fail any memory mapping call. However,
the host should support this function whenever possible, to achieve
compatibility with application programs that use memory-mapped devices
of which the host is not aware. Useful guidelines are that the host
should fail any attempt to map addresses below 1 MB, or addresses
which the host considers to be general-purpose RAM memory. Attempts
to map any other physical address should succeed, since the host
should either (a) already know about the device and be able to return
a linear address used to access the device, or (b) assume the program
is attempting to map a legitimate device of which the host has no
knowledge.<p>
<li>Programs and device drivers which need to perform DMA I/O to
physical addresses in a virtualized hardware environment should use
the Virtual DMA Services (see the Glossary entry for the Virtual DMA
Services Specification). Also see page 10 of the DPMI execution
environment section.<p>
</ul>

View File

@@ -0,0 +1,54 @@
<h2>Set Debug Watchpoint
<img src="../0.9.gif" alt="[0.9]" width=22 height=17></h2>
Sets a debug watchpoint at the specified linear address.<p>
<b>Call With</b><br>
<img src="r/ax+bx+cx+dh+dl.gif" alt="" width=245 height=59><br>
AX = 0B00H<br>
BX:CX = linear address of watchpoint<br>
DL = size of watchpoint (1, 2, or 4 bytes)<br>
DH = type of watchpoint
<blockquote><table border=1 cellspacing=0 cellpadding=4>
<tr><th>Value</th><th>Breakpoint Type</th></tr>
<tr><td align=center>0</td><td align=left>execute</td></tr>
<tr><td align=center>1</td><td align=left>write</td></tr>
<tr><td align=center>2</td><td align=left>read/write</td></tr>
</table></blockquote>
<b>Returns</b><br>
<img src="r/ax+bx+c.gif" alt="" width=245 height=59><br>
<i>if function successful</i><br>
Carry flag = clear<br>
BX = watchpoint handle<p>
<i>if function unsuccessful</i><br>
Carry flag = set<br>
AX = <a href="errors.html">error code</a>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>8016H</td><td>too many breakpoints</td></tr>
<tr><td>8021H</td><td>invalid value (in DL or DH)</td></tr>
<tr><td>8025H</td><td>invalid linear address (linear address
not mapped or alignment error)</td></tr>
</table>
<h2>Notes</h2><ul>
<li>Under DPMI 1.0, the handle will be in the range 0-14. Under DPMI
0.9, the handle range is not limited.<p>
<li>The watchpoint handle corresponds to the bit number in the Virtual
DR6 returned in the exception frame (see <a href="310212.html">Int 31H
Function 0212H</a> and page 18 of the DPMI spec).<p>
</ul>

View File

@@ -0,0 +1,51 @@
<h2>Terminate and Stay Resident
<img src="../1.0.gif" alt="[1.0]" width=22 height=17></h2>
A resident service provider uses this function after its
initialization to terminate execution while leaving its protected mode
memory (and optionally some real mode memory) allocated.<p>
<b>Call With</b><br>
<img src="r/ax+bl+dx.gif" alt="" width=245 height=59><br>
AX = 0C01H<br>
BL = return code<br>
DX = number of paragraphs (16-byte blocks) of DOS
memory to reserve<p>
<b>Returns</b><br>
Nothing (this call never returns)
<h2>Notes</h2><ul>
<li>This function should only be used by DPMI clients which only
provide resident services to other DPMI protected mode clients. If
the objective is only to provide resident services to real mode
programs, the client should use the DPMI translation service <a
href="310300.html">Int 31H Function 0300H</a> to invoke DOS's Int 21H
Function 31H directly.<p.
<li>The value in DX only specifies the size of DOS allocated memory to
reserve. Any protected mode memory owned by the program remains
allocated unless it is explicitly released before executing this
function. Note that the value in DX must either be 0 or a minimum of
6. If DX is 0, the DPMI host executes a DOS real mode terminate
function (Int 21H Function 4CH), and no real mode memory is reserved.
If DX is nonzero, the DPMI host requests the DOS real mode
terminate-and-stay-resident function (Int 21H Function 31H).<p>
<li>If the client has not made a prior call to <a
href="310c00.html">Int 31H Function 0C00H</a>, the client will simply
be terminated.<p>
<li>For further details on programming of resident service providers,
see <a href="../ch4.8.html">that page</a>.<p>
</ul>

View File

@@ -0,0 +1,141 @@
Note that DPMI 0.9 hosts are <em>not</em> required to return a valid
error code in AX. You may only rely on the carry flag being set if an
error occurred. <p>
Nearly all Int 31H function calls can fail, either because of client
errors, unavailable resources, or internal host problems. Most
failures due to client errors and all failures due to unavailable
resources are reported to the client via error codes. Some client
errors, such as passing an invalid pointer in a function call, may
cause the host to fault; the client can detect these events by
installing an exception handler. <p>
Internal host errors are handled in a host-specific manner and
generally not reported to clients with an error code. The only
exception to this is the case when a host cannot allocate internal
resources. Any Int 31H function is capable of returning error code
8010H to indicate this condition.<p>
A DPMI 1.0 host signals an error by returning from a function with the
Carry flag set and an error code in AX. If the error code has bit 15
clear (0), the DPMI host is passing a DOS error code through to the
client; for a list of these error codes, consult a DOS technical
reference. If the error code has bit 15 set (1), it is generated
within the DPMI host, and is interpreted according to the list below.
All DPMI 1.0 hosts are required to check for the error conditions
listed in this specification, and must return the error codes that are
documented for each function.<p>
If Int 31H is invoked with an function number that is not defined in
this specification, the DPMI host will return the "Unsupported
Function" error code 8001H. The table lists all defined error codes
and their messages. Unused error codes are reserved for the later
versions of the DPMI spcifications.<p>
<table border=1 cellspacing=0 cellpadding=4>
<tr><th>Error Code</th>
<th>Name</th>
<th>Explanation</th></tr>
<tr><td>0007H</td>
<td align=left>Memory configuration blocks damaged</td>
<td align=left>The operating system has detected corruption in the real-mode memory arena.</td></tr>
<tr><td>0008H</td>
<td align=left>Insufficient memory</td>
<td align=left>There is not enough real-mode memory to satisfy the request.</td></tr>
<tr><td>0009H</td>
<td align=left>Incorrect memory segment specified</td>
<td align=left>The segment value specified was not one provided by the operating system</td></tr>
<tr><td>8001H</td>
<td align=left>Unsupported function</td>
<td align=left>Returned in response to any function call which is not implemented by this host, because the requested function is either undefined or optional.</td></tr>
<tr><td>8002H</td>
<td align=left>Invalid state</td>
<td align=left>Some object is in the wrong state for the requested operation.</td></tr>
<tr><td>8003H</td>
<td align=left>System integrity</td>
<td align=left>The requested operation would endanger system integrity, e.g., a request to map linear addresses onto system code or data.</td></tr>
<tr><td>8004H</td>
<td align=left>Deadlock</td>
<td align=left>Host detected a deadlock situation.</td></tr>
<tr><td>8005H</td>
<td align=left>Request cancelled</td>
<td align=left>A pending serialization request was cancelled.</td></tr>
<tr><td>8010H</td>
<td align=left>Resource Unavailable</td>
<td align=left>The DPMI host cannot allocate internal resources to complete an operation.</td></tr>
<tr><td>8011H</td>
<td align=left>Descriptor unavailable</td>
<td align=left>Host is unable to allocate a descriptor.</td></tr>
<tr><td>8012H</td>
<td align=left>Linear memory unavailable</td>
<td align=left>Host is unable to allocate the required linear memory.</td></tr>
<tr><td>8013H</td>
<td align=left>Physical memory unavailable</td>
<td align=left>Host is unable to allocate the required physical memory.</td></tr>
<tr><td>8014H</td>
<td align=left>Backing store unavailable</td>
<td align=left>Host is unable to allocate the required backing store.</td></tr>
<tr><td>8015H</td>
<td align=left>Callback unavailable</td>
<td align=left>Host is unable to allocate the required callback address.</td></tr>
<tr><td>8016H</td>
<td align=left>Handle unavailable</td>
<td align=left>Host is unable to allocate the required handle.</td></tr>
<tr><td>8017H</td>
<td align=left>Lock count exceeded</td>
<td align=left>A locking operation exceeds the maximum count maintained by the host.</td></tr>
<tr><td>8018H</td>
<td align=left>Resource owned exclusively</td>
<td align=left>A request for serialization of a shared memory block could not be satisfied because it is already serialized exclusively by another client.</td></tr>
<tr><td>8019H</td>
<td align=left>Resource owned shared</td>
<td align=left>A request for exclusive serialization of a shared memory block could not be satisfied because it is already serialized shared by another client.</td></tr>
<tr><td>8021H</td>
<td align=left>Invalid value</td>
<td align=left>A numeric or flag parameter has an invalid value.</td></tr>
<tr><td>8022H</td>
<td align=left>Invalid selector</td>
<td align=left>A selector does not correspond to a valid descriptor.</td></tr>
<tr><td>8023H</td>
<td align=left>Invalid handle</td>
<td align=left>A handle parameter is invalid.</td></tr>
<tr><td>8024H</td>
<td align=left>Invalid callback</td>
<td align=left>A callback parameter is invalid.</td></tr>
<tr><td>8025H</td>
<td align=left>Invalid linear address</td>
<td align=left>A linear address range (either supplied as a parameter or implied by the call) is invalid.</td></tr>
<tr><td>8026H</td>
<td align=left>Invalid request</td>
<td align=left>The request is not supported by the underlying hardware.</td></tr>
</table>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,125 @@
DPMI clients are loaded in real mode. In order to enter protected
mode, the client must first call <a href="api/2f1687.html">Int 2FH
Function 1687H</a> to test for the presence of a DPMI host and obtain
the address of the real-to-protected mode switch entry point. <a
href="api/2f1687.html">Function 1687H</a> also returns information
about the DPMI host's capabilities and the size of a private data area
which will be used by the host to hold client-specific data
structures. After allocating the required private data area via the
normal real mode memory allocation interface (DOS Int 21H Function
48H), the client makes a <tt>FAR CALL</tt> to the mode switch entry
point with the following parameters: <p>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td rowspan=5 align=center>AX</td><td colspan=2>flags</td></tr>
<tr><th align=center>Bit</th><th>Significance</th></tr>
<tr><td align=center rowspan=2>0</td><td align=left>0 = 16-bit application</td></tr>
<tr><td align=left>1 = 32-bit application</td></tr>
<tr><td align=center rowspan=1>1-15</td><td align=left>Reserved, should be zero</td></tr>
<tr><td align=center>ES</td><td colspan=2>real mode segment of DPMI
host private data area (must be at least as large as the size returned
in SI by <a href="api/2f1687.html">Int 2FH Function 1687H</a>; ES is
ignored if the size was zero.</td></tr>
</table><p>
If the Carry flag is set upon return, the mode switch was
unsuccessful, the client is still running in real mode, and register
AX contains one of the following error codes: <p>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td align=center>8011H</td><td align=left>descriptor unavailable
(cannot allocate descriptors for CS, DS, ES, SS, PSP, and environment
pointer)</td></tr>
<tr><td align=center>8021H</td><td align=left>invalid value (32-bit
program specified but not supported)</td></tr>
</table><p>
If the mode switch was successful, the mode switch routine returns to
the call in protected mode with the Carry flag clear and the following
results:<p>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td align=center>CS</td><td align=left>16-bit selector with base
of real mode CS and a 64KB limit</td></tr>
<tr><td align=center>SS</td><td align=left>selector with base of real
mode SS and a 64 KB limit</td></tr>
<tr><td align=center>DS</td><td align=left>selector with base of real
mode DS and a 64 KB limit</td></tr>
<tr><td align=center>ES</td><td align=left>selector to program's PSP
with a 100H byte limit</td></tr>
<tr><td align=center>FS</td><td align=left>0 (if running on an 80386
or later)</td></tr>
<tr><td align=center>GS</td><td align=left>0 (if running on an 80386
or later)</td></tr>
</table><p>
All other registers are preserved, except that for 32-bit clients the
high word of ESP will be forced to zero. 32-bit clients will
initially run with a 16-bit code segment, but all Int 31H calls will
still require 48-bit pointers, and the stack and data descriptors will
be 32-bit (the Big bit will be set in the descriptors). Note that if
DS+SS at the time of the mode switch call, only one descriptor may be
allocated, and the same selector may be returned in DS and SS. The
client is allowed to modify or free the CS, DS and SS descriptors
allocated by the mode switch routine. <p>
The environment pointer in the client program's PSP is automatically
converted to a selector during the mode switch. If the client wishes
to free the memory occupied by the environment, it should do so <i>
before </i> entering protected mode and zero the word at PSP:2CH
(segment address of the environment>. The client may change the
environment point in the PSP after entering protected mode but it must
restore it to the selector created by the DPMI host before
terminating. The client should <i>not</I> modify or free the PSP or
environment descriptors supplied by the DPMI host.<p>
<b> Example:</b> The following code illustrates how a DPMI client
would obtain the address of the mode switch entry point, allocate the
DPMI host private data area, and enter protected mode.
<pre>
modesw dd 0 ; far pointer to DPMI host's
; mode switch entry point
.
.
.
mov ax,1687h ; get address of DPMI host's
<a href="api/2f1687.html">int 2fh</a> ; mode switch entry point
or ax,ax ; exit if no DPMI host
jnz error
mov word ptr modesw,di ; save far pointer to host's
mov word ptr modesw+2,es ; mode switch entry point
or si,si ; check private data area size
jz @@1 ; jump if no private data area
mov bx,si ; allocate DPMI private area
mov ah,48h ; allocate memory
int 21h ; transfer to DOS
jc error ; jump, allocation failed
mov es,ax ; let ES=segment of data area
@@1: mov ax,0 ; bit 0=0 indicates 16-bit app
call modesw ; switch to protected mode
jc error ; jump if mode switch failed
; else we're in prot. mode now
.
.
.
</pre>

View File

@@ -0,0 +1,98 @@
A protected mode client terminates by executing an Int 21H in
protected mode, passing the value 4CH in register AH and a return code
in register AL. (This mimics the Int 21H Function 4CH termination
used by DOS applications in real mode.> The client has the following
responsibilities before termination:
<ul>
<li> real mode memory that was unlocked for paging with <a
href="api/310602.html">Int 31H Function 0602H</a> must be relocked
with <a href="api/310603.html">Int 31H Function 0603H</a>;<p>
<li> interrupts hooked by the client for real mode with <a
href="api/310201.html">Int 31H Function 0201H</a> must be released by
restoring the address of the original owner of the interrupt.<p>
<li> protected mode handlers for real mode exceptions installed with
<a href="api/310213.html">Int 31H Function 0213H</a> should be cleaned
up if possible.<p>
</ul>
When the DPMI host detects an Int 21H Function 4CH termination
request, it takes the following actions (the detailed comparison of
DPMI version 0.9 and version 1.0 host termination handling is in
Appendix C, page 158>:
<ul>
<li> any extended memory blocks that were previously allocated with <a
href="api/310501.html">Function 0501H</a> or <a
href="api/310504.html">0504H</a> are unlocked and freed (this is the
only cleanup action required by a DPMI V 0.9 host>;<p>
<li> the client's local descriptor table (LDT) is freed in its
entirety by DPMI 1.0 hosts. (A DPMI version 0.9 client should clean
up its own segment descriptors before its termination since some DPMI
version 0.9 hosts may not free the terminating client's segment
descriptors if the client is not the primary client);<p>
<li> physical address mappings created with <a
href="api/310800.html">Int 31H Function 0800H</a> are freed;<p>
<li> mappings created with <a href="api/310508.html">Int 31H Functions
0508H</a> or <a href="api/310509.html">0509H</a> are destroyed;<p>
<li> the client's interrupt descriptor table (IDT) is freed in it's
entirety and any client exception handlers installed through <a
href="api/310203.html">Functions 0203H</a>, <a
href="api/310212.html">0212H</a> and <a
href="api/310213.html">0213H</a> are deregistered;<p>
<li> any real mode regions that were unlocked with <a
href="api/310602.html">Function 0602H</a> are relocked;<p>
<li> any real mode callbacks that were allocated with <a
href="api/310303.html">Function 0303H</a> are deallocated;<p>
<li> the client's shared memory block allocations and serializations
are freed;<p>
<li> any debug watchpoints that were set with <a
href="api/310b00.html">Function 0B00H</a> are cleared;<p>
<li> the coprocessor state (if any) is restored to the default.<p>
</ul>
After the DPMI host performs the cleanup activities listed above, it
will switch to real mode and re-issue the Int 21H Function 4CH
interrupt, passing the return code from the DPMI client down to DOS.
DOS will then terminate the client as a real mode process by releasing
its DOS memory blocks (whether allocated by real mode Int 21H Function
48H or by <a href="api/310100.html">DPMI Function 0100H</a>), flushing
file buffers, closing file and device handles, and so on.<p>
Clients should only terminate from their main thread of execution, and
should not issue the protected mode Int 21H Function 4CH from within a
hardware interrupt handler, exception handler, or real mode callback.
Client may, however, terminate from within a protected mode routine
that has been entered via the DPMI raw mode switch service. Clients
which wish to terminate-and-stay-resident to provide services to
protected mode clients should use <a href="api/310c01.html">DPMI
Function 0C01H</a> rather than Int 21H Function 31H.<p>
<i>Note:</i> Although the DPMI host monitors for Int 21H Function 4Ch
in protected mode, it ignores all other Int 21H Functions. DOS
Extenders typically install an interrupt 21H handler of their own in
order to trap and service DOS function requests by a protected mode
application; thus, the DOS Extender's Int 21H handler will always see
the Function 4CH termination request first. The DOS Extender should
perform any cleanup activities of its own and then pass the
termination request to the DPMI host by chaining the original owner of
the protected mode Int 21H vector.<p>

View File

@@ -0,0 +1,209 @@
At one point in its execution or another, every DPMI client runs on
four different stacks: an application stack, a locked protected mode
stack, a real mode stack, and a DPMI host stack. It is important to
understand how the host maintains these stacks to fully understand the
protected mode environment.<p>
The <i>application stack</i> is the primary stack that the DPMI client
executes on. It is initially the real mode stack that the client was
on when it switched into protected mode, although nothing prevents the
client from switching protected mode stacks at any point after the
initial mode switch. Th application stack can be unlocked if desired.
Software interrupts executed in protected mode are reflected on this
stack.<p>
The <i>locked protected mode stack</i> is provided by the DPMI host.
The host automatically switches to this stack during servicing of
hardware interrupts, software interrupts 1CH, 23H, and 24H, all
exceptions, and during the execution of real mode callbacks.
Subsequent nested interrupts or calls will not cause a stack switch.
If the client switches off this stack, the new stack must also be
locked and will become the protected mode stack until it switches
back. When the interrupt or call returns, the host switches back to
the original protected mode stack. Note that the host must provide a
minimum of one 4 KB locked stack, and that software interrupts other
than 1CH, 23H, and 24H do <i>not</i> use this stack. (Refer Appendix
D for descriptor usage rule of locked stack.)<p>
The <i>real mode stack</i> is also provided by the DPMI host, and is
usually located in the DPMI host data area allocated by the client
prior to its initial switch into protected mode. The real mode stack
is at least 200H bytes in size and is always located in locked memory.
Interrupts that are reflected to real mode, as well as calls to real
mode interrupt handlers or procedures via <a
href="api/310300.html">Int 31H Functions 0300H</a>, <a
href="api/310301.html">0301H</a>, or <a
href="api/310302.html">0302H</a>, will use this stack.<p>
A <i>DPMI host stack</i> is only accessible to the DPMI host; it is
used by the host to handle interrupts and exceptions that occur while
the host is executing on behalf of the client. For example, when the
client requests a mode switch, the original SS:(E)SP of the protected
mode program can be saved on the host stack while the DPMI host
switches onto the locked protected mode stack.<p>
There are four different ways that a client can force a mode switch
between protected and real mode:
<ul>
<li> Execute the default interrupt reflection handler (all interrupts
other than Int 31H and Int 21H Function 4CH are initialized by the
DPMI host to point to a handler that reflects the interrupt to real
mode);<p>
<li> Use the DPMI translation services (<a href="api/310303.html">Int
31H Function 0303H</a>, <a href="api/310301.html">0301H</a>, and <a
href="api/310302.html">0302H</a>) to call a real mode interrupt
handler or procedure;<p>
<li> Allocate a real mode callback address with <a
href="api/310303.html">Int 31H Function 0303H</a>; when a real mode
program transfer control to the callback address, the DPMI host will
switch the CPU from real mode into protected mode;<p>
<li> Use the DPMI raw mode switch functions, whose addresses are
obtained with <a href="api/310306.html">Int 31H Function 0306H</a>.<p>
</ul>
All of these mode switches except for the raw mode switches may save
some information on the DPMI host's stack. This means that clients
should not terminate within nested mode switches unless they are using
the raw mode switching services. However, even clients that use raw
mode switches should not attempt to terminate from a hardware
interrupt or exception handler or real mode callback because the DPMI
host performs automatic mode and stack switching during these
events.<p>
Clients that use the raw mode switch services and perform nested mode
switches must use the DPMI state save/restore functions (whose
addresses may be obtained with <a href="api/310305.html">Int 31H
Function 0305H</a>), causing the host to maintain information on the
"other" mode's current state. This information includes the CS:(E)IP,
SS:(E)SP, and other segment register contents; values that the client
has no way to access directly. For example, during the service of a
hardware interrupt that occurs in real mode, the DPMI host may
preserve the real mode CS:(E)IP, SS:(E)SP, and segment registers on
the host stack, causing a return to the wrong address when the handler
finally executes the IRET.<p>
<b>Example:</b> This example illustrates code that saves the state of
the real mode registers using the DPMI save/restore function, switches
to real mode using the raw mode switch service, issues a DOS call to
open a file, switches back to protected mode using the raw mode switch
service, and restores the state of the real mode registers using the
save/restore function. The protected mode registers are saved by
pushing them on the stack in the usual fashion. The example is
intended only to show the logical sequence of execution; in a real
program, the real mode and protection mode variables and functions
would likely reside in separate segments.
<pre>
savsiz dw 0 ; size of state information
realsrs dd 0 ; far pointer to real mode
; save/restore state entry point
protsrs dd 0 ; far pointer to protected mode
; save/restore state entry point
realrms dd 0 ; far pointer to real mode
; raw mode switch entry point
protrms dd 0 ; far pointer to protected mode
; raw mode switch entry point
protdw dw 0 ; placeholder for protected mode DS
protip dw 0 ; placeholder for protected mode IP
protcs dw 0 ; placeholder for protected mode CS
protsp dw 0 ; placeholder for protected mode SP
protss dw 0 ; placeholder for protected mode SS
.
.
.
; this code is executed during
; application initialization
mov ax,305h ; get addresses of DPMI host's
<a href="api/310305.html">int 31h</a> ; state save/restore entry points
mov savsiz,ax ; save state info buffer size
mov word ptr realsrs,cx ; BX:CX = state save/restore
mov word ptr realsrs+2,bx ; entry point for real mode
mov word ptr protsrs,di ; SI:DI = state save/restore
mov word ptr protsrs+2,si ; entry point for protected mode
mov ax,306h ; get address of DPMI host's
<a href="api/310306.html">int 31h</a> ; raw mode switch entry points
mov savsiz,ax ; save state info buffer size
mov word ptr realrms,cx ; BX:CX = raw mode switch
mov word ptr realrms+2,bx ; entry piont for real mode
mov word ptr protrms,di ; SI:DI = raw mode switch
mov word ptr protrms+2,si ; entry point for protected mode
; must also initialize the
; sp and realss variables
.
.
.
; this code is executed during
; program execution
callopenfile proc
pusha ; save protected mode registers
push es
sub sp,savsiz ; allocate space on current stack
mov di,sp ; to save real mode state
mov ax,ss ; set ES:DI = address of buffer
mov es,ax ; to receive state information
xor al,al ; AL=0 for save state request
call protsrs ; call state save/restore routine
mov protds,ds ; save current DS for switch back
mov protss,ss ; save current SS
mov protsp,sp ; save current SP
mov protip,offset returnfromreal ; save return IP
mov protcs,cs ; save return CS
mov ax,seg filename ; load real mode DS
mov ds,realss ; load real mode SS
mov bx,realsp ; load real mode SP
mov si,seg openfile ; load real mode CS
mov di,offset openfile ; load real mode IP
jmp protrms ; go to openfile
returnfromreal:
mov ax,ss ; let ES:DI = address of buffer
mov es,ax ; holding state information
mov di,sp
mov al,1 ; AL=1 to restore state
call protsrs ; call state restore routine
add sp,savsiz ; discard state info buffer
pop es
popa ; restore protected mode registers
ret
callopenfile endp
.
.
.
; this code is executed in real mode
openfile proc
mov dx,offset filename
mov ah,3dh ; issue Open File DOS call
int 21h
jc openerr ; check for error (not shown here)
mov filehandle,bx ; save file handle
mov ax,protds ; load protected mode DS
mov dx,protss ; load protected mode SS
mov bx,protsp ; load protected mode SP
mov si,protcs ; load protected mode CS
mov di,protip ; load protected mode IP
jmp realrms
openfile endp
</pre>

View File

@@ -0,0 +1,46 @@
Under many DPMI hosts, interrupts will always remain enabled in
protected mode (i.e. the interrupt flag will be set at all times) to
allow preemptive multitasking. Such hosts will maintain a virtual
interrupt state for each virtual machine, trapping the execution of
instructions that ordinarily affect the hardware interrupt flag and
adjusting the client's virtual interrupt flag accordingly. When the
virtual interrupt flag is cleared by the client's execution of
<tt>CLI</tt> or call to <a href="api/310900.html">DPMI function Int
31H 0900H</a>, the program will not receive any hardware interrupts
until it sets the flag again with <tt>STI</tt> or calls <a
href="api/310901.html">Function 0901H</a>. DPMI clients should not
use the <tt>PUSHF</tt> instruction to examine their interrupt status.
This is because <tt>PUSHF</tt> pushes the real processor flags onto
the stack, which do not reflect the state of the client's virtual
interrupt flag. Similarly, clients cannot use <tt>IRET(D)</tt> or
<tt>POPF</tt> to alter the interrupt flag, because these instructions
access the physical interrupt flag and are ignored by the CPU due to
the client's privilege level. <p>
<b>Example:</b> The following source code demonstrates how a client
would disable virtual interrupts prior to entry to an
interrupt-critical section of code, then restore the virtual interrupt
flag to its previous state at the end of the critical section:
<pre>
mov ax,0900h ; get previous virtual interrupt
<a href="api/310900.html">int 31h</a> ; flag and disable interrupts
push ax ; save value 0900H or 0901H
.
. ; interrupt-critical code goes here
.
pop ax
<a href="api/310900.html">int 31h</a> ; restore previous interrupt flag
</pre>
If the client already knows (or does not care about) the previous
state of the virtual interrupt flag, it can use <tt>CLI</tt> and
<tt>STI</tt> instead of <a href="api/310900.html">DPMI functions
0900H</a> and <a href="api/310901.html">0901H</a>. The programmer
should assume that the execution of either of these instructions will
be slow. <p>

View File

@@ -0,0 +1,55 @@
The programmable interrupt controllers are mapped by the DPMI host to
the system's default interrupt assignments. On an IBM AT-compatible
system, for example, the master interrupt controller (IRQ0 through
IRQ7) is programmed to use a base interrupt level of 8 and the slave
controller (IRQ8 through IRQ15) uses a base interrupt level of 70H.<p>
All of the code and data that may be touched by hardware interrupt
handlers must reside in locked memory to avoid page faults at
interrupt time. The handler will always be called on a locked stack.
As in real mode, hardware interrupt handlers are called with virtual
interrupts disabled and the trace flag reset. In systems where the
CPU's interrupt flag is virtualized, <tt>IRET</tt> may not restore the
interrupt flag. Therefore, clients should execute a <tt>STI</tt>
before executing <tt>IRET</tt> or else interrupts will remain
disabled. <p>
Protected mode hardware interrupt handlers that call a real mode
routine must either ensure that the real mode code will not modify
segment registers or user the DPMI state save/restore services (see
page 94). However, any interrupt handler that executes completely in
protected mode, or uses the translation services (<a
href="api/310300.html">Int 31H Functions 0300H</a>, <a
href="api/310301.html">0301H</a>, or <a
href="api/310302.html">0302H</a>), does not need to save the real mode
register state. <p>
Personal computers with two programmable interrupt controllers usually
have a BIOS that redirects one of the interrupts from the slave
controller into the range of the master controller for compatibility
with older, 8086/88-based systems. For example, devices jumpered for
IRQ2 on PC/AT-compatible computers actually interrupt on IRQ 9 (Int
71H), but the BIOS on these systems converts Int 71H to Int 0AH yet
sends the EOI command (appropriately) to the slave controller. A
protected mode client that needs access to the redirected interrupt
might use a variation on one of the following techniques:
<ul>
<li> Install only a real mode handler for the target interrupt, taking
advantage of the built-in redirection. This method is robust on
systems where other software has reprogrammed the interrupt
controllers, or where the slave interrupt controller may be
absent. <p>
<li> Install both real mode and protected mode handlers for the target
interrupt. In such cases, the program must send the EOI command to
both the slave and master interrupt controllers since the BIOS is
never called. This method is more efficient in that there are not any
unnecessary switches to real mode. <p>
</ul>

View File

@@ -0,0 +1,28 @@
Ordinarily, a handler installed with <a href="api/310205.html">DPMI
Function 0205H</a> will only service software interrupts that are
executed in protected mode; real mode software interrupts are passed
to handlers installed with DOS Int 21H Function 25H issued from real
mode, <a href="api/310201.html">DPMI Int 31H Function 0201H</a>, or by
direct manipulation of the interrupt vector table at real mode address
0000:0000. However, there are three real mode software interrupts
that a DPMI host will always reflect to a protected mode handler, if
one is installed:
<ul>
Int 1CH - ROM BIOS timer tick interrupt<br>
Int 23H - DOS Ctrl+C interrupt<br>
Int 24H - DOS critical error interrupt<br>
</ul>
Clients should never terminate during the processing of interrupts
that were reflected from real mode. Such a termination might prevent
the DPMI host from cleaning up the client's resources properly. <p>
Protected mode handlers for software interrupts 0-7 are called with
virtual interrupts disabled and trace flag reset, and these handlers
should return with interrupts enabled. All other software interrupts
do not modify the interrupt flag state. <p>

View File

@@ -0,0 +1,35 @@
When a DPMI client switches into protected mode, a unique interrupt
descriptor table (IDT) is created for the client by the DPMI host.
Initially, all software interrupts (except for Int 31H, Int 2FH and
Int 21H Function 4CH) or external hardware interrupts are directed to
a handler that simply reflects the interrupt to real mode; i.e. the
DPMI host's default handler simply switches the CPU into real mode and
re-issues the interrupt, so that it can be serviced by the original
real mod owner of the interrupt. The contents of the general
registers and flags are passed to the real mode handler and the
modified registers and flags are returned to the protected mode
handler. Segment registers and the stack pointer are not passed
between modes; the contents of the segment registers after the switch
to real mode are undefined, and the DPMI host automatically supplies a
valid real mode stack. <p>
DPMI clients can install their own distinct real mode or protected
mode handlers for software and external hardware interrupts with <a
href="api/310201.html">Functions 0201H</a> and <a
href="api/310205.html">0205H</a> respectively. If a protected mode
handler is installed, it is called instead of any real mode handler or
the DPMI host's default handler. Just as in real mode, the protected
mode handler can either service the interrupt and terminate with an
IRET, or transfer to the next handler in the chain by executing a
<tt>PUSHF/CALL</tt> or a <tt>FAR JMP</tt>. The final handler in the
protected mode handler chain (the DPMI host's default handler) will
reflect the interrupt to real mode. <p>
<hr>
<img src="/icons/menu.sm.gif"><a href="ch4.4.1.html">Virtual Interrupts</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.4.2.html">Hardware Interrupts</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.4.3.html">Software Interrupts</a><br>

View File

@@ -0,0 +1,308 @@
Exceptions are interrupts that are generated internally by the CPU
when certain conditions are detected during the execution of a
program. Examples of such conditions are: use of an invalid selector,
use of a selector for which the program has insufficient privileges,
use of an offset outside the limits of a segment, execution of an
illegal opcode, or division by zero. The DPMI host distinguishes
between exceptions and external hardware interrupts or software
interrupts. <p>
Handlers for exceptions can only be installed with <a
href="api/310203.html">Int 31H Functions 0203H</a>, <a
href="api/310212.html">0212H</a>, or <a
href="api/310213.html">0213H</a>. If the client does not install a
handler for a particular exception, or installs a handler but chains
to the host's default handler, the host reflects the exception as a
real mode interrupt for exceptions 0,1,2,3,4,5, and 7. The default
behavior of exceptions 6 and 8-1FH is to terminate the client (some
hosts may decide that they have to terminate the VM because the fault
came from real mode code or it is in a non-terminatable state).<p>
<a href="api/310203.html">Function 0203H</a> was defined in DPMI version 0.9 and continues to be
supported in DPMI version 1.0 for compatibility reasons. Exception
handlers installed with <a href="api/310203.html">Function 0203H</a> are only called for exceptions
that occur in protected mode. All exceptions are examined by the DPMI
host. The host processes any exception that it is responsible for,
such as page fault for virtual memory management. These <i>transparent
exceptions</i> are never passed to the client exception handlers. All
other exceptions become <i>visible exceptions</i> to a client and are
passed to the client exception handler (if any) from the DPMI host.
The client exception handlers must return with a <tt>FAR RETURN</tt>,
with interrupts disabled on a locked stack, and with SS, (E)SP, CS,
and (E)IP registers at the point of exception pushed on the stack.
All other registers are unchanged from their contents at the point of
exception. The stack frame for 16-bit handlers installed with
Function 0203H has the following format:
<pre>
15 0
+---------------+
| SS |
|---------------| 0EH
| SP |
|---------------| 0CH
| Flags |
|---------------| 0AH
| CS |
|---------------| 08H
| IP |
|---------------| 06H
| Error Code |
|---------------| 04H
| Return CS |
|---------------| 02H
| Return IP |
|---------------| 00H <-- SS:SP
</pre>
The stack frame for 32-bit handlers installed with <a
href="api/310203.html">Function 0203H</a> has the following format:
<pre>
31 15 0
+---------------+---------------|
| Reserved | SS |
+---------------+---------------| 1CH
| ESP |
|-------------------------------| 18H
| EFLAGS |
|---------------+---------------| 14H
| Reserved | CS |
|---------------+---------------| 10H
| EIP |
|-------------------------------| 0CH
| Error Code |
|---------------+---------------| 08H
| | Return CS |
|---------------+---------------| 04H
| Return EIP |
|-------------------------------| 00H <-- SS:ESP
</pre>
The error code in the stack frame is only valid for the following
exceptions:
<table>
<tr><td align=center>08H</td><td align=left>Double fault</td></tr>
<tr><td align=center>0AH</td><td align=left>Invalid TSS</td></tr>
<tr><td align=center>0BH</td><td align=left>Segment not present</td></tr>
<tr><td align=center>0CH</td><td align=left>Stack fault</td></tr>
<tr><td align=center>0DH</td><td align=left>General protection fault</td></tr>
<tr><td align=center>0EH</td><td align=left>Page Fault</td></tr>
</table>
In the case of other exceptions and faults, the value of the error
code is undefined. The fields marked <tt>Return CS</tt>, <tt>Return
(E)IP</tt>, and <tt>Reserved</tt> in the stack frame should should not
be modified, but anything else in the stack frame can be altered by
the client before returning from the exception handler. <p>
The exception handler must preserve and restore all registers, and
must either jump to the next handler in the chain or terminate with a
<tt>RETF</tt> (far return) instruction. In the latter case, the
original SS:(E)SP, CS:(E)IP and flags on the stack, including the
interrupt flag, will be restored. The exception handler can arrange
to transfer control to a more general error-handling routine within
the application by modifying the CS:(E)IP that is stored in the stack
frame above the Return CS:(E)IP. <p>
DPMI version 1.0 supports an expanded stack frame for exception
handlers, and the ability to install separate handlers for exceptions
which occur in real mode and in protected mode with <a
href="api/310210.html">Functions 0212H</a> and <a
href="api/310213.html">0213H</a>. The expanded frame is defined on
the stack <i>above</i> the frame previously described for handlers
installed with <a href="api/310203.html">Function 0203H</a>. This
allows DPMI 0.9-compatible handlers and DPMI 1.0-compatible handlers
to coexist in the same handler chain; old handlers will be oblivious
to the additional information available beyond the old stack frame,
while new handlers can ignore the old frame and use only the expanded
frame higher up on the stack. <p>
The format of the expanded stack frame for both 16-bit and 32-bit
handlers installed with <a href="api/310212.html">Functions 0212H</a>
and <a href="api/310213.html">0213H</a> is as follows:
<pre>
31 15 0
+---------------------------------------------------------------+ 58H
| PTE |
|---------------------------------------------------------------| 54H
| CR2 |
|---------------------------------------------------------------| 50H
| Reserved | GS |
|---------------------------------------------------------------| 4CH
| Reserved | FS |
|---------------------------------------------------------------| 48H
| Reserved | DS |
|---------------------------------------------------------------| 44H
| Reserved | ES |
|---------------------------------------------------------------| 40H
| Reserved | SS |
|---------------------------------------------------------------| 3CH
| ESP |
|---------------------------------------------------------------| 38H
| EFLAGS |
|-------------------------------+-------------------------------| 34H
| Exception information bits | CS |
|-------------------------------+-------------------------------| 30H
| EIP |
|-------------------------------+-------------------------------| 2CH
| Error Code |
|-------------------------------+-------------------------------| 28H
| Reserved | Return CS (32-bit) or 0 |
|-------------------------------+-------------------------------| 24H
| Return EIP (32-bit) or CS:IP (16-bit) |
|-------------------------------+-------------------------------| 20H+SS:(E)SP
</pre>
A 32-bit stack frame image is always presented, even for 16-bit
handlers, and the offset from SS:(E)SP to the expanded stack frame is
always 20H (32) regardless of the handler type. The DS, ES, FS, and
GS registers are saved for both real and protected mode. The client
can inspect the VM bit in EFLAGS to determine the mode at the point of
exception. The CS field at SS:(E)SP+24H is zero if the handler is
running in 16-bit protected mode. <p>
The exception information bits at SS:(E)SP+32H have the following
meanings: <p>
<table border=1 cellspacing=0 cellpadding=4>
<tr> <th>Bit</th> <th colspan=2>Significance</th> </tr>
<tr> <td align=center rowspan=2>0</td>
<td align=center>0</td> <td align=left>exception occurred in the
client</td></tr>
<td align=center>1</td> <td align=left>exception occurred in the host
(most likely due to page fault or invalid selector passed to host in
an Int 31H call)</td></tr>
<tr> <td align=center rowspan=2>1</td>
<td align=center>0</td> <td align=left>exception can be retried</td></tr>
<td align=center>1</td> <td align=left>Exception cannot be retried,
handler should perform whatever cleanup is possible</td></tr>
<tr> <td align=center rowspan=2>2</td>
<td align=center>0</td> <td align=left>host exception should be
retried (invalid selector or page causing fault corrected by exception
handler, this is the default)</td></tr>
<td align=center>1</td> <td align=left>host exception is being
redirected somewhere other than a retry address</td></tr>
<tr> <td align=center>3</td><td colspan=2
align=left>reserved</td></tr>
</table><p>
Bits 0 through 2 of the exception information bits are relevant on
hosts which support the Exceptions Restartability capability (see <a
href="api/310401.html">Int 31H Function 0401H</a>). Bits 0 and 1 of
the exception information bits are supplied to the client by the host.
The default state of bit 2 as set by the host is zero, and the client
may st the bit to 1 before returning from the exception handler.<p>
Bit 0-14 of the error code at SS:(E)SP+28H are the "virtual" DR6 on
debug (Int 1) exceptions, and correspond to debug breakpoint 0-14. In
other words, if bits 0 and 2 are set in the error code field on an Int
1 exception, then debug watchpoints 0 and 2 have fired. The handle
returned by the Set Debug Watchpoint (<a
href="api/310b00.html">Function 0B00H</a>) corresponds to the bit
number in the virtual DR6. Bit 15 of the virtual DR6 is set (1) if
the Int 1 is due to the trap flag. Breakpoints may be virtualized,
and there is no guarantee of correspondence with the actual hardware.
The provision for up to 15 breakpoints is made for future CPUs or
external debugging hardware (80386 and 80486 CPUs support only four
hardware breakpoints). <p>
The PTE and CR2 fields of the expanded stack frame at SS:(E)SP+50H and
54H respectively are only valid for page faults (Int 0EH). Bits 0-7
of the PTE (page table entry) field are from the actual PTE and may be
virtualized by the host; the remaining bits of the PTE field are
undefined. The CR2 field contains the linear address that caused the
fault. <p>
Exception handlers installed with <a href="api/310212.html">Functions
0212H</a> and <a href="api/310213.html">0213H</a> may terminate in any
of the following three ways:
<ul>
<li> <tt>RETF</tt> from the old-style stack frame (only modifications
to the old-style stack frame will be recognized and a client may not
use this type of return for real-mode exceptions);<p>
<li> Discard the old-style stack frame by adding 20H (32) to (E)SP,
then <tt>RETF</tt> from the new-style (expanded) stack frame);<p>
<li> <tt>FAR JUMP</tt> to previous owner of the exception (the previous
owner should never be <tt>CALL</tt>ed).<p>
</ul>
The fields at offsets 2CH through 4FH in the expanded stack frame may
be modified by an exception handler. Note that the handler should
only modify the values in the particular frame (SS:(E)SP)+0 or
SS:(E)SP+20H) that it will use for the <tt>RETF</tt>. Altered values
in the other frame are ignored by the DPMI host. Real mode exceptions
do not have valid data in the old-style frame. A real mode exception
handler must discard the old-style stack frame if it returns.<p>
<b>Example:</b> The following code illustrates how a client would
install its own exception handler for general protection (GP) faults.
The actual handler does nothing more than reach into the stack frame
and alter the return address, so that control within the application
restarts at a different point after the exception handler exits.
<pre>
prevgp dd 0 ; address of previous
; GP fault handler
.
. ; this code is executed during
. ; application initialization...
mov ax,0210h ; get address of previous
mov bl,13 ; owner of GP fault vector
<a href="api/310210.html">int 31h</a>
mov word ptr prevgp,dx ; save as far pointer
mov word ptr prevgp+2,cx
mov ax,0212h ; install our GP fault handler
mov bl,13
mov cx,cs ; CX:DX = handler address
mov dx,offset _TEXT:gpfisr
<a href="api/310212.html">int 31h</a>
jc init9 ; jump, couldn't install
. ; continue with initialization
.
.
gpfisr proc far ; this is the actual exception
; handler for GP faults
add sp,20h ; discard "old" stack frame
push bp ; point CS:IP in stack frmae to
mov bp,sp ; GP fault error message routine
mov word ptr [bp+0eh],offset _TEXT: gpferr
mov word ptr [bp+12h],cs
pop bp
ret ; now return from exception
gpfisr endp
gpferr proc near ; this routine executes after
; GPFISR returns to DPMI host
mov ax,4c01h ; terminate DPMI client with
int 21h ; nonzero return code
gpferr endp
</pre>

View File

@@ -0,0 +1,231 @@
The DPMI real mode callback mechanism allows a DPMI protected mode
client to be called as a subroutine by real mode programs in a
transparent manner. That is, a real mode program can use a real mode
callback to pass information to the DPMI client, or obtain services
provided by the DPMI client, without necessarily being aware of
protected mode or extended memory in any way. The callback mechanism
can be thought of as the converse of <a href="api/310300.html">DPMI
Int 31H Functions 0300H</a>, <a href="api/310301.html">0301H</a>, and
<a href="api/310302.html">0302H</a>, which allow a DPMI client to pass
information to a real mode program, or obtain services from a real mode
program, in a manner that is similarly transparent to the real mode
program. <p>
In order to make a real mode callback available, the DPMI client must
first call <a href="api/310303.html">Int 31H Function 0303H</a> with
the selector and offset of the protected mode routine which will
receive control when the callback is entered, and the selector and
offset of a real mode register data structure (in the same format as
used for <a href="api/310300.html">Int 31H Functions 0300H</a>, <a
href="api/310301.html">0301H</a>, and <a
href="api/310302.html">0302H</a>). <a href="api/310303.html">Function
0303H</a> will return a real mode address (segment and offset) for the
callback entry point that can be passed to a real mode program via a
software interrupt or far call (<a href="api/310300.html">Int 31H
Functions 0300H</a>, <a href="api/310301.html">0301H</a>, or <a
href="api/310302.html">0302H</a>), a DOS memory block, or any other
convenient mechanism. <p>
When the real mode program executes a <tt>FAR CALL</tt> to the real
mode callback address supplied to it by the DPMI client, the DPMI host
saves the contents of all real mode registers into the DPMI client's
real mode register data structure, switches the CPU into protected
mode, and enters the DPMI client's callback routine with the following
conditions:
<ul>
<li> Interrupts disabled
<li> CS:(E)IP = selector:offset specified in the original call to
<a href="api/310303.html">Int 31H Function 0303H</a>
<li> DS:(E)SI = selector:offset corresponding to real mode SS:SP
<li> ES:(E)DI = selector:offset of real mode register data structure
<li> SS:(E)SP = locked protected mode stack provided by DPMI host
<li> All other registers undefined
</ul>
The format of the real mode register data structure is as follows:
(Note that the content of the 32H bytes data structure are undefined
at the time of the original <a href="api/310303.html">Int 31H Function
0303H</a> call.) <p>
<blockquote><table border=1 cellspacing=0 cellpadding=4>
<tr><th>Offset</th><th>Length</th><th>Contents</th></tr>
<tr><td align=center>00H</td><td align=center>4</td><td align=left>DI or EDI</td></tr>
<tr><td align=center>04H</td><td align=center>4</td><td align=left>SI or ESI</td></tr>
<tr><td align=center>08H</td><td align=center>4</td><td align=left>BP or EBP</td></tr>
<tr><td align=center>0CH</td><td align=center>4</td><td align=left>reserved, should be zero</td></tr>
<tr><td align=center>10H</td><td align=center>4</td><td align=left>BX or EBX</td></tr>
<tr><td align=center>14H</td><td align=center>4</td><td align=left>DX or EDX</td></tr>
<tr><td align=center>18H</td><td align=center>4</td><td align=left>CX or ECX</td></tr>
<tr><td align=center>1CH</td><td align=center>4</td><td align=left>AX or EAX</td></tr>
<tr><td align=center>20H</td><td align=center>2</td><td align=left>CPU status flags</td></tr>
<tr><td align=center>22H</td><td align=center>2</td><td align=left>ES</td></tr>
<tr><td align=center>24H</td><td align=center>2</td><td align=left>DS</td></tr>
<tr><td align=center>26H</td><td align=center>2</td><td align=left>FS</td></tr>
<tr><td align=center>28H</td><td align=center>2</td><td align=left>GS</td></tr>
<tr><td align=center>2AH</td><td align=center>2</td><td align=left>IP</td></tr>
<tr><td align=center>2CH</td><td align=center>2</td><td align=left>CS</td></tr>
<tr><td align=center>2EH</td><td align=center>2</td><td align=left>SP</td></tr>
<tr><td align=center>30H</td><td align=center>2</td><td align=left>SS</td></tr>
</table></blockquote>
The callback procedure can then extract its parameters from the real
mode register data structure and/or copy parameters from the real mode
stack to the protected mode stack. Recall that the segment register
fields of the real mode register data structure contain segment or
paragraph addresses that are not valid in protected mode. Far
pointers passed in the real mode register data structure must be
translated to virtual addresses before they can be used. The
recommended procedure is for the DPMI client to allocate a selector
for this purpose during its initialization, then use <a
href="api/310007.html">Int 31H Function 0007H</a> within the callback
procedure to set the segment base to 16 times the value found in the
real mode segment register. The DPMI client should <i>not</i> use <a
href="api/310002.html">Int 31H Function 0002</a> for this purpose,
because selectors allocated by <a href="api/310002.html">Function
0002</a> can never be freed. <p>
The callback procedure exits by executing an <tt>IRET</tt> with the
address of the real mode register data structure in ES:(E)DI, passing
information back to the real mode caller by modifying the contents of
the real mode register data structure and/or manipulating the contents
of the real mode stack. The callback procedure is responsible for
setting the proper address for resumption of real mode execution into
the real mode register data structure; typically, this is accomplished
by extracting the return address from the real mode stack and placing
it into the CS:IP fields of the real mode register data structure.
After the <tt>IRET</tt>, the DPMI host switches the CPU back into real
mode, loads all registers (including CS:IP) with the contents of the
real mode register data structure, and finally returns control to the
real mode program.<p>
Since the real mode call structure and the selector used for the real
mode SS are static, care must be taken when writing DPMI client
callback procedures that may be reentered (for example, by a real mode
program that services hardware interrupt). The simplest method of
avoiding reentrancy is to leave interrupts disabled throughout the
entire callback procedure. However, if the amount of code executed by
the callback is large, the client may find it more desirable to copy
the real mode register data structure into a dynamically allocated
buffer and then re-enable interrupts and not use the incoming DS any
more. The real mode register data structure pointed to by ES:(E)DI
upon return from the callback procedure is <i>not</i> required to be
at the same address as the original real mode register data
structure.<p>
DPMI hosts must provide a minimum of 16 callback addresses per virtual
machine. Real mode callbacks are a limited system resource. A DPMI
client should always use <a href="api/310304.html">Int 31H Function
0304H</a> to free any callbacks that it is no longer using. <p>
<b>Example:</b> The following code is an example 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 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.
<pre>
;******************************************************
;
; 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
<a href="api/31000a.html">int 31h</a>
jc ERROR
mov ds, ax
assume ds:_TEXT
; Get current Int 21h real mode SEG:OFFSET
;
mov ax, 0200h
mov bl, 21h
<a href="api/310200.html">int 31h</a>
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
<a href="api/310303.html">int 31h</a>
jc ERROR
; Hook real mode int 21h with the call-back
; address
;
mov ax, 0201h
mov bl, 21h
int 21h
jc ERROR
;******************************************************
;
; 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 ; St 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
</pre>

View File

@@ -0,0 +1,190 @@
Shared memory blocks can be used for inter-client communication or
simply to hold tables or subroutine libraries that are needed by more
than one client. Explicit use of shared blocks is necessary because
each VM has its own linear address space, and thus cannot inspect or
modify the memory owned by a client in another virtual machine. The
basic strategy for use of a shared memory block is as follows:
<ul>
<li> Allocate shared memory block;<p>
<li> Establish addressability for the shared block;<p>
<li> Make a successful serialization request for the shared block
(i.e. obtain ownership or right of access to the block);<p>
<li> Access the code or data in the shared block; <p>
<li> Free the serialization of the shared block;<p>
<li> Deallocate the shared memory block.<p>
</ul>
Shared memory blocks are allocated with <a href="api/310d00.html">Int 31H Function 0D00H</a>. The
client passes the address of a data structure that specifies the ASCIIZ
name and requested size of the shared block to the host; the host
returns the block's handle, linear base address, and actual size in
the same structure. The block's true size is determined by the first
client to allocate the block, and the block will have the same linear
address for all clients which allocate it. <p>
After the shared block is allocated, the client must allocate one or
more descriptors that will be used to address the block with <a
href="api/310000.html">Int 31H Function 0000H</a>. Once descriptor(s)
have been allocated and initialized to point to a shared memory block
through separate LDT management calls, the client has the physical
capability to read, write, or execute addresses within the block as
allowed by the access rights/type byte. The client should synchronize
with any other clients which might have addressability to the same
block, to avoid race conditions or corruption of data. This
synchronization is accomplished with <a href="api/310d02.html">Int 31H
Function 0D02H</a> (Serialize on Shared Memory) and <a
href="api/310d03.html">Int 31H Function 0D03H</a> (Free Serialization
on Shared Memory). Serialization can be thought of as representing
ownership or right of access to a shared memory block.<p>
In essence, <a href="api/310d02.html">Int 31H Functions 0D02H</a> and
<a href="api/310d03.html">0D03H</a> treat the handle of a shared
memory block as a semaphore. The client can request exclusive
(read/write) or shared (read-only) serialization with <a
href="api/310d02.html">Int 31H Function 0D02H</a>, and the host will
grant the serialization if no other client has already obtained a
conflicting serialization on the same memory block. The client can
then go ahead and manipulate the shared memory block, releasing the
serialization with <a href="api/310d03.html">Int 31H Function
0D03H</a> when it is finished using the block. If the <a
href="api/310d02.html">Int 31H Function 0D02H</a> serialization request
fails, the client will either be suspended until the serialization is
available, or the function will return with an error code, depending
on the parameters supplied by the client. <p>
The first paragraph (16 bytes) of the shared memory block (or the
entire shared block, if smaller than 16 bytes) will always be
initialized to zero on the first allocation and can be used by clients
as an "area initialized" indicator. For example, a shared memory
block might be used by a suite of cooperating client programs to hold
a table of static data or a subroutine library. The first client to
allocate the shared memory block can obtain exclusive ownership of the
block with <a href="api/310d02.html">Int 31H Function 0D02H</a>, load
the necessary data or code into the block from disk, set the first 16
bytes of the block to a nonzero value, and finally release its
ownership of the block with <a href="api/310d03.html">Int 31H Function
0D03H</a>. Other clients that allocate the shared memory block can
check the "area initialized" indicator and know that the desired code
or data is already present in memory. <p>
When a client has finished using the shared memory block, it should
deallocate the shared block with <a href="api/310d01.html">Int 31H
Function 0D01H</a>. After the block is deallocated, the linear
addresses within the block are no longer valid for the current client,
and may cause an exception if accessed. However, the block is not
actually destroyed until all clients which have allocated the block
have also deallocated it. <p>
Note that a client can make multiple (nested) allocation requests for
the same shared memory block, and should assume that each allocation
request will return a distinct handle. The shared block will remain
physically accessible to the client until each of its handles to the
block have been deallocated. Similarly, a client can make multiple
serialization requests for the same block, and will retain "ownership"
of the block until a corresponding number of deserialization requests
have been issued. Lastly, allocation of zero-length shared memory
blocks is explicitly allowed, so that clients can use the handles
resulting from such allocations as pure semaphores. <p>
<b>Example:</b> The following code illustrates how shared memory can
be used to load code and data that can be used by more than one DPMI
client. Note that no serialization calls are required if the memory
is already initialized.
<pre>
memreqstruc struc
length dd ? ; number of bytes requested
actual dd ? ; number of bytes allocated
handle dd ? ; handle for shared memory block
base dd ? ; linear address of shared block
nameptr dp ? ; pointer to shared memory name
dw 0 ; reserved, must be zero
dd 0 ; reserved, must be zero
memreqstruc ends
memname db 'MYBLOCK',0
memreq memreqstruc <> ; allocate request block
.
.
.
mov word ptr memreq.length,2000h ; set reqeusted length
mov word ptr memreq.length+2,0 ; of shared block to 8 KB
; initialize nameptr
mov dword ptr memreq.nameptr, offset memname
mov word ptr memreq.nameptr+4, ds
mov di,ds ; ES:DI = address of shared
mov es,di ; memory request structure
mov di,offset memreq
mov ax,0d00h ; DPMI fxn 0D00H = allocate
<a href="api/310d00.html">int 31h</a> ; shared memory block
jc error ; jump if allocation failed
mov cx,1 ; allocate one LDT descriptor
mov ax,0 ; using DPMI Function 0000h
<a href="api/310000.html">int 31h</a>
jc error ; jump, no descriptor available
mov bx,ax ; let BX = new selector
mov dx,word ptr memreq.base ; let CX:DX = linear base
mov cx,word ptr memreq.base+2 ; address of shared block
mov ax,0007h ; set descriptor base address
<a href="api/310007.html">int 31h</a> ; using DPMI Function 0007H
jc error ; jump, function failed
mov dx,word ptr memreq.actual ; set CX:DX = length-1
mov cx,word ptr memreq.actual+2 ; of shared memory block
sub dx,0
sbb cx,0 ; (BX still = selector)
mov ax,8 ; set descriptor limit using
<a href="api/310008.html">int 31h</a> ; DPMI Function 0008H
jc error ; jump, function failed
mov es,bx ; ES = selector for shared block
mov ax,es:[0] ; is block already initialized
or ax,ax
jnz @@1 ; jump if it's initialized
; not initialized, get ownership
; of the shared memory block
mov di,word ptr memreq.handle ; SI:DI = handle for
mov si,word ptr memreq.handle+2 ; shared memory block
mov dx,0 ; exclusive + wait for ownership
mov ax,0d02h ; DPMI Fxn 0D02H = serialize
<a href="api/310d02.html">int 31h</a>
jc error ; jump if serialization failed
mov ax,es: [0] ; check again if someone else
or ax,ax ; already initialized block
jnz @@2 ; jump if it's initialized
.
. ; load code into the shared
. ; memory block here...
.
@@2: ; now release ownership of
; the shared memory block
mov di,word ptr memreq.handle ; SI:DI = handle for
mov si,word ptr memreq.hanlde+2 ; shared memory block
mov dx,0 ; serialization type = exclusive
mov ax,0d03h ; DPMI Fxn 0D03H = release
<a href="api/310d03.html">int 31h</a>
jc error ; jump if serialization failed
@@1: ; finished initializing the
; shared memory block
</pre>

View File

@@ -0,0 +1,100 @@
A DPMI client that provides resident protected mode services (also
called a "protected mode TSR") must install itself using <a
href="api/310c00.html">Int 31H Functions 0C00H</a> and <a
href="api/310c01.html">0C01H</a>. The protected mode TSR first
declares its intent to remain resident by calling <a
href="api/310c00.html">Function 0C00H</a>, providing the DPMI host
with the code and data descriptors and callback entry points for
16-bit and/or 32-bit protected mode. If the TSR does not wish to
provide services in a particular mode, it provides a code descriptor
for that mode containing all zero bytes. The protected mode TSR then
terminates and stays resident by calling <a href="api/310c01.html">Int
31H Function 0C01H</a>. Note that after this function call, the TSR's
original addressing context is destroyed; its LDT and IDT no longer
exist, although any extended memory blocks it owned at the time of
termination remain allocated. <p>
Whenever another DPMI client <i>in the same virtual machine</i> loads
or terminates, the DPMI host will inspect its list of protected mode
TSRs. If a particular TSR has indicated that it can execute in the
active client's mode, the DPMI host will automatically allocate two
LDT descriptors in the active client's context, initialize them to the
values specified in the protected mode TSR's original <a
href="api/310c00.html">Function 0C00H</a> call, and enter the TSR via
a <tt>FAR CALL</tt> at the offset appropriate to the current mode,
passing the following values:<p>
<table border=1 cellspacing=0 cellpadding=4>
<tr><td>CS</td><td align=left>executable selector which maps the same
memory as the code descriptor in the <a href="api/310c00.html">Int 31H
Function 0C00H</a> data structure for the current mode (16-bit or
32-bit)</td></tr>
<tr><td>(E)IP</td><td align=left>Offset specified in the <a
href="api/310c00.html">Int 31H Function 0C00H</a> data structure for
the current mode (16-bit or 32-bit)</td></tr>
<tr><td>DS</td><td align=left>read/write data selector which maps the
same memory as the data descriptor specified in the <a
href="api/310c00.html">Int 31H Function 0C00H</a> data structure for
the current mode (16-bit or 32-bit)</td></tr>
<tr><td>ES</td><td align=left>0</td></tr>
<tr><td>FS</td><td align=left>0</td></tr>
<tr><td>GS</td><td align=left>0</td></tr>
<tr><td>AX</td><td align=left>Reason for callback: 0=DPMI client
loading, 1=DPMI client terminating</td></tr>
<tr><td>BX</td><td align=left>unique handle for the client within the
virtual machine</td></tr>
</table><p>
When a new DPMI client is loaded and executes the initial switch to
protected mode, the appropriate callback procedure in the protected
mode TSR will be entered by a <tt>FAR CALL</tt> with AX=0
<i>before</i> the DPMI host returns to the new program. The TSR may
then hook interrupts, create descriptors, or allocate memory blocks in
the new client's context prior to the client's access to such
protected mode resources. For example, the initialization callback
gives the TSR an opportunity to insert itself in the chain of handlers
for any arbitrary interrupt or exception. The TSRs are invoked in the
order of their installation but are removed in the reverse order. The
TSR may also need to construct per-client data structures in its own
memory, and can use the value supplied to it in BX as a "handle" for
the client. The TSR must exit from the initialization callback with a
<tt>RETF</tt>.
Similarly, when a DPMI client terminates using Int 21H Function 4CH or
<a href="api/310c01.html">Int 31H Function 0C01H</a>, the TSR's
callback procedure will be entered by a <tt>FAR CALL</tt> with AX=1
<i>before</i> the active client's LDT or IDT has been destroyed. The
protected mode TSR can then perform any client termination
responsibilities of which the client is unaware (e.g. unmapping of
physical memory), release any protected mode resources which it has
acquired on behalf of the client (e.g. ownership of shared memory),
and deallocate any per-client data structures of its own. The
termination callback must exit with a <tt>RETF</tt> and indicate an
action to the DPMI host as follows:
<ul>
Carry = clear to keep resident services in memory, or<br>
Carry = set to remove resident services from memory.
</ul>
A resident service provider should only be removed from memory of the
last client of the virtual machine they are servicing.<p>
<a href="api/310c00.html">Int 31H Functions 0C00H</a> and <a
href="api/310c01.html">0C01H</a> should only be used by DPMI clients
which intend to provide resident services to other protected mode
clients. If the objective is only to provide resident services to
real mode programs, the client should use the DPMI translation service
<a href="api/310300.html">Int 31H Function 0300H</a> to invoke DOS's
Int 31H Function 31H directly. <p>

View File

@@ -0,0 +1,111 @@
Programs that use DPMI services are called DPMI clients. Generally,
DPMI clients fall into one of two categories:<p>
<ul>
<li> DOS Extenders which use DPMI services as building blocks for a
more extensive interface that is exported to application programs running under their control;<p>
<li> Application programs that call DPMI directly.<p>
</ul>
In the near term, most client programs will need to be able to run in
several different environments, each providing a different interface
and range of services. It is recommended that clients test for the
existence of such environments in the following order:<p>
<ul>
<li> DOS Protected Mode Interface (DPMI)-compatible host;<p>
<li> Virtual Control Program Interface (VCPI)-compatible server;<p>
<li> eXtended Memory Specification (XMS)-compatible driver;<p>
<li> <i>Top-Down memory allocation</i> (See Appendix A: Glossary) or
bottom-up (VDISK-compatible) memory allocation.<p>
</ul>
Figure 2 on page 21 illustrates a typical DPMI client configuration,
consisting of a DOS Extender and a protected-mode application. The
application code relies on the DOS Extender functions and APIs. The
DOS Extender contains separate modules for each possible environment,
and code to implement those services that are lacking in a particular
environment. <p>
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. <p>
<b>Figure 2.</b> An example of a DPMI client consisting of a DOS
Extender and a protected-mode application. The client should be able
to run in the presence of DPMI, VCPI, or XMS environments or in the
absence of all three.
<pre>
+----------------------------------------------------------+
| |
| +----------------------------------------------------+ |
| | | |
| | 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) |
| |
+----------------------------------------------------+
</pre>
<hr>
<img src="/icons/menu.sm.gif"><a href="ch4.1.html">Client Initialization</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.2.html">Client Termination</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.3.html">Stacks and Mode Switching</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.4.html">Handling Interrupts</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.5.html">Handling CPU Exceptions</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.6.html">Using Real-Mode Callbacks</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.7.html">Using Shared Memory</a><br>
<img src="/icons/menu.sm.gif"><a href="ch4.8.html">Writing Resident Service Providers</a><br>

View File

@@ -0,0 +1,85 @@
<img src="0.9.gif" alt="[0.9]"> <a href="api/310100.html"><tt>31 0100</tt> - Allocate DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310000.html"><tt>31 0000</tt> - Allocate LDT Descriptors</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310504.html"><tt>31 0504</tt> - Allocate Linear Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310501.html"><tt>31 0501</tt> - Allocate Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310303.html"><tt>31 0303</tt> - Allocate Real Mode Callback Address</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d00.html"><tt>31 0d00</tt> - Allocate Shared Memory</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000d.html"><tt>31 000d</tt> - Allocate Specific LDT Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310301.html"><tt>31 0301</tt> - Call Real Mode Procedure With Far Return Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310302.html"><tt>31 0302</tt> - Call Real Mode Procedure With IRET Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b01.html"><tt>31 0b01</tt> - Clear Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000a.html"><tt>31 000a</tt> - Create Alias Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310703.html"><tt>31 0703</tt> - Discard Page Contents</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310101.html"><tt>31 0101</tt> - Free DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310001.html"><tt>31 0001</tt> - Free LDT Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310502.html"><tt>31 0502</tt> - Free Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310801.html"><tt>31 0801</tt> - Free Physical Address Mapping</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310304.html"><tt>31 0304</tt> - Free Real Mode Callback Address</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d03.html"><tt>31 0d03</tt> - Free Serialization on Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d01.html"><tt>31 0d01</tt> - Free Shared Memory</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1686.html"><tt>2f 1686</tt> - Get CPU Mode</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e00.html"><tt>31 0e00</tt> - Get Coprocessor Status</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310401.html"><tt>31 0401</tt> - Get DPMI Capabilities</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000b.html"><tt>31 000b</tt> - Get Descriptor</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310210.html"><tt>31 0210</tt> - Get Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310211.html"><tt>31 0211</tt> - Get Extended Processor Exception Handler Vector (Real Mode)</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310500.html"><tt>31 0500</tt> - Get Free Memory Information</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050a.html"><tt>31 050a</tt> - Get Memory Block Size and Base</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050b.html"><tt>31 050b</tt> - Get Memory Information</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000e.html"><tt>31 000e</tt> - Get Multiple Descriptors</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310506.html"><tt>31 0506</tt> - Get Page Attributes</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310604.html"><tt>31 0604</tt> - Get Page Size</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310202.html"><tt>31 0202</tt> - Get Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310204.html"><tt>31 0204</tt> - Get Protected Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310306.html"><tt>31 0306</tt> - Get Raw Mode Switch Addresses</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310200.html"><tt>31 0200</tt> - Get Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310006.html"><tt>31 0006</tt> - Get Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310003.html"><tt>31 0003</tt> - Get Selector Increment Value</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310305.html"><tt>31 0305</tt> - Get State Save/Restore Addresses</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b02.html"><tt>31 0b02</tt> - Get State of Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310a00.html"><tt>31 0a00</tt> - Get Vendor-Specific API Entry Point</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f168a.html"><tt>2f 168a</tt> - Get Vendor-Specific API Entry Point</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310400.html"><tt>31 0400</tt> - Get Version</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310902.html"><tt>31 0902</tt> - Get Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310900.html"><tt>31 0900</tt> - Get and Disable Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310901.html"><tt>31 0901</tt> - Get and Enable Virtual Interrupt State</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c00.html"><tt>31 0c00</tt> - Install Resident Service Provider Callback</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310600.html"><tt>31 0600</tt> - Lock Linear Region</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310509.html"><tt>31 0509</tt> - Map Conventional Memory in Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310508.html"><tt>31 0508</tt> - Map Device in Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310702.html"><tt>31 0702</tt> - Mark Page as Demand Paging Candidate</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310602.html"><tt>31 0602</tt> - Mark Real Mode Region as Pageable</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1687.html"><tt>2f 1687</tt> - Obtain Real-to-Protected Mode Switch Entry Point</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310800.html"><tt>31 0800</tt> - Physical Address Mapping</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f1680.html"><tt>2f 1680</tt> - Release Current Virtual Machine's Time Slice</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310603.html"><tt>31 0603</tt> - Relock Real Mode Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310004.html"><tt>31 0004</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310005.html"><tt>31 0005</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310700.html"><tt>31 0700</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310701.html"><tt>31 0701</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b03.html"><tt>31 0b03</tt> - Reset Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310102.html"><tt>31 0102</tt> - Resize DOS Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310505.html"><tt>31 0505</tt> - Resize Linear Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310503.html"><tt>31 0503</tt> - Resize Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310002.html"><tt>31 0002</tt> - Segment to Descriptor</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d02.html"><tt>31 0d02</tt> - Serialize on Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e01.html"><tt>31 0e01</tt> - Set Coprocessor Emulation</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b00.html"><tt>31 0b00</tt> - Set Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310009.html"><tt>31 0009</tt> - Set Descriptor Access Rights</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000c.html"><tt>31 000c</tt> - Set Descriptor</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310212.html"><tt>31 0212</tt> - Set Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310213.html"><tt>31 0213</tt> - Set Extended Processor Exception Handler Vector (Real Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000f.html"><tt>31 000f</tt> - Set Multiple Descriptors</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310507.html"><tt>31 0507</tt> - Set Page Attributes</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310203.html"><tt>31 0203</tt> - Set Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310205.html"><tt>31 0205</tt> - Set Protected Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310201.html"><tt>31 0201</tt> - Set Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310007.html"><tt>31 0007</tt> - Set Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310008.html"><tt>31 0008</tt> - Set Segment Limit</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310300.html"><tt>31 0300</tt> - Simulate Real Mode Interrupt</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c01.html"><tt>31 0c01</tt> - Terminate and Stay Resident</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310601.html"><tt>31 0601</tt> - Unlock Linear Region</a><br>

View File

@@ -0,0 +1,105 @@
<h2>Initialization Services</h2>
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f1680.html"><tt>2f 1680</tt> - Release Current Virtual Machine's Time Slice</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1686.html"><tt>2f 1686</tt> - Get CPU Mode</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1687.html"><tt>2f 1687</tt> - Obtain Real-to-Protected Mode Switch Entry Point</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f168a.html"><tt>2f 168a</tt> - Get Vendor-Specific API Entry Point</a><br>
<h2>LDT Management Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310000.html"><tt>31 0000</tt> - Allocate LDT Descriptors</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310001.html"><tt>31 0001</tt> - Free LDT Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310002.html"><tt>31 0002</tt> - Segment to Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310003.html"><tt>31 0003</tt> - Get Selector Increment Value</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310006.html"><tt>31 0006</tt> - Get Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310007.html"><tt>31 0007</tt> - Set Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310008.html"><tt>31 0008</tt> - Set Segment Limit</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310009.html"><tt>31 0009</tt> - Set Descriptor Access Rights</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000a.html"><tt>31 000a</tt> - Create Alias Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000b.html"><tt>31 000b</tt> - Get Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000c.html"><tt>31 000c</tt> - Set Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000d.html"><tt>31 000d</tt> - Allocate Specific LDT Descriptor</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000e.html"><tt>31 000e</tt> - Get Multiple Descriptors</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000f.html"><tt>31 000f</tt> - Set Multiple Descriptors</a><br>
<h2>Extended Memory Management Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310500.html"><tt>31 0500</tt> - Get Free Memory Information</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310501.html"><tt>31 0501</tt> - Allocate Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310502.html"><tt>31 0502</tt> - Free Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310503.html"><tt>31 0503</tt> - Resize Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310504.html"><tt>31 0504</tt> - Allocate Linear Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310505.html"><tt>31 0505</tt> - Resize Linear Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310506.html"><tt>31 0506</tt> - Get Page Attributes</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310507.html"><tt>31 0507</tt> - Set Page Attributes</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310508.html"><tt>31 0508</tt> - Map Device in Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310509.html"><tt>31 0509</tt> - Map Conventional Memory in Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050a.html"><tt>31 050a</tt> - Get Memory Block Size and Base</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050b.html"><tt>31 050b</tt> - Get Memory Information</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310800.html"><tt>31 0800</tt> - Physical Address Mapping</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310801.html"><tt>31 0801</tt> - Free Physical Address Mapping</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d00.html"><tt>31 0d00</tt> - Allocate Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d01.html"><tt>31 0d01</tt> - Free Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d02.html"><tt>31 0d02</tt> - Serialize on Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d03.html"><tt>31 0d03</tt> - Free Serialization on Shared Memory</a><br>
<h2>DOS Memory Management Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310100.html"><tt>31 0100</tt> - Allocate DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310101.html"><tt>31 0101</tt> - Free DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310102.html"><tt>31 0102</tt> - Resize DOS Memory Block</a><br>
<h2>Interrupt Management Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310200.html"><tt>31 0200</tt> - Get Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310201.html"><tt>31 0201</tt> - Set Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310202.html"><tt>31 0202</tt> - Get Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310203.html"><tt>31 0203</tt> - Set Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310204.html"><tt>31 0204</tt> - Get Protected Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310205.html"><tt>31 0205</tt> - Set Protected Mode Interrupt Vector</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310210.html"><tt>31 0210</tt> - Get Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310211.html"><tt>31 0211</tt> - Get Extended Processor Exception Handler Vector (Real Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310212.html"><tt>31 0212</tt> - Set Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310213.html"><tt>31 0213</tt> - Set Extended Processor Exception Handler Vector (Real Mode)</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310900.html"><tt>31 0900</tt> - Get and Disable Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310901.html"><tt>31 0901</tt> - Get and Enable Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310902.html"><tt>31 0902</tt> - Get Virtual Interrupt State</a><br>
<h2>Translation Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310300.html"><tt>31 0300</tt> - Simulate Real Mode Interrupt</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310301.html"><tt>31 0301</tt> - Call Real Mode Procedure With Far Return Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310302.html"><tt>31 0302</tt> - Call Real Mode Procedure With IRET Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310303.html"><tt>31 0303</tt> - Allocate Real Mode Callback Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310304.html"><tt>31 0304</tt> - Free Real Mode Callback Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310305.html"><tt>31 0305</tt> - Get State Save/Restore Addresses</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310306.html"><tt>31 0306</tt> - Get Raw Mode Switch Addresses</a><br>
<h2>Page Management Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310600.html"><tt>31 0600</tt> - Lock Linear Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310601.html"><tt>31 0601</tt> - Unlock Linear Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310602.html"><tt>31 0602</tt> - Mark Real Mode Region as Pageable</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310603.html"><tt>31 0603</tt> - Relock Real Mode Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310604.html"><tt>31 0604</tt> - Get Page Size</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310702.html"><tt>31 0702</tt> - Mark Page as Demand Paging Candidate</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310703.html"><tt>31 0703</tt> - Discard Page Contents</a><br>
<h2>Debug Support Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b00.html"><tt>31 0b00</tt> - Set Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b01.html"><tt>31 0b01</tt> - Clear Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b02.html"><tt>31 0b02</tt> - Get State of Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b03.html"><tt>31 0b03</tt> - Reset Debug Watchpoint</a><br>
<h2>Miscellaneous Services</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310400.html"><tt>31 0400</tt> - Get Version</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310401.html"><tt>31 0401</tt> - Get DPMI Capabilities</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310a00.html"><tt>31 0a00</tt> - Get Vendor-Specific API Entry Point</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c00.html"><tt>31 0c00</tt> - Install Resident Service Provider Callback</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c01.html"><tt>31 0c01</tt> - Terminate and Stay Resident</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e00.html"><tt>31 0e00</tt> - Get Coprocessor Status</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e01.html"><tt>31 0e01</tt> - Set Coprocessor Emulation</a><br>
<h2>Reserved Function Numbers</h2>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310004.html"><tt>31 0004</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310005.html"><tt>31 0005</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310700.html"><tt>31 0700</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310701.html"><tt>31 0701</tt> - Reserved</a><br>

View File

@@ -0,0 +1,36 @@
The Int 2FH and Int 31H functions supported by DPMI version 1.0 hosts
are described in this section. Each function entry has five parts:
<ul>
<li> The function name, interrupt and function number, and the DPMI
version where the function is first defined. All subsequent DPMI
versions can be assumed to support the function as documented unless
explicitly noted otherwise. <p>
<li> A brief description of the function's purpose and usage. <p>
<li> The parameters supplied by the DPMI client when it makes the
function call. <p>
<li> The results returned for the function by the DPMI host. <p>
<li> Programmer's notes giving more detailed information about the
function and/or describing special uses of the function. <p>
</ul>
<hr>
<img src="/icons/menu.sm.gif" alt="*">
<a href="ch5.a.html">DPMI Functions by Name</a><br>
<img src="/icons/menu.sm.gif" alt="*">
<a href="ch5.n.html">DPMI Functions by Number</a><br>
<img src="/icons/menu.sm.gif" alt="*">
<a href="ch5.g.html">DPMI Functions by Functional Group</a><br>

View File

@@ -0,0 +1,100 @@
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f1680.html"><tt>2f 1680</tt> - Release Current Virtual Machine's Time Slice</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1686.html"><tt>2f 1686</tt> - Get CPU Mode</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/2f1687.html"><tt>2f 1687</tt> - Obtain Real-to-Protected Mode Switch Entry Point</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/2f168a.html"><tt>2f 168a</tt> - Get Vendor-Specific API Entry Point</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310000.html"><tt>31 0000</tt> - Allocate LDT Descriptors</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310001.html"><tt>31 0001</tt> - Free LDT Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310002.html"><tt>31 0002</tt> - Segment to Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310003.html"><tt>31 0003</tt> - Get Selector Increment Value</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310004.html"><tt>31 0004</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310005.html"><tt>31 0005</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310006.html"><tt>31 0006</tt> - Get Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310007.html"><tt>31 0007</tt> - Set Segment Base Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310008.html"><tt>31 0008</tt> - Set Segment Limit</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310009.html"><tt>31 0009</tt> - Set Descriptor Access Rights</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000a.html"><tt>31 000a</tt> - Create Alias Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000b.html"><tt>31 000b</tt> - Get Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000c.html"><tt>31 000c</tt> - Set Descriptor</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/31000d.html"><tt>31 000d</tt> - Allocate Specific LDT Descriptor</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000e.html"><tt>31 000e</tt> - Get Multiple Descriptors</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31000f.html"><tt>31 000f</tt> - Set Multiple Descriptors</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310100.html"><tt>31 0100</tt> - Allocate DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310101.html"><tt>31 0101</tt> - Free DOS Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310102.html"><tt>31 0102</tt> - Resize DOS Memory Block</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310200.html"><tt>31 0200</tt> - Get Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310201.html"><tt>31 0201</tt> - Set Real Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310202.html"><tt>31 0202</tt> - Get Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310203.html"><tt>31 0203</tt> - Set Processor Exception Handler Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310204.html"><tt>31 0204</tt> - Get Protected Mode Interrupt Vector</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310205.html"><tt>31 0205</tt> - Set Protected Mode Interrupt Vector</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310210.html"><tt>31 0210</tt> - Get Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310211.html"><tt>31 0211</tt> - Get Extended Processor Exception Handler Vector (Real Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310212.html"><tt>31 0212</tt> - Set Extended Processor Exception Handler Vector (Protected Mode)</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310213.html"><tt>31 0213</tt> - Set Extended Processor Exception Handler Vector (Real Mode)</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310300.html"><tt>31 0300</tt> - Simulate Real Mode Interrupt</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310301.html"><tt>31 0301</tt> - Call Real Mode Procedure With Far Return Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310302.html"><tt>31 0302</tt> - Call Real Mode Procedure With IRET Frame</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310303.html"><tt>31 0303</tt> - Allocate Real Mode Callback Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310304.html"><tt>31 0304</tt> - Free Real Mode Callback Address</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310305.html"><tt>31 0305</tt> - Get State Save/Restore Addresses</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310306.html"><tt>31 0306</tt> - Get Raw Mode Switch Addresses</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310400.html"><tt>31 0400</tt> - Get Version</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310401.html"><tt>31 0401</tt> - Get DPMI Capabilities</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310500.html"><tt>31 0500</tt> - Get Free Memory Information</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310501.html"><tt>31 0501</tt> - Allocate Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310502.html"><tt>31 0502</tt> - Free Memory Block</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310503.html"><tt>31 0503</tt> - Resize Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310504.html"><tt>31 0504</tt> - Allocate Linear Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310505.html"><tt>31 0505</tt> - Resize Linear Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310506.html"><tt>31 0506</tt> - Get Page Attributes</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310507.html"><tt>31 0507</tt> - Set Page Attributes</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310508.html"><tt>31 0508</tt> - Map Device in Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310509.html"><tt>31 0509</tt> - Map Conventional Memory in Memory Block</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050a.html"><tt>31 050a</tt> - Get Memory Block Size and Base</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/31050b.html"><tt>31 050b</tt> - Get Memory Information</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310600.html"><tt>31 0600</tt> - Lock Linear Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310601.html"><tt>31 0601</tt> - Unlock Linear Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310602.html"><tt>31 0602</tt> - Mark Real Mode Region as Pageable</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310603.html"><tt>31 0603</tt> - Relock Real Mode Region</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310604.html"><tt>31 0604</tt> - Get Page Size</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310700.html"><tt>31 0700</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310701.html"><tt>31 0701</tt> - Reserved</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310702.html"><tt>31 0702</tt> - Mark Page as Demand Paging Candidate</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310703.html"><tt>31 0703</tt> - Discard Page Contents</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310800.html"><tt>31 0800</tt> - Physical Address Mapping</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310801.html"><tt>31 0801</tt> - Free Physical Address Mapping</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310900.html"><tt>31 0900</tt> - Get and Disable Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310901.html"><tt>31 0901</tt> - Get and Enable Virtual Interrupt State</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310902.html"><tt>31 0902</tt> - Get Virtual Interrupt State</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310a00.html"><tt>31 0a00</tt> - Get Vendor-Specific API Entry Point</a><p>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b00.html"><tt>31 0b00</tt> - Set Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b01.html"><tt>31 0b01</tt> - Clear Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b02.html"><tt>31 0b02</tt> - Get State of Debug Watchpoint</a><br>
<img src="0.9.gif" alt="[0.9]"> <a href="api/310b03.html"><tt>31 0b03</tt> - Reset Debug Watchpoint</a><p>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c00.html"><tt>31 0c00</tt> - Install Resident Service Provider Callback</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310c01.html"><tt>31 0c01</tt> - Terminate and Stay Resident</a><p>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d00.html"><tt>31 0d00</tt> - Allocate Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d01.html"><tt>31 0d01</tt> - Free Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d02.html"><tt>31 0d02</tt> - Serialize on Shared Memory</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310d03.html"><tt>31 0d03</tt> - Free Serialization on Shared Memory</a><p>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e00.html"><tt>31 0e00</tt> - Get Coprocessor Status</a><br>
<img src="1.0.gif" alt="[1.0]"> <a href="api/310e01.html"><tt>31 0e01</tt> - Set Coprocessor Emulation</a><p>

View File

@@ -0,0 +1,79 @@
The following table shows the DPMI client's restrictions on usage of
previously allocated descriptors as input parameters to DPMI
functions. The columns represent the ways the DPMI host allocates
descriptors for its clients. (The first two columns represent LDT
descriptor management functions which allocate descriptors, the third
column represents DOS memory functions, and the last column represents
"other" descriptors, i.e., unallocated descriptors or descriptors used
by the DPMI host for internal purposes.) Each row represents a set of
functions where a client passes those previously allocated
descriptor(s) to the host as input parameters. A `N' indicates that
an "Invalid Selector" error will be generated if the given descriptor
is used in the specified function.<p>
Note that a `Y' for a given entry does not indicate that the function
will succeed, only that it will not generate an "Invalid Selector"
error. Similarly, an `N' does not necessarily indicate a descriptor
is invalid for referencing memory, only that it cannot be used with
that particular function. This chart does not address the usage of
descriptors in pointers. <p>
For example, descriptors allocated by the Allocate LDT Descriptor function
may be used in any of the interrogation and modification functions of
LDT Descriptor Management, as well as the functions which set
exception handlers and interrupt vectors. They may not be passed to
Allocate Specific LDT Descriptor or the DOS Memory Block Functions.<p>
<table border=1 cellspacing=0 cellpadding=4>
<tr> <td>&nbsp;</td> <th colspan=4>Descriptor Allocators</th></tr>
<tr> <th>Functions referring to allocated descriptors</th>
<td>Allocate LDT Descriptor, Allocate Specfic LDT Descriptor, Create Alias descriptr, Initial CS, DS, SS</td>
<td>Segment to Descriptor, PSP, Environment Pointer, Callback DS, Locked Stack SS</td>
<td>Allocate/Resize DOS Memory Block</td>
<td> GDT-based Descriptor, System Descriptor, Unallocated Descriptor</td></tr>
<tr><td>Interrogation Functions: Get Segment Base Address, Get Descriptor, Get Multiple Descriptor, Create Segment Alias</td>
<td align=center>Y</td> <td align=center>Y</td> <td align=center>Y</td> <td align=center>N</td></tr>
<tr><td> Modification Functions: Set Segment Base Address, Set Segment Limit, Set Descriptor Access Rights, Set Descriptor, Set Multiple Descriptors, Free LDT Descriptor</td>
<td align=center>Y</td> <td align=center>N</td> <td align=center>N</td> <td align=center>N</td></tr>
<tr><td> Allocate Specific LDT Descriptor</td>
<td align=center>N</td> <td align=center>N</td> <td align=center>N</td> <td align=center>Y(1)</td></tr>
<tr><td>Free/Resize DOS Memory Block</td>
<td align=center>N</td> <td align=center>N</td> <td align=center>Y</td> <td align=center>N</td></tr>
<tr><td>Set Exception Handler/Interrupt Vector</td>
<td align=center>Y</td> <td align=center>Y(3)</td> <td align=center>Y</td> <td align=center>Y(2)</td></tr>
</table><p>
Notes:
<ol>
<li> Unallocated descriptors within the range of the LDT only.
<li> GDT-Based segment descriptors only.
<li> Although this call will succeed, a fault will result if the
exception or interrupt occurs, since the segment can never be made
executable.
</ul>