home *** CD-ROM | disk | FTP | other *** search
/ Computer Installation Guide - Dragon Clan Series / CD2.iso / DOSTOOLS / PMODEW / PMODEW.DOC < prev    next >
Encoding:
Text File  |  1996-12-31  |  74.2 KB  |  2,168 lines

  1. ------------------------------------------------------------------------------
  2. ---------------------- PMODE For Watcom C/C++ - v1.33 ------------------------
  3. ------------------------------------------------------------------------------
  4.  
  5.   This is the documentation for PMODE for Watcom C/C++ - v1.33, henceforth
  6. referred to as PMODE/W. PMODE/W is Copyright (c) 1994-1997, Charles Scheffold
  7. and Thomas Pytel. All rights reserved.
  8.  
  9. Contents:
  10. ---------
  11.  
  12. 1 - Overview
  13.     1.0  - Legal disclaimer
  14.     1.1  - Description
  15.     1.2  - Usage
  16.     1.3  - Performance and compatibility
  17.     1.4  - PMODE/W protected mode
  18.     1.5  - PMODE/W execution
  19.     1.6  - Terms for non-commercial use
  20.     1.7  - Licensing PMODE/W for commercial use
  21.     1.8  - Contact information
  22.  
  23. 2 - Supported DPMI INT 31h functions
  24.     2.0  - Function 0000h - Allocate Descriptors
  25.     2.1  - Function 0001h - Free Descriptor
  26.     2.2  - Function 0002h - Segment to Descriptor
  27.     2.3  - Function 0003h - Get Selector Increment Value
  28.     2.4  - Function 0006h - Get Segment Base Address
  29.     2.5  - Function 0007h - Set Segment Base Address
  30.     2.6  - Function 0008h - Set Segment Limit
  31.     2.7  - Function 0009h - Set Descriptor Access Rights
  32.     2.8  - Function 000Ah - Create Alias Descriptor
  33.     2.9  - Function 000Bh - Get Descriptor
  34.     2.10 - Function 000Ch - Set Descriptor
  35.     2.11 - Function 0100h - Allocate DOS Memory Block
  36.     2.12 - Function 0101h - Free DOS Memory Block
  37.     2.13 - Function 0102h - Resize DOS Memory Block
  38.     2.14 - Function 0200h - Get Real Mode Interrupt Vector
  39.     2.15 - Function 0201h - Set Real Mode Interrupt Vector
  40.     2.16 - Function 0202h - Get Processor Exception Handler Vector
  41.     2.17 - Function 0203h - Set Processor Exception Handler Vector
  42.     2.18 - Function 0204h - Get Protected Mode Interrupt Vector
  43.     2.19 - Function 0205h - Set Protected Mode Interrupt Vector
  44.     2.20 - Function 0300h - Simulate Real Mode Interrupt
  45.     2.21 - Function 0301h - Call Real Mode Procedure With Far Return Frame
  46.     2.22 - Function 0302h - Call Real Mode Procedure With IRET Frame
  47.     2.23 - Function 0303h - Allocate Real Mode Callback Address
  48.     2.24 - Function 0304h - Free Real Mode Callback Address
  49.     2.25 - Function 0305h - Get State Save/Restore Addresses
  50.     2.26 - Function 0306h - Get Raw Mode Switch Addresses
  51.     2.27 - Function 0400h - Get Version
  52.     2.28 - Function 0500h - Get Free Memory Information
  53.     2.29 - Function 0501h - Allocate Memory Block
  54.     2.30 - Function 0502h - Free Memory Block
  55.     2.31 - Function 0503h - Resize Memory Block
  56.     2.32 - Function 0800h - Physical Address Mapping
  57.     2.33 - Function 0801h - Free Physical Address Mapping
  58.     2.34 - Function 0900h - Get and Disable Virtual Interrupt State
  59.     2.35 - Function 0901h - Get and Enable Virtual Interrupt State
  60.     2.36 - Function 0902h - Get Virtual Interrupt State
  61.     2.37 - Function EEFFh - Get DOS Extender Information
  62.  
  63. 3 - Supported DOS extended INT 21h functions
  64.     3.0  - Function 09h - Write String to Standard Output
  65.     3.1  - Function 1Ah - Set Disk Transfer Area
  66.     3.2  - Function 1Bh - Get Allocation Information for Default Drive
  67.     3.3  - Function 1Ch - Get Allocation Information for Specific Drive
  68.     3.4  - Function 1Fh - Get Drive Parameter Block for Default Drive
  69.     3.5  - Function 25h - Set Interrupt Vector
  70.     3.6  - Function 2Fh - Get Disk Transfer Area
  71.     3.7  - Function 32h - Get Drive Parameter Block for Specific Drive
  72.     3.8  - Function 34h - Get Address of InDOS Flag
  73.     3.9  - Function 35h - Get Interrupt Vector
  74.     3.10 - Function 39h - Create Subdirectory
  75.     3.11 - Function 3Ah - Remove Subdirectory
  76.     3.12 - Function 3Bh - Set Directory
  77.     3.13 - Function 3Ch - Create File
  78.     3.14 - Function 3Dh - Open File
  79.     3.15 - Function 3Fh - Read From File
  80.     3.16 - Function 40h - Write to File
  81.     3.17 - Function 41h - Delete File
  82.     3.18 - Function 43h - Get/Set File Attributes
  83.     3.19 - Function 47h - Get Directory Path
  84.     3.20 - Function 48h - Allocate Memory Block
  85.     3.21 - Function 49h - Free Memory Block
  86.     3.22 - Function 4Ah - Resize Memory Block
  87.     3.23 - Function 4Bh - Sub-Function 00h - Load and Execute Program
  88.     3.24 - Function 4Eh - Search for First Filename Match
  89.     3.25 - Function 4Fh - Search for Next Filename Match
  90.     3.26 - Function 56h - Rename File
  91.     3.27 - Function 62h - Get PSP Address
  92.  
  93. 4 - Supported mouse extended INT 33h functions
  94.     4.0  - Function 0009h - Define Graphics Cursor
  95.     4.1  - Function 000Ch - Define Interrupt Subroutine Parameters
  96.     4.2  - Function 0016h - Save Driver State
  97.     4.3  - Function 0017h - Restore Driver State
  98.  
  99. ------------------------------------------------------------------------------
  100. ------------------------------ 1 - Overview ----------------------------------
  101. ------------------------------------------------------------------------------
  102.  
  103.   This section will give you all the information you will need to plug PMODE/W
  104. right into your Watcom C/C++ protected mode programs. All of the other things
  105. you need to be aware of about using PMODE/W commercially and non-commercially
  106. are also in this section. Specific information on INT 31h and INT 21h DOS
  107. extended services supported by PMODE/W is in the following sections. Please
  108. note that we have tested this extender with Watcom C/C++ versions 9.5, 10.0,
  109. 10.5, and 10.6.
  110.  
  111. 1.0 - Legal disclaimer:
  112. -----------------------
  113.  
  114.   We exclude any and all implied warranties, including warranties of
  115. merchantability and fitness for a particular purpose. We make no warranty or
  116. representation, either express or implied, with respect to PMODE/W, its
  117. quality, performance, merchantability, or fitness for a particular purpose.
  118. We shall have no liability for special, incidental, or consequential damages
  119. arising out of or resulting from the use, misuse, or modification of PMODE/W.
  120.  
  121.   All trademarks used in this documentation are property of their respective
  122. owners.
  123.  
  124. 1.1 - Description:
  125. ------------------
  126.  
  127.   PMODE/W is a DOS extender for the Watcom C/C++ package. It allows DOS
  128. programs to run in full 32 bit protected mode, with access to all memory
  129. available in the system. PMODE/W basically extends the DOS environment to
  130. protected mode and provides a simple interface to the real mode DOS system
  131. services for your code. PMODE/W takes care of all aspects of running the
  132. system in protected mode and maintaining compatibility with the underlying
  133. real mode software. PMODE/W deals with low level necessities such as
  134. descriptor tables, memory management, IRQ and interrupt redirection,
  135. real/protected mode translation functions, exception handling, and other
  136. miscellaneous aspects of running in protected mode. Your code does not need to
  137. deal with specific aspects of different systems, such as XMS/EMS/VCPI/DPMI
  138. availability. PMODE/W will run on top of almost any system and provide common
  139. protected mode services to your program through the DPMI interface
  140. specification, as well as most standard DOS functions extended for protected
  141. mode use.
  142.  
  143.   PMODE/W replaces DOS/4GW extender in the Watcom C/C++ package. Whereas
  144. DOS/4GW requires a stub and an large external extender, PMODE/W is the stub
  145. and extender in one. The generated executable contains the PMODE/W extender
  146. within it as the stub. When run, PMODE/W will take care of setting up the
  147. system and executing the protected mode portion of the program. PMODE/W has
  148. the added advantage of allowing you to compress you protected mode programs.
  149. PMODE/W is also completely interchangeable with DOS/4GW. You may plug PMODE/W
  150. into almost any Watcom C/C++ programs without worry. So long as the program
  151. does not use any DOS/4GW specific functions, the code will work fine. This
  152. allows you to switch directly back to DOS/4GW if for any reason you are not
  153. satisfied with PMODE/W. This also allows you to debug PMODE/W programs unsing
  154. the Watcom debugger, as any uncompressed PMODE/W executable can be run with
  155. DOS/4GW simply by executing it with DOS4GW.EXE.
  156.  
  157.   Several years have gone into the development of PMODE/W. It is now a fairly
  158. mature DOS extender, and has gone through its fair share of bugs and
  159. incompatibilities. It is at this point, a very stable protected mode system.
  160. Great pains have gone into the optimization and testing of PMODE/W. Our major
  161. goals have been speed, size, and stability. We now feel that we have achieved
  162. a good deal of those things. But don't take our word for it, try it yourself,
  163. as you can do that very easily before you actually decide to buy PMODE/W. Just
  164. plug PMODE/W into any popular program out there which uses DOS/4GW.
  165.  
  166.   To sum it up, if you are looking for a good solid, stable, and fast
  167. extender, PMODE/W may be just what you need.
  168.  
  169. Here are the advantages of PMODE/W:
  170.  
  171. ) No external extender required (everything needed to execute is in the EXE).
  172. ) Small size (less than 12k for the entire extender program).
  173. ) Compression of protected mode executables.
  174. ) Low extended memory overhead.
  175. ) Does not require ANY extended memory to load OR execute.
  176. ) Fast execution.
  177. ) Free for non-commercial use.
  178.  
  179. 1.2 - Usage:
  180. ------------
  181.  
  182.   The following main files should be present in your PMODE/W archive:
  183.  
  184. ) FILE_ID.DIZ   - BBS description file.
  185. ) UPDATES.DOC   - Information about updates/bug fixes.
  186. ) PMODEW.DOC    - The documentation you are now reading.
  187. ) PMODEW.EXE    - The actual PMODE/W DOS extender.
  188. ) PMODEW.FAQ    - Frequently asked questions.
  189. ) PMODEW.LNK    - Example linker initialization file for PMODE/W.
  190. ) PMWSETUP.EXE  - PMODE/W parameter setup utility.
  191. ) PMWBIND.EXE   - PMODE/W bind utility.
  192. ) PMWLITE.EXE   - PMODE/W protected mode executable compression utility.
  193. ) PMWVER.COM    - PMODE/W version check utility.
  194. ) UTILS.DOC     - Documentation on PMWSETUP, PMWBIND, PMWLITE, and PMWVER.
  195. ) EXAMPLES.ZIP  - Example files.
  196.  
  197.   You will probably want to add a new system, PMODE/W, to your WLSYSTEM.LNK
  198. file. All you need to do in this case is add the contents of PMODEW.LNK to
  199. your WLSYSTEM.LNK file, this will add the system 'pmodew' to your Watcom C/C++
  200. setup. You may also just compile to a 'dos4g' system but replace the stub with
  201. PMODEW.EXE.
  202.  
  203. 1.3 - Performance and compatibility:
  204. ------------------------------------
  205.  
  206.   Our major concerns in developing PMODE/W were speed, size, and stability.
  207. PMODE/W itself was written entirely in assembly. When running under PMODE/W,
  208. your code will be running at a privilege level of zero, the highest and
  209. fastest. PMODE/W does not virtualize what it does not need to, and does not
  210. invoke any protected mode mechanism that is slow. For example, if the system
  211. is running clean or under XMS, PMODE/W does not turn on paging. Under a memory
  212. manager which provides both VCPI and DPMI services, PMODE/W will opt for VCPI
  213. protected mode which is significantly faster than DPMI. When PMODE/W makes
  214. calls to real mode, it switches the system into actual real mode rather than
  215. the slower V86 mode (when it can, under VCPI this is not possible, control
  216. must be passed back to the VCPI server). In terms of speed, when your code is
  217. running under PMODE/W, it is running as fast as the system will allow.
  218.  
  219.   In terms of size on disk, we need say no more than for you to look at the
  220. size of the PMODE/W executable and compare it to other extenders. In terms of
  221. memory size, you may do tests yourself to confirm that PMODE/W does indeed
  222. suck up a lot less memory at run-time than the competition. In fact, PMODE/W
  223. will run even if there is absolutely no extended memory in the system
  224. (assuming of course there is enough low memory for the program). To be fair,
  225. we must say we squished the PMODE/W executable with our own compression
  226. program written expressly for the purpose, this though demonstrates the extent
  227. we took most of our optimizations to.
  228.  
  229.   As for compatibility, PMODE/W is almost fully compatible with DOS/4GW as far
  230. as Watcom C/C++ is concerned. PMODE/W extends only those DOS functions
  231. required by the Watcom C/C++ libraries, though this is a good deal of them.
  232. The exception is BIOS INT 13h functions, which PMODE/W does not extend.
  233. PMODE/W also provides a subset of DPMI 0.9 INT 31h functions in protected
  234. mode. We do not emulate DOS/4GW though, as none of its API functions are
  235. duplicated by PMODE/W. PMODE/W will run under a clean system, XMS, VCPI, or
  236. DPMI. Though you should be aware that under a DPMI system, PMODE/W will not be
  237. providing the DPMI functions, but rather the actual DPMI host in the system
  238. will. You should also be aware that PMODE/W will leave the A20 line enabled
  239. when calling real mode. Disabling the A20 for real mode is not really
  240. necessary, it is a big slowdown during mode switches to have to enable/disable
  241. the A20, so PMODE/W avoids it.
  242.  
  243. 1.4 - PMODE/W protected mode:
  244. -----------------------------
  245.  
  246.   When run under a clean system, XMS, or VCPI, PMODE/W has control of
  247. protected mode. In this case, it can set up the system to run as fast as
  248. possible under the various conditions. Under DPMI, the DPMI host of the system
  249. will have full protected mode control and PMODE/W will install its DOS
  250. extensions on top of that. If the system provides both VCPI and DPMI services,
  251. PMODE/W will use the VCPI services for faster execution, unless instructed not
  252. to by the setup program. When PMODE/W does have protected mode control under
  253. clean/XMS/VCPI, it runs all code at a privilege level of zero. In addition,
  254. under a clean or XMS system, paging will not be enabled. This is only a minor
  255. speed increase, but there is no real need to manage paging.
  256.  
  257.   PMODE/W provides a subset of DPMI 0.9 function calls and general
  258. functionality when a DPMI host is not present. PMODE/W will pass any software
  259. interrupts from protected mode to their default real mode handlers, provided
  260. no protected mode handlers have been installed for them, just as DPMI will.
  261. The general registers will be passed on to the real mode handler, but the
  262. segment registers can not be as they have different meanings in real mode and
  263. protected mode. The flags will be passed back from the real mode handler. This
  264. provides a simple interface to all real mode interrupt routines which do not
  265. take parameters in the segment registers, for example, INT 16h function 00h.
  266.  
  267.   Any IRQs that occur in protected mode and have not been hooked by a
  268. protected mode handler will be sent on to their real mode handlers. If an IRQ
  269. occurs in real mode, and a protected mode handler has hooked that IRQ, it will
  270. be sent to the protected mode handler first. The protected mode handler may
  271. chain to the real mode handler for that IRQ by calling the previous protected
  272. mode handler for that IRQ. This behavior is in accordance with the DPMI
  273. standard. If you hook a protected mode IRQ (INT 31h function 0205h), then hook
  274. the same IRQ in real mode (INT 31h function 0201h), the protected mode handler
  275. will be called if the IRQ occurs in protected mode, and the real mode handler
  276. will handle the IRQs if they occur in real mode. Setting up two handlers like
  277. this assures minimal latency. This means a handler will get control when the
  278. IRQ occurs as soon as physically possible. PMODE/W does have to intervene in
  279. the IRQ process, however, when the low 8 IRQs are mapped to INTs 08h-15h to
  280. differentiate IRQs from CPU exceptions.
  281.  
  282.   In accordance with DPMI specifications, PMODE/W will pass up software
  283. interrupts 1ch (BIOS timer tick), 23h (DOS CTRL+C), and 24h (DOS critical
  284. error) from real mode to protected mode. This means that those interrupts can
  285. be hooked directly in protected mode without having to set up a callback
  286. mechanism yourself. PMODE/W will also pass interrupt 1bh (BIOS CTRL+BREAK)
  287. from real mode up to protected mode. This is not a DPMI requirement, but it is
  288. necessary for the sake of compatibility with DOS/4GW.
  289.  
  290.   Another departure by PMODE/W from official DPMI specifications is in
  291. extended memory allocation. DPMI documentation states that the block of
  292. extended memory allocated through function 0501h is guaranteed at least
  293. paragraph alignment. The PMODE/W DPMI implementation will enforce only DWORD
  294. alignment.
  295.  
  296. 1.5 - PMODE/W execution:
  297. ------------------------
  298.  
  299.   When a PMODE/W executable is run, PMODE/W will attempt to switch the system
  300. into protected mode and load the protected mode portion of the same
  301. executable. If there is some error, not enough memory, or a system
  302. incompatibility, PMODE/W will exit with an error message. If loading was
  303. successful, PMODE/W will pass execution control on to the program. PMODE/W
  304. will load any 16 bit code and data into low memory, but 32 bit code and data
  305. may be loaded into low or extended memory depending on avaliability.
  306.  
  307.   There are a number of modifiable parameters in the PMODE/W extender
  308. executable that affect protected mode execution. For the most part, these
  309. parameters deal with memory. PMODE/W allocates one large block of extended
  310. memory for its pool from which it provides memory to its client program. There
  311. is a maximum value for the extended memory to be allocated. By default, the
  312. maximum is all of the extended memory in the system. The maximum value
  313. reflects the size of the block you want PMODE/W to take from the system, not
  314. necessarily the size of the largest block available to the default C/C++
  315. malloc functions. You may set the maximum to zero to indicate you do not want
  316. PMODE/W to allocate ANY extended memory. The amount of memory that you allow
  317. PMODE/W to allocate from the system determines how much extended memory will
  318. be left to other if you shell out of your PMODE/W program.
  319.  
  320.   Another variable specifies the amount of low memory for PMODE/W to TRY to
  321. keep free. If PMODE/W can, it will accommodate this value by loading 32 bit
  322. code and data into extended memory. If there is not enough extended memory
  323. available for this, 32 bit code and data will be loaded into low memory
  324. anyway. If PMODE/W can not keep this much low memory free, it will not exit
  325. with an error message. Setting this parameter to a high value will, in effect,
  326. duplicate the DOS/4GW behavior of loading all 32 bit code and data into
  327. extended memory. If you do not necessarily need any extra low memory free
  328. during the execution of your program, you may set this value to zero.
  329.  
  330.   There is a group of parameters that specify the number and size of nested
  331. mode switch stacks. Whenever you make a call to real mode, or a callback or
  332. IRQ is passed from real mode to its routine in protected mode, a nested stack
  333. is used. These parameters have meaning only if the program is not run under a
  334. DPMI system. If a DPMI host is in place when the program is run, it provides
  335. its own nested stacks for mode switches. The number of nested stacks directly
  336. affects the number of nested mode switches your program can make using the
  337. various mode switch methods. The size of both the real mode and protected mode
  338. nested stacks can also be specified. By default, these values are high enough
  339. for normal operation. However, if you intend to use a lot of stack variables
  340. in a protected mode IRQ handler, or a lot of recursive calls, you may need to
  341. increase the size of the protected mode nested stacks. The more nested stacks
  342. you specify, and the larger they are, the more low memory is needed by PMODE/W
  343. during execution.
  344.  
  345.   Another group of variables that has meaning only under clean/XMS/VCPI
  346. execution specify the number of selectors and DPMI callbacks you want PMODE/W
  347. to make available. The more selectors and callbacks you ask for, the more low
  348. memory is used by PMODE/W, though the amount of low memory used for each is
  349. quite low so that large numbers of each can be specified. There will usually
  350. be a little less than the number of selectors and callbacks you request
  351. available to your program due to the protected mode system and C/C++ code
  352. using some of them. For this reason you should request 20h-40h more selectors
  353. and 2-4 more callbacks than you will need in your program.
  354.  
  355.   There are four other miscellaneous parameters that can be set. There is a
  356. maximum number of page tables to use under a VCPI system. Each page table
  357. allocated requires 4k of low memory to be used by PMODE/W and maps 4M of
  358. memory. This directly affects the maximum amount of extended memory available
  359. under a VCPI system. This parameter is only the maximum number of page tables
  360. to allow. At run-time, only as many page tables will be allocated as are
  361. needed. Under a clean/XMS system, no page tables are required, so this
  362. parameter has no meaning. But under VCPI, you may want to restrict the number
  363. of page tables to save low memory if you do not need more than a certain
  364. amount of extended memory. This puts a maximum ceiling on extended memory
  365. under VCPI which may be lower than the maximum actually specified in the other
  366. variable. The second parameter specifies the order of DPMI and VCPI detection.
  367. By default, VCPI will be checked before DPMI, but you may set DPMI to be
  368. checked before VCPI so that under a system which supports both VCPI and DPMI,
  369. DPMI will be used. The third variable specifies how many pages to reserve for
  370. physical address mapping calls (INT 31h function 0800h) under VCPI. Under XMS
  371. or a clean system, paging is not enabled, and PMODE/W does not need pages for
  372. physical address mapping. Each page will allow you to map up to 4M of address
  373. space and takes up 4k of extended memory. So for example, if you intend to map
  374. a 2M frame buffer of a video card, you will need only one page. You may set
  375. this parameter to zero if you do not intend to map any physical addresses.
  376. The fourth parameter specifies whether PMODE/W displays its banner at startup.
  377. This may be desirable to indicate that the program is indeed running, and has
  378. not crashed, as allocating memory from certain VCPI servers can be a slow
  379. process.
  380.  
  381. 1.6 - Terms for non-commercial use:
  382. -----------------------------------
  383.  
  384.   You are hereby permitted to use this DOS extender in any and all
  385. non-commercial and non-shareware software programs free of any financial
  386. obligation to us, provided that if the program is distributed, it is
  387. distributed to the public, free of any charge for the program itself. There is
  388. no restriction on what kind of reselling of the above mentioned program is
  389. done (shareware houses, CD-ROMs, etc...), as long as the program is available
  390. to the public with no financial obligation to the author(s). The only thing we
  391. ask in this case is that you credit us in your production for the DOS
  392. extender. It would also be nice, but not necessary, if you dropped us a note
  393. informing us of your use of PMODE/W in some production.
  394.  
  395. 1.7 - Licensing PMODE/W for commercial use:
  396. -------------------------------------------
  397.  
  398.   If you wish to use PMODE/W in a commercial, shareware, or any program which
  399. is to be sold or has attached to it an obligation to buy something, you MUST
  400. purchase a commercial distribution license. This license will allow royalty
  401. free distribution of any and all applications using PMODE/W created and owned
  402. by the holder of the license. A separate license is NOT required for each
  403. application in which PMODE/W is used. This license is non-transferrable (you
  404. cannot sell, give, loan, or otherwise transfer it to someone else).
  405.  
  406.   The license fee is $500 U.S. for commercial or shareware programs. Once
  407. purchased, this license is valid for any and all programs created and owned by
  408. the person or company purchasing the license until the end of time. The
  409. license is a one time fee, with no restrictions on how many programs PMODE/W
  410. can be used in. There is a special discount available to students on PMODE/W.
  411. The license can be purchased by university students for $100 U.S.
  412.  
  413. 1.8 - Contact information:
  414. --------------------------
  415.  
  416.   If you are interested in licensing PMODE/W for a commercial or shareware
  417. program, you may contact us in the following manner:
  418.  
  419. ) Send mail to:
  420.  
  421.     Ryan Cramer
  422.     8300 Riding Ridge Place
  423.     McLean, VA  22102
  424.     USA
  425.  
  426. ) Send E-mail to:
  427.  
  428.     rcramer1@osf1.gmu.edu
  429.  
  430. ) On the World Wide Web:
  431.  
  432.     http://www.di.net/pmw (Official page)
  433.     http://www.dorsai.org/~daredevi/pmw (Latest version download only)
  434.  
  435. ) Drop a note to the sysop on the Data Connection BBS at:
  436.  
  437.     +1-703-506-8598
  438.     +1-703-847-0861
  439.  
  440. ) For technical questions, drop a note to the following address:
  441.  
  442.     daredevi@dorsai.org
  443.  
  444. ------------------------------------------------------------------------------
  445. ------------------- 2 - Supported DPMI INT 31h functions ---------------------
  446. ------------------------------------------------------------------------------
  447.  
  448.   PMODE/W duplicates a subset of DPMI protected mode functions. These
  449. functions are available ONLY in protected through INT 31h. They provide
  450. descriptor services, extended memory services, interrupt services, translation
  451. services, and some other miscellaneous things. A function is called by setting
  452. AX to the function code, setting any other registers for the function, and
  453. executing INT 31h. Upon return, the carry flag will be clear if the function
  454. was successful. If the carry flag is set, the function failed. All other
  455. registers are preserved unless otherwise specified. In addition to the
  456. functions listed here, functions 0600h, 0601h, 0702h, and 0703h will return
  457. with the carry flag clear to stay compatible with code that uses those
  458. particular DPMI functions.
  459.  
  460. 2.0 - Function 0000h - Allocate Descriptors:
  461. --------------------------------------------
  462.  
  463.   Allocates one or more descriptors in the client's descriptor table. The
  464. descriptor(s) allocated must be initialized by the application with other
  465. function calls.
  466.  
  467. In:
  468.   AX     = 0000h
  469.   CX     = number of descriptors to allocate
  470.  
  471. Out:
  472.   if successful:
  473.     carry flag clear
  474.     AX       = base selector
  475.  
  476.   if failed:
  477.     carry flag set
  478.  
  479. Notes:
  480. ) If more that one descriptor was requested, the function returns a base
  481.   selector referencing the first of a contiguous array of descriptors. The
  482.   selector values for subsequent descriptors in the array can be calculated
  483.   by adding the value returned by INT 31h function 0003h.
  484.  
  485. ) The allocated descriptor(s) will be set to expand-up writeable data, with
  486.   the present bit set and a base and limit of zero. The privilege level of the
  487.   descriptor(s) will match the client's code segment privilege level.
  488.  
  489. 2.1 - Function 0001h - Free Descriptor:
  490. ---------------------------------------
  491.  
  492.   Frees a descriptor.
  493.  
  494. In:
  495.   AX     = 0001h
  496.   BX     = selector for the descriptor to free
  497.  
  498. Out:
  499.   if successful:
  500.     carry flag clear
  501.  
  502.   if failed:
  503.     carry flag set
  504.  
  505. Notes:
  506. ) Each descriptor allocated with INT 31h function 0000h must be freed
  507.   individually with the function. Even if it was previously allocated as part
  508.   of a contiguous array of descriptors.
  509.  
  510. ) Under DPMI 1.0/VCPI/XMS/raw, any segment registers which contain the
  511.   selector being freed are zeroed by this function.
  512.  
  513. 2.2 - Function 0002h - Segment to Descriptor:
  514. ---------------------------------------------
  515.  
  516.   Converts a real mode segment into a protected mode descriptor.
  517.  
  518. In:
  519.   AX     = 0002h
  520.   BX     = real mode segment
  521.  
  522. Out:
  523.   if successful:
  524.     carry flag clear
  525.     AX     = selector
  526.  
  527.   if failed:
  528.     carry flag set
  529.  
  530. Notes:
  531. ) Multiple calls for the same real mode segment return the same selector.
  532.  
  533. ) The returned descriptor should never be modified or freed.
  534.  
  535. 2.3 - Function 0003h - Get Selector Increment Value:
  536. ----------------------------------------------------
  537.  
  538.   The Allocate Descriptors function (0000h) can allocate an array of
  539. contiguous descriptors, but only return a selector for the first descriptor.
  540. The value returned by this function can be used to calculate the selectors for
  541. subsequent descriptors in the array.
  542.  
  543. In:
  544.   AX     = 0003h
  545.  
  546. Out:
  547.   always successful:
  548.     carry flag clear
  549.     AX       = selector increment value
  550.  
  551. Notes:
  552. ) The increment value is always a power of two.
  553.  
  554. 2.4 - Function 0006h - Get Segment Base Address:
  555. ------------------------------------------------
  556.  
  557.   Returns the 32bit linear base address from the descriptor table for the
  558. specified segment.
  559.  
  560. In:
  561.   AX     = 0006h
  562.   BX     = selector
  563.  
  564. Out:
  565.   if successful:
  566.     carry flag clear
  567.     CX:DX  = 32bit linear base address of segment
  568.  
  569.   if failed:
  570.     carry flag set
  571.  
  572. Notes:
  573. ) Client programs must use the LSL instruction to query the limit for a
  574.   descriptor.
  575.  
  576. 2.5 - Function 0007h - Set Segment Base Address:
  577. ------------------------------------------------
  578.  
  579.   Sets the 32bit linear base address field in the descriptor for the specified
  580. segment.
  581.  
  582. In:
  583.   AX     = 0007h
  584.   BX     = selector
  585.   CX:DX  = 32bit linear base address of segment
  586.  
  587. Out:
  588.   if successful:
  589.     carry flag clear
  590.  
  591.   if failed:
  592.     carry flag set
  593.  
  594. Notes:
  595. ) Under DPMI 1.0/VCPI/XMS/raw, any segment register which contains the
  596.   selector specified in register BX will be reloaded. DPMI 0.9 may do this,
  597.   but it is not guaranteed.
  598.  
  599. ) We hope you have enough sense not to try to modify your current CS or SS
  600.   descriptor.
  601.  
  602. 2.6 - Function 0008h - Set Segment Limit:
  603. -----------------------------------------
  604.  
  605.   Sets the limit field in the descriptor for the specified segment.
  606.  
  607. In:
  608.   AX     = 0008h
  609.   BX     = selector
  610.   CX:DX  = 32bit segment limit
  611.  
  612. Out:
  613.   if successful:
  614.     carry flag clear
  615.  
  616.   if failed:
  617.     carry flag set
  618.  
  619. Notes:
  620. ) The value supplied to the function in CX:DX is the byte length of the
  621.   segment-1.
  622.  
  623. ) Segment limits greater than or equal to 1M must be page aligned. That is,
  624.   they must have the low 12 bits set.
  625.  
  626. ) This function has an implicit effect on the "G" bit in the segment's
  627.   descriptor.
  628.  
  629. ) Client programs must use the LSL instruction to query the limit for a
  630.   descriptor.
  631.  
  632. ) Under DPMI 1.0/VCPI/XMS/raw, any segment register which contains the
  633.   selector specified in register BX will be reloaded. DPMI 0.9 may do this,
  634.   but it is not guaranteed.
  635.  
  636. ) We hope you have enough sense not to try to modify your current CS or SS
  637.   descriptor.
  638.  
  639. 2.7 - Function 0009h - Set Descriptor Access Rights:
  640. ----------------------------------------------------
  641.  
  642.   Modifies the access rights field in the descriptor for the specified
  643. segment.
  644.  
  645. In:
  646.   AX     = 0009h
  647.   BX     = selector
  648.   CX     = access rights/type word
  649.  
  650. Out:
  651.   if successful:
  652.     carry flag clear
  653.  
  654.   if failed:
  655.     carry flag set
  656.  
  657. Notes:
  658. ) The access rights/type word passed to the function in CX has the following
  659.   format:
  660.  
  661.     Bit: 15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
  662.        +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  663.        | G |B/D| 0 | ? |       ?       | 1 |  DPL  | 1 |C/D|E/C|W/R| A |
  664.        +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  665.  
  666.     G   - 0=byte granular, 1=page granular
  667.     B/D - 0=default 16bit, 1=default 32bit
  668.     DPL - must be equal to caller's CPL
  669.     C/D - 0=data, 1=code
  670.     E/C - data: 0=expand-up, 1=expand-down
  671.           code: must be 0 (non-conforming)
  672.     W/R - data: 0=read, 1=read/write
  673.           code: must be 1 (readable)
  674.     A   - 0=not accessed, 1=accessed
  675.     0   - must be 0
  676.     1   - must be 1
  677.     ?   - ignored
  678.  
  679. ) Client programs should use the LAR instruction to examine the access rights
  680.   of a descriptor.
  681.  
  682. ) Under DPMI 1.0/VCPI/XMS/raw, any segment register which contains the
  683.   selector specified in register BX will be reloaded. DPMI 0.9 may do this,
  684.   but it is not guaranteed.
  685.  
  686. ) We hope you have enough sense not to try to modify your current CS or SS
  687.   descriptor.
  688.  
  689. 2.8 - Function 000Ah - Create Alias Descriptor:
  690. -----------------------------------------------
  691.  
  692.   Creates a new data descriptor that has the same base and limit as the
  693. specified descriptor.
  694.  
  695. In:
  696.   AX     = 000ah
  697.   BX     = selector
  698.  
  699. Out:
  700.   if successful:
  701.     carry flag clear
  702.     AX       = data selector (alias)
  703.  
  704.   if failed:
  705.     carry flag set
  706.  
  707. Notes:
  708. ) The selector supplied to the function may be either a data descriptor or
  709.   a code descriptor. The alias descriptor created is always an expand-up
  710.   writeable data segment.
  711.  
  712. ) The descriptor alias returned by this function will not track changes to the
  713.   original descriptor.
  714.  
  715. 2.9 - Function 000Bh - Get Descriptor:
  716. --------------------------------------
  717.  
  718.   Copies the descriptor table entry for the specified selector into an 8 byte
  719. buffer.
  720.  
  721. In:
  722.   AX     = 000bh
  723.   BX     = selector
  724.   ES:EDI = selector:offset of 8 byte buffer
  725.  
  726. Out:
  727.   if successful:
  728.     carry flag clear
  729.     buffer pointed to by ES:EDI contains descriptor
  730.  
  731.   if failed:
  732.     carry flag set
  733.  
  734. 2.10 - Function 000Ch - Set Descriptor:
  735. ---------------------------------------
  736.  
  737.   Copies the contents of an 8 byte buffer into the descriptor for the
  738. specified selector.
  739.  
  740. In:
  741.   AX     = 000ch
  742.   BX     = selector
  743.   ES:EDI = selector:offset of 8 byte buffer containing descriptor
  744.  
  745. Out:
  746.   if successful:
  747.     carry flag clear
  748.  
  749.   if failed:
  750.     carry flag set
  751.  
  752. ) The descriptors access rights/type word at offset 5 within the descriptor
  753.   follows the same format and restrictions as the access rights/type parameter
  754.   CX to the Set Descriptor Access Rights function (0009h).
  755.  
  756. ) Under DPMI 1.0/VCPI/XMS/raw, any segment register which contains the
  757.   selector specified in register BX will be reloaded. DPMI 0.9 may do this,
  758.   but it is not guaranteed.
  759.  
  760. ) We hope you have enough sense not to try to modify your current CS or SS
  761.   descriptor or the descriptor of the buffer.
  762.  
  763. 2.11 - Function 0100h - Allocate DOS Memory Block:
  764. --------------------------------------------------
  765.  
  766.   Allocates low memory through DOS function 48h and allocates it a descriptor.
  767.  
  768. In:
  769.   AX     = 0100h
  770.   BX     = paragraphs to allocate
  771.  
  772. Out:
  773.   if successful:
  774.     carry flag clear
  775.     AX       = real mode segment address
  776.     DX       = protected mode selector for memory block
  777.  
  778.   if failed:
  779.     carry flag set
  780.     AX       = DOS error code
  781.     BX       = size of largest available block
  782.  
  783. 2.12 - Function 0101h - Free DOS Memory Block:
  784. ----------------------------------------------
  785.  
  786.   Frees a low memory block previously allocated by function 0100h.
  787.  
  788. In:
  789.   AX     = 0101h
  790.   DX     = protected mode selector for memory block
  791.  
  792. Out:
  793.   if successful:
  794.     carry flag clear
  795.  
  796.   if failed:
  797.     carry flag set
  798.     AX       = DOS error code
  799.  
  800. 2.13 - Function 0102h - Resize DOS Memory Block:
  801. ------------------------------------------------
  802.  
  803.   Resizes a low memory block previously allocated by function 0100h
  804.  
  805. In:
  806.   AX     = 0102h
  807.   BX     = new block size in paragraphs
  808.   DX     = protected mode selector for memory block
  809.  
  810. Out:
  811.   if successful:
  812.     carry flag clear
  813.  
  814.   if failed:
  815.     carry flag set
  816.     AX       = DOS error code
  817.     BX       = size of largest available block
  818.  
  819. 2.14 - Function 0200h - Get Real Mode Interrupt Vector:
  820. -------------------------------------------------------
  821.  
  822.   Returns the real mode segment:offset for the specified interrupt vector.
  823.  
  824. In:
  825.   AX     = 0200h
  826.   BL     = interrupt number
  827.  
  828. Out:
  829.   always successful:
  830.     carry flag clear
  831.     CX:DX  = segment:offset of real mode interrupt handler
  832.  
  833. Notes:
  834. ) The value returned in CX is a real mode segment address, not a protected
  835.   mode selector.
  836.  
  837. 2.15 - Function 0201h - Set Real Mode Interrupt Vector:
  838. -------------------------------------------------------
  839.  
  840.   Sets the real mode segment:offset for the specified interrupt vector.
  841.  
  842. In:
  843.   AX     = 0201h
  844.   BL     = interrupt number
  845.   CX:DX  = segment:offset of real mode interrupt handler
  846.  
  847. Out:
  848.   always successful:
  849.     carry flag clear
  850.  
  851. Notes:
  852. ) The value passed in CX must be a real mode segment address, not a protected
  853.   mode selector. Consequently, the interrupt handler must either reside in
  854.   DOS memory (below the 1M boundary) or the client must allocate a real mode
  855.   callback address.
  856.  
  857. 2.16 - Function 0202h - Get Processor Exception Handler Vector:
  858. ---------------------------------------------------------------
  859.  
  860.   Returns the address of the current protected mode exception handler for the
  861. specified exception number.
  862.  
  863. In:
  864.   AX     = 0202h
  865.   BL     = exception number (00h-1fh)
  866.  
  867. Out:
  868.   if successful:
  869.     carry flag clear
  870.     CX:EDX = selector:offset of exception handler
  871.  
  872.   if failed:
  873.     carry flag set
  874.  
  875. Notes:
  876. ) PMODE/W handles exceptions under clean/XMS/VCPI environments. Under a DPMI
  877.   environment, exception handling is provided by the DPMI host.
  878.  
  879. ) PMODE/W only traps exceptions 0 through 14. The default behavior is to
  880.   terminate execution and do a debug dump. PMODE/W will terminate on
  881.   exceptions 0, 1, 2, 3, 4, 5, and 7, instead of passing them down to the
  882.   real mode handlers as DPMI specifications state.
  883.  
  884. 2.17 - Function 0203h - Set Processor Exception Handler Vector:
  885. ---------------------------------------------------------------
  886.  
  887.   Sets the address of a handler for a CPU exception or fault, allowing a
  888. protected mode application to intercept processor exceptions.
  889.  
  890. In:
  891.   AX     = 0203h
  892.   BL     = exception number (00h-1fh)
  893.   CX:EDX = selector:offset of exception handler
  894.  
  895. Out:
  896.   if successful:
  897.     carry flag clear
  898.  
  899.   if failed:
  900.     carry flag set
  901.  
  902. Notes:
  903. ) PMODE/W handles exceptions under clean/XMS/VCPI environments. Under a DPMI
  904.   environment, exception handling is provided by the DPMI host.
  905.  
  906. ) PMODE/W only traps exceptions 0 through 14. The default behavior is to
  907.   terminate execution and do a debug dump. PMODE/W will terminate on
  908.   exceptions 0, 1, 2, 3, 4, 5, and 7, instead of passing them down to the
  909.   real mode handlers as DPMI specifications state.
  910.  
  911. ) If you wish to hook one of the low 8 interrupts, you must hook it as an
  912.   exception. It will not be called if you hook it with function 0205h.
  913.  
  914. 2.18 - Function 0204h - Get Protected Mode Interrupt Vector:
  915. ------------------------------------------------------------
  916.  
  917.   Returns the address of the current protected mode interrupt handler for the
  918. specified interrupt.
  919.  
  920. In:
  921.   AX     = 0204h
  922.   BL     = interrupt number
  923.  
  924. Out:
  925.   always successful:
  926.     carry flag clear
  927.     CX:EDX = selector:offset of protected mode interrupt handler
  928.  
  929. Notes:
  930. ) The value returned in CX is a valid protected mode selector, not a real mode
  931.   segment address.
  932.  
  933. 2.19 - Function 0205h - Set Protected Mode Interrupt Vector:
  934. ------------------------------------------------------------
  935.  
  936.   Sets the address of the protected mode interrupt handler for the specified
  937. interrupt.
  938.  
  939. In:
  940.   AX     = 0205h
  941.   BL     = interrupt number
  942.   CX:EDX = selector offset of protected mode interrupt handler
  943.  
  944. Out:
  945.   if successful:
  946.     carry flag clear
  947.  
  948.   if failed:
  949.     carry flag set
  950.  
  951. Notes:
  952. ) The value passed in CX must be a valid protected mode selector, not a real
  953.   mode segment address.
  954.  
  955. ) If you wish to hook one of the low 8 interrupts, you must hook it as an
  956.   exception. It will not be called if you hook it with function 0205h.
  957.  
  958. 2.20 - Function 0300h - Simulate Real Mode Interrupt:
  959. -----------------------------------------------------
  960.  
  961.   Simulates an interrupt in real mode. The function transfers control to the
  962. address specified by the real mode interrupt vector. The real mode handler
  963. must return by executing an IRET.
  964.  
  965. In:
  966.   AX     = 0300h
  967.   BL     = interrupt number
  968.   BH     = must be 0
  969.   CX     = number of words to copy from the protected mode stack to the real
  970.            mode stack
  971.   ES:EDI = selector:offset of real mode register data structure in the
  972.            following format:
  973.  
  974.            Offset  Length  Contents
  975.            00h     4       EDI
  976.            04h     4       ESI
  977.            08h     4       EBP
  978.            0ch     4       reserved, ignored
  979.            10h     4       EBX
  980.            14h     4       EDX
  981.            18h     4       ECX
  982.            1ch     4       EAX
  983.            20h     2       CPU status flags
  984.            22h     2       ES
  985.            24h     2       DS
  986.            26h     2       FS
  987.            28h     2       GS
  988.            2ah     2       IP (reserved, ignored)
  989.            2ch     2       CS (reserved, ignored)
  990.            2eh     2       SP
  991.            30h     2       SS
  992.  
  993. Out:
  994.   if successful:
  995.     carry flag clear
  996.     ES:EDI = selector offset of modified real mode register data structure
  997.  
  998.   if failed:
  999.     carry flag set
  1000.  
  1001. Notes:
  1002. ) The CS:IP in the real mode register data structure is ignored by this
  1003.   function. The appropriate interrupt handler will be called based on the
  1004.   value passed in BL.
  1005.  
  1006. ) If the SS:SP fields in the real mode register data structure are zero, a
  1007.   real mode stack will be provided by the host. Otherwise the real mode SS:SP
  1008.   will be set to the specified values before the interrupt handler is called.
  1009.  
  1010. ) The flags specified in the real mode register data structure will be put on
  1011.   the real mode interrupt handler's IRET frame. The interrupt handler will be
  1012.   called with the interrupt and trace flags clear.
  1013.  
  1014. ) Values placed in the segment register positions of the data structure must
  1015.   be valid for real mode. That is, the values must be paragraph addresses, not
  1016.   protected mode selectors.
  1017.  
  1018. ) The target real mode handler must return with the stack in the same state
  1019.   as when it was called. This means that the real mode code may switch stacks
  1020.   while it is running, but must return on the same stack that it was called
  1021.   on and must return with an IRET.
  1022.  
  1023. ) When this function returns, the real mode register data structure will
  1024.   contain the values that were returned by the real mode interrupt handler.
  1025.   The CS:IP and SS:SP values will be unmodified in the data structure.
  1026.  
  1027. ) It is the caller's responsibility to remove any parameters that were pushed
  1028.   on the protected mode stack.
  1029.  
  1030. 2.21 - Function 0301h - Call Real Mode Procedure With Far Return Frame:
  1031. -----------------------------------------------------------------------
  1032.  
  1033.   Simulates a FAR CALL to a real mode procedure. The called procedure must
  1034. return by executing a RETF instruction.
  1035.  
  1036. In:
  1037.   AX     = 0301h
  1038.   BH     = must be 0
  1039.   CX     = number of words to copy from the protected mode stack to the real
  1040.            mode stack
  1041.   ES:EDI = selector:offset of real mode register data structure in the
  1042.            following format:
  1043.  
  1044.            Offset  Length  Contents
  1045.            00h     4       EDI
  1046.            04h     4       ESI
  1047.            08h     4       EBP
  1048.            0ch     4       reserved, ignored
  1049.            10h     4       EBX
  1050.            14h     4       EDX
  1051.            18h     4       ECX
  1052.            1ch     4       EAX
  1053.            20h     2       CPU status flags
  1054.            22h     2       ES
  1055.            24h     2       DS
  1056.            26h     2       FS
  1057.            28h     2       GS
  1058.            2ah     2       IP
  1059.            2ch     2       CS
  1060.            2eh     2       SP
  1061.            30h     2       SS
  1062.  
  1063. Out:
  1064.   if successful:
  1065.     carry flag clear
  1066.     ES:EDI = selector offset of modified real mode register data structure
  1067.  
  1068.   if failed:
  1069.     carry flag set
  1070.  
  1071. Notes:
  1072. ) The CS:IP in the real mode register data structure specifies the address of
  1073.   the real mode procedure to call.
  1074.  
  1075. ) If the SS:SP fields in the real mode register data structure are zero, a
  1076.   real mode stack will be provided by the host. Otherwise the real mode SS:SP
  1077.   will be set to the specified values before the procedure is called.
  1078.  
  1079. ) Values placed in the segment register positions of the data structure must
  1080.   be valid for real mode. That is, the values must be paragraph addresses, not
  1081.   protected mode selectors.
  1082.  
  1083. ) The target real mode procedure must return with the stack in the same state
  1084.   as when it was called. This means that the real mode code may switch stacks
  1085.   while it is running, but must return on the same stack that it was called
  1086.   on and must return with a RETF and should not clear the stack of any
  1087.   parameters that were passed to it on the stack.
  1088.  
  1089. ) When this function returns, the real mode register data structure will
  1090.   contain the values that were returned by the real mode procedure. The CS:IP
  1091.   and SS:SP values will be unmodified in the data structure.
  1092.  
  1093. ) It is the caller's responsibility to remove any parameters that were pushed
  1094.   on the protected mode stack.
  1095.  
  1096. 2.22 - Function 0302h - Call Real Mode Procedure With IRET Frame:
  1097. -----------------------------------------------------------------
  1098.  
  1099.   Simulates a FAR CALL with flags pushed on the stack to a real mode routine.
  1100. The real mode procedure must return by executing an IRET instruction or a
  1101. RETF 2.
  1102.  
  1103. In:
  1104.   AX     = 0302h
  1105.   BH     = must be 0
  1106.   CX     = number of words to copy from the protected mode stack to the real
  1107.            mode stack
  1108.   ES:EDI = selector:offset of real mode register data structure in the
  1109.            following format:
  1110.  
  1111.            Offset  Length  Contents
  1112.            00h     4       EDI
  1113.            04h     4       ESI
  1114.            08h     4       EBP
  1115.            0ch     4       reserved, ignored
  1116.            10h     4       EBX
  1117.            14h     4       EDX
  1118.            18h     4       ECX
  1119.            1ch     4       EAX
  1120.            20h     2       CPU status flags
  1121.            22h     2       ES
  1122.            24h     2       DS
  1123.            26h     2       FS
  1124.            28h     2       GS
  1125.            2ah     2       IP
  1126.            2ch     2       CS
  1127.            2eh     2       SP
  1128.            30h     2       SS
  1129.  
  1130. Out:
  1131.   if successful:
  1132.     carry flag clear
  1133.     ES:EDI = selector offset of modified real mode register data structure
  1134.  
  1135.   if failed:
  1136.     carry flag set
  1137.  
  1138. Notes:
  1139. ) The CS:IP in the real mode register data structure specifies the address of
  1140.   the real mode procedure to call.
  1141.  
  1142. ) If the SS:SP fields in the real mode register data structure are zero, a
  1143.   real mode stack will be provided by the host. Otherwise the real mode SS:SP
  1144.   will be set to the specified values before the procedure is called.
  1145.  
  1146. ) The flags specified in the real mode register data structure will be put on
  1147.   the real mode procedure's IRET frame. The procedure will be called with the
  1148.   interrupt and trace flags clear.
  1149.  
  1150. ) Values placed in the segment register positions of the data structure must
  1151.   be valid for real mode. That is, the values must be paragraph addresses, not
  1152.   protected mode selectors.
  1153.  
  1154. ) The target real mode procedure must return with the stack in the same state
  1155.   as when it was called. This means that the real mode code may switch stacks
  1156.   while it is running, but must return on the same stack that it was called
  1157.   on and must return with an IRET or discard the flags from the stack with a
  1158.   RETF 2 and should not clear the stack of any parameters that were passed to
  1159.   it on the stack.
  1160.  
  1161. ) When this function returns, the real mode register data structure will
  1162.   contain the values that were returned by the real mode procedure. The CS:IP
  1163.   and SS:SP values will be unmodified in the data structure.
  1164.  
  1165. ) It is the caller's responsibility to remove any parameters that were pushed
  1166.   on the protected mode stack.
  1167.  
  1168. 2.23 - Function 0303h - Allocate Real Mode Callback Address:
  1169. ------------------------------------------------------------
  1170.  
  1171.   Returns a unique real mode segment:offset, known as a "real mode callback",
  1172. that will transfer control from real mode to a protected mode procedure.
  1173. Callback addresses obtained with this function can be passed by a protected
  1174. mode program to a real mode application, interrupt handler, device driver,
  1175. TSR, etc... so that the real mode program can call procedures within the
  1176. protected mode program.
  1177.  
  1178. In:
  1179.   AX     = 0303h
  1180.   DS:ESI = selector:offset of protected mode procedure to call
  1181.   ES:EDI = selector:offset of 32h byte buffer for real mode register data
  1182.            structure to be used when calling the callback routine.
  1183.  
  1184. Out:
  1185.   if successful:
  1186.     carry flag clear
  1187.     CX:DX  = segment:offset of real mode callback
  1188.  
  1189.   if failed:
  1190.     carry flag set
  1191.  
  1192. Notes:
  1193. ) A descriptor may be allocated for each callback to hold the real mode SS
  1194.   descriptor. Real mode callbacks are a limited system resource. A client
  1195.   should release a callback that it is no longer using.
  1196.  
  1197. 2.24 - Function 0304h - Free Real Mode Callback Address:
  1198. --------------------------------------------------------
  1199.  
  1200.   Releases a real mode callback address that was previously allocated with the
  1201. Allocate Real Mode Callback Address function (0303h).
  1202.  
  1203. In:
  1204.   AX     = 0304h
  1205.   CX:DX  = segment:offset of real mode callback to be freed
  1206.  
  1207. Out:
  1208.   if successful:
  1209.     carry flag clear
  1210.  
  1211.   if failed:
  1212.     carry flag set
  1213.  
  1214. Notes:
  1215. ) Real mode callbacks are a limited system resource. A client should release
  1216.   any callback that it is no longer using.
  1217.  
  1218. 2.25 - Function 0305h - Get State Save/Restore Addresses:
  1219. ---------------------------------------------------------
  1220.  
  1221.   Returns the address of two procedures used to save and restore the state of
  1222. the current task's registers in the mode (protected or real) which is not
  1223. currently executing.
  1224.  
  1225. In:
  1226.   AX     = 0305h
  1227.  
  1228. Out:
  1229.   always successful:
  1230.     carry flag clear
  1231.     AX       = size of buffer in bytes required to save state
  1232.     BX:CX  = segment:offset of real mode routine used to save/restore state
  1233.     SI:EDI = selector:offset of protected mode routine used to save/restore
  1234.          state
  1235.  
  1236. Notes:
  1237. ) The real mode segment:offset returned by this function should be called
  1238.   only in real mode to save/restore the state of the protected mode registers.
  1239.   The protected mode selector:offset returned by this function should be
  1240.   called only in protected mode to save/restore the state of the real mode
  1241.   registers.
  1242.  
  1243. ) Both of the state save/restore procedures are entered by a FAR CALL with the
  1244.   following parameters:
  1245.  
  1246.   AL       = 0 to save state
  1247.            = 1 to restore state
  1248.   ES:(E)DI = (selector or segment):offset of state buffer
  1249.  
  1250.   The state buffer must be at least as large as the value returned in AX by
  1251.   INT 31h function 0305h. The state save/restore procedures do not modify any
  1252.   registers. DI must be used for the buffer offset in real mode, EDI must be
  1253.   used in protected mode.
  1254.  
  1255. ) Some DPMI hosts and VCPI/XMS/raw will not require the state to be saved,
  1256.   indicating this by returning a buffer size of zero in AX. In such cases,
  1257.   that addresses returned by this function can still be called, although they
  1258.   will simply return without performing any useful function.
  1259.  
  1260. ) Clients do not need to call the state save/restore procedures before using
  1261.   INT 31h function 0300h, 0301h, or 0302h. The state save/restore procedures
  1262.   are provided for clients that use the raw mode switch services only.
  1263.  
  1264. 2.26 - Function 0306h - Get Raw Mode Switch Addresses:
  1265. ------------------------------------------------------
  1266.  
  1267.   Returns addresses that can be called for low level mode switching.
  1268.  
  1269. In:
  1270.   AX     = 0306h
  1271.  
  1272. Out:
  1273.   always successful:
  1274.     carry flag clear
  1275.     BX:CX  = segment:offset of real to protected mode switch procedure
  1276.     SI:EDI = selector:offset of protected to real mode switch procedure
  1277.  
  1278. Notes:
  1279. ) The real mode segment:offset returned by this function should be called
  1280.   only in real mode to switch to protected mode. The protected mode
  1281.   selector:offset returned by this function should be called only in protected
  1282.   mode to switch to real mode.
  1283.  
  1284. ) The mode switch procedures are entered by a FAR JMP to the appropriate
  1285.   address with the following parameters:
  1286.  
  1287.   AX    = new DS
  1288.   CX    = new ES
  1289.   DX    = new SS
  1290.   (E)BX = new (E)SP
  1291.   SI    = new CS
  1292.   (E)DI = new (E)IP
  1293.  
  1294.   The processor is placed into the desired mode, and the DS, ES, SS, (E)SP,
  1295.   CS, and (E)IP registers are updated with the specific values. In other
  1296.   words, execution of the client continues in the requested mode at the
  1297.   address provided in registers SI:(E)DI. The values specified to be placed
  1298.   into the segment registers must be appropriate for the destination mode.
  1299.   That is, segment addresses for real mode, and selectors for protected mode.
  1300.  
  1301.   The values in EAX, EBX, ECX, EDX, ESI, and EDI after the mode switch are
  1302.   undefined. EBP will be preserved across the mode switch call so it can be
  1303.   used as a pointer. FS and GS will contain zero after the mode switch.
  1304.  
  1305.   If interrupts are disabled when the mode switch procedure is invoked, they
  1306.   will not be re-enabled by the host (even temporarily).
  1307.  
  1308. ) It is up to the client to save and restore the state of the task when using
  1309.   this function to switch modes. This requires the state save/restore
  1310.   procedures whose addresses can be obtained with INT 31h function 0305h.
  1311.  
  1312. 2.27 - Function 0400h - Get Version:
  1313. ------------------------------------
  1314.  
  1315.   Returns the version of the DPMI Specification implemented by the DPMI host.
  1316. The client can use this information to determine what functions are available.
  1317.  
  1318. In:
  1319.   AX     = 0400h
  1320.  
  1321. Out:
  1322.   always successful:
  1323.     carry flag clear
  1324.     AH     = DPMI major version as a binary number (VCPI/XMS/raw returns 00h)
  1325.     AL     = DPMI minor version as a binary number (VCPI/XMS/raw returns 5ah)
  1326.     BX       = flags:
  1327.          Bits    Significance
  1328.              0       0 = host is 16bit (PMODE/W never runs under one of these)
  1329.              1 = host is 32bit
  1330.          1         0 = CPU returned to V86 mode for reflected interrupts
  1331.              1 = CPU returned to real mode for reflected interrupts
  1332.          2         0 = virtual memory not supported
  1333.              1 = virtual memory supported
  1334.          3-15    reserved
  1335.     CL       = processor type:
  1336.          03h = 80386
  1337.          04h = 80486
  1338.          05h = 80586
  1339.          06h-ffh = reserved
  1340.     DH       = current value of master PIC base interrupt (low 8 IRQs)
  1341.     DL       = current value of slave PIC base interrupt (high 8 IRQs)
  1342.  
  1343. Notes:
  1344. ) The major and minor version numbers are binary, not BCD. So a DPMI 0.9
  1345.   implementation would return AH as 0 and AL as 5ah (90).
  1346.  
  1347. 2.28 - Function 0500h - Get Free Memory Information:
  1348. ----------------------------------------------------
  1349.  
  1350.   Returns information about the amount of available memory. Since DPMI clients
  1351. could be running in a multitasking environment, the information returned by
  1352. this function should be considered advisory.
  1353.  
  1354. In:
  1355.   AX     = 0500h
  1356.   ES:EDI = selector:offset of 48 byte buffer
  1357.  
  1358. Out:
  1359.   if successful:
  1360.     carry flag clear
  1361.     buffer is filled with the following information:
  1362.  
  1363.       Offset  Length  Contents
  1364.       00h     4       Largest available free block in bytes
  1365.       04h     2ch     Other fields only supplied by DPMI
  1366.  
  1367.   if failed:
  1368.     carry flag set
  1369.  
  1370. Notes:
  1371. ) Only the first field of the structure is guaranteed to contain a valid
  1372.   value. Any fields that are not supported by the host will be set to -1
  1373.   (0ffffffffh) to indicate that the information is not available.
  1374.  
  1375. 2.29 - Function 0501h - Allocate Memory Block:
  1376. ----------------------------------------------
  1377.  
  1378.   Allocates a block of extended memory.
  1379.  
  1380. In:
  1381.   AX     = 0501h
  1382.   BX:CX  = size of block in bytes (must be non-zero)
  1383.  
  1384. Out:
  1385.   if successful:
  1386.     carry flag clear
  1387.     BX:CX  = linear address of allocated memory block
  1388.     SI:DI  = memory block handle (used to resize and free block)
  1389.  
  1390.   if failed:
  1391.     carry flag set
  1392.  
  1393. Notes:
  1394. ) The allocated block is guaranteed to have at least dword alignment.
  1395.  
  1396. ) This function does not allocate any descriptors for the memory block. It is
  1397.   the responsibility of the client to allocate and initialize any descriptors
  1398.   needed to access the memory with additional function calls.
  1399.  
  1400. 2.30 - Function 0502h - Free Memory Block:
  1401. ------------------------------------------
  1402.  
  1403.   Frees a memory block previously allocated with the Allocate Memory Block
  1404. function (0501h).
  1405.  
  1406. In:
  1407.   AX     = 0502h
  1408.   SI:DI  = memory block handle
  1409.  
  1410. Out:
  1411.   if successful:
  1412.     carry flag clear
  1413.  
  1414.   if failed:
  1415.     carry flag set
  1416.  
  1417. Notes:
  1418. ) No descriptors are freed by this call. It is the client's responsibility to
  1419.   free any descriptors that it previously allocated to map the memory block.
  1420.   Descriptors should be freed before memory blocks.
  1421.  
  1422. 2.31 - Function 0503h - Resize Memory Block:
  1423. --------------------------------------------
  1424.  
  1425.   Changes the size of a memory block previously allocated with the Allocate
  1426. Memory Block function (0501h).
  1427.  
  1428. In:
  1429.   AX     = 0503h
  1430.   BX:CX  = new size of block in bytes (must be non-zero)
  1431.   SI:DI  = memory block handle
  1432.  
  1433. Out:
  1434.   if successful:
  1435.     carry flag clear
  1436.     BX:CX  = new linear address of memory block
  1437.     SI:DI  = new memory block handle
  1438.  
  1439.   if failed:
  1440.     carry flag set
  1441.  
  1442. Notes:
  1443. ) After this function returns successfully, the previous handle for the memory
  1444.   block is invalid and should not be used anymore.
  1445.  
  1446. ) It is the client's responsibility to update any descriptors that map the
  1447.   memory block with the new linear address after resizing the block.
  1448.  
  1449. 2.32 - Function 0800h - Physical Address Mapping:
  1450. -------------------------------------------------
  1451.  
  1452.   Converts a physical address into a linear address. This functions allows the
  1453. client to access devices mapped at a specific physical memory address.
  1454. Examples of this are the frame buffers of certain video cards in extended
  1455. memory.
  1456.  
  1457. In:
  1458.   AX     = 0800h
  1459.   BX:CX  = physical address of memory
  1460.   SI:DI  = size of region to map in bytes
  1461.  
  1462. Out:
  1463.   if successful:
  1464.     carry flag clear
  1465.     BX:CX  = linear address that can be used to access the physical memory
  1466.  
  1467.   if failed:
  1468.     carry flag set
  1469.  
  1470. Notes:
  1471. ) It is the caller's responsibility to allocate and initialize a descriptor
  1472.   for access to the memory.
  1473.  
  1474. ) Clients should not use this function to access memory below the 1 MB
  1475.   boundary.
  1476.  
  1477. 2.33 - Function 0801h - Free Physical Address Mapping:
  1478. ------------------------------------------------------
  1479.  
  1480.   Releases a mapping of physical to linear addresses that was previously
  1481. obtained with function 0800h.
  1482.  
  1483. In:
  1484.   AX     = 0801h
  1485.   BX:CX  = linear address returned by physical address mapping call
  1486.  
  1487. Out:
  1488.   if successful:
  1489.     carry flag clear
  1490.  
  1491.   if failed:
  1492.     carry flag set
  1493.  
  1494. Notes:
  1495. ) The client should call this function when it is finished using a device
  1496.   previously mapped to linear addresses with function 0801h.
  1497.  
  1498. 2.34 - Function 0900h - Get and Disable Virtual Interrupt State:
  1499. ----------------------------------------------------------------
  1500.  
  1501.   Disables the virtual interrupt flag and returns the previous state of it.
  1502.  
  1503. In:
  1504.   AX     = 0900h
  1505.  
  1506. Out:
  1507.   always successful:
  1508.     carry flag clear
  1509.     AL       = 0 if virtual interrupts were previously disabled
  1510.     AL       = 1 if virtual interrupts were previously enabled
  1511.  
  1512. Notes:
  1513. ) AH is not changed by this function. Therefore the previous state can be
  1514.   restored by simply executing another INT 31h.
  1515.  
  1516. ) A client that does not need to know the prior interrupt state can execute
  1517.   the CLI instruction rather than calling this function. The instruction may
  1518.   be trapped by a DPMI host and should be assumed to be very slow.
  1519.  
  1520. 2.35 - Function 0901h - Get and Enable Virtual Interrupt State:
  1521. ---------------------------------------------------------------
  1522.  
  1523.   Enables the virtual interrupt flag and returns the previous state of it.
  1524.  
  1525. In:
  1526.   AX     = 0901h
  1527.  
  1528. Out:
  1529.   always successful:
  1530.     carry flag clear
  1531.     AL       = 0 if virtual interrupts were previously disabled
  1532.     AL       = 1 if virtual interrupts were previously enabled
  1533.  
  1534. Notes:
  1535. ) AH is not changed by this function. Therefore the previous state can be
  1536.   retstored by simply executing another INT 31h.
  1537.  
  1538. ) A client that does not need to know the prior interrupt state can execute
  1539.   the STI instruction rather than calling this function. The instruction may
  1540.   be trapped by a DPMI host and should be assumed to be very slow.
  1541.  
  1542. 2.36 - Function 0902h - Get Virtual Interrupt State:
  1543. ----------------------------------------------------
  1544.  
  1545.   Returns the current state of the virtual interrupt flag.
  1546.  
  1547. In:
  1548.   AX     = 0902h
  1549.  
  1550. Out:
  1551.   always successful:
  1552.     carry flag clear
  1553.     AL       = 0 if virtual interrupts are disabled
  1554.     AL       = 1 if virtual interrupts are enabled
  1555.  
  1556. Notes:
  1557. ) This function should be used in preference to the PUSHF instruction to
  1558.   examine the interrupt flag, because the PUSHF instruction returns the
  1559.   physical interrupt flag rather than the virtualized interrupt flag. On some
  1560.   DPMI hosts, the physical interrupt flag will always be enabled, even when
  1561.   the hardware interrupts are not being passed through to the client.
  1562.  
  1563. 2.37 - Function EEFFh - Get DOS Extender Information:
  1564. -----------------------------------------------------
  1565.  
  1566.   Returns information about the DOS extender.
  1567.  
  1568. In:
  1569.   AX     = EEFFh
  1570.  
  1571. Out:
  1572.   if successful:
  1573.     carry flag clear
  1574.     EAX    = 'PMDW' (504D4457h)
  1575.     ES:EBX = selector:offset of ASCIIZ copyright string
  1576.     CH     = protected mode system type (0=raw, 1=XMS, 2=VCPI, 3=DPMI)
  1577.     CL     = processor type (3=386, 4=486, 5=586)
  1578.     DH     = extender MAJOR version (binary)
  1579.     DL     = extender MINOR version (binary)
  1580.  
  1581.   if failed:
  1582.     carry flag set
  1583.  
  1584. Notes:
  1585. ) In PMODE/W's implementation of this function, the value returned in ES is
  1586.   equivalent to the 4G data selector returned in DS at startup.
  1587.  
  1588. ) This function is always successful under PMODE/W.
  1589.  
  1590. ------------------------------------------------------------------------------
  1591. -------------- 3 - Supported DOS extended INT 21h functions ------------------
  1592. ------------------------------------------------------------------------------
  1593.  
  1594.   For the most part, PMODE/W extends only the most widely used DOS functions.
  1595. The term "extend" means to extend real mode 16:16 pointers which have a limit
  1596. of 1MB into the full protected mode range of 16:32 pointers with a range of
  1597. 4GB. Since DOS can only address memory under 1MB, we must buffer any data that
  1598. is to be passed to or from DOS in low memory. Only DOS functions which use
  1599. 16:16 pointers or segment registers need to be extended. This means that DOS
  1600. functions that are not listed here can still be used provided they don't make
  1601. use of those kinds of parameters. Examples of such functions are INT 21h
  1602. AH=30h or INT 21h AH=2, etc. The following is a detailed list of all functions
  1603. extended by PMODE/W. All segment registers used as parameters must be valid
  1604. protected mode selectors. Any functions that are not listed here will be
  1605. passed on to the real mode INT 21h handler without any buffering or
  1606. modification. This and the other sections on interrupts are provided as
  1607. reference as to how PMODE/W deals with these interrupts. It is assumed the
  1608. reader is familiar with the normal real mode operation of these functions.
  1609.  
  1610. 3.0 - Function 09h - Write String to Standard Output:
  1611. -----------------------------------------------------
  1612.  
  1613. In:
  1614.   AH     = 09h
  1615.   DS:EDX -> '$' terminated string to write
  1616.  
  1617. Out:
  1618.   always successful
  1619.  
  1620. 3.1 - Function 1Ah - Set Disk Transfer Area:
  1621. --------------------------------------------
  1622.  
  1623. In:
  1624.   AH     = 1Ah
  1625.   DS:EDX -> buffer for DTA
  1626.  
  1627. Out:
  1628.   always successful
  1629.  
  1630. Notes:
  1631. ) PMODE/W keeps an internal DTA buffer in low memory that is used to buffer
  1632.   any functions which use the DTA. After calling the real mode DOS function,
  1633.   the data will be transfered into the buffer specified by DS:EDX.
  1634.  
  1635. 3.2 - Function 1Bh - Get Allocation Information for Default Drive:
  1636. ------------------------------------------------------------------
  1637.  
  1638. In:
  1639.   AH     = 1Bh
  1640.  
  1641. Out:
  1642.   always successful:
  1643.     AL     = sectors per cluster
  1644.     ECX    = bytes per sector
  1645.     EDX    = total number of clusters
  1646.     DS:EBX -> media ID byte
  1647.  
  1648. Notes:
  1649. ) This functions simply converts the real mode segment:offset returned by DOS
  1650.   to a protected mode selector:offset.
  1651.  
  1652. 3.3 - Function 1Ch - Get Allocation Information for Specific Drive:
  1653. -------------------------------------------------------------------
  1654.  
  1655. In:
  1656.   AH     = 1Ch
  1657.   DL     = drive number
  1658.  
  1659. Out:
  1660.   if successful:
  1661.     AL     = sectors per cluster
  1662.     ECX    = bytes per sector
  1663.     EDX    = total number of clusters
  1664.     DS:EBX -> media ID byte
  1665.  
  1666.   if failed:
  1667.     AL     = FFh (invalid drive)
  1668.  
  1669. Notes:
  1670. ) This functions simply converts the real mode segment:offset returned by DOS
  1671.   to a protected mode selector:offset.
  1672.  
  1673. 3.4 - Function 1Fh - Get Drive Parameter Block for Default Drive:
  1674. -----------------------------------------------------------------
  1675.  
  1676. In:
  1677.   AH     = 1Fh
  1678.  
  1679. Out:
  1680.   if successful:
  1681.     AL     = 0
  1682.     DS:EBX -> drive parameter block
  1683.  
  1684.   if failed:
  1685.     AL     = FFh (invalid drive)
  1686.  
  1687. Notes:
  1688. ) This functions simply converts the real mode segment:offset returned by DOS
  1689.   to a protected mode selector:offset.
  1690.  
  1691. 3.5 - Function 25h - Set Interrupt Vector:
  1692. ------------------------------------------
  1693.  
  1694. In:
  1695.   AH     = 25h
  1696.   AL     = interrupt number
  1697.   DS:EDX -> interrupt routine
  1698.  
  1699. Out:
  1700.   if successful:
  1701.     carry flag clear
  1702.  
  1703.   if failed:
  1704.     carry flag set
  1705.  
  1706. Notes:
  1707. ) This function is equivalent to INT 31h function 0205h.
  1708.  
  1709. 3.6 - Function 2Fh - Get Disk Transfer Area:
  1710. --------------------------------------------
  1711.  
  1712. In:
  1713.   AH     = 2Fh
  1714.  
  1715. Out:
  1716.   always successful:
  1717.     ES:EBX -> DTA
  1718.  
  1719. Notes:
  1720. ) This function will return the value that was previously set by function 1Ah
  1721.   or the default buffer if function 1Ah was not called.
  1722.  
  1723. 3.7 - Function 32h - Get Drive Parameter Block for Specific Drive:
  1724. ------------------------------------------------------------------
  1725.  
  1726. In:
  1727.   AH     = 32h
  1728.   DL     = drive number
  1729.  
  1730. Out:
  1731.   if successful:
  1732.     AL     = 0
  1733.     DS:EBX -> drive parameter block
  1734.  
  1735.   if failed:
  1736.     AL     = FFh (invalid drive)
  1737.  
  1738. Notes:
  1739. ) This functions simply converts the real mode segment:offset returned by DOS
  1740.   to a protected mode selector:offset.
  1741.  
  1742. 3.8 - Function 34h - Get Address of InDOS Flag:
  1743. -----------------------------------------------
  1744.  
  1745. In:
  1746.   AH = 34h
  1747.  
  1748. Out:
  1749.   always successful:
  1750.     ES:EBX -> InDOS flag
  1751.  
  1752. Notes:
  1753. ) This functions simply converts the real mode segment:offset returned by DOS
  1754.   to a protected mode selector:offset.
  1755.  
  1756. 3.9 - Function 35h - Get Interrupt Vector:
  1757. ------------------------------------------
  1758.  
  1759. In:
  1760.   AH     = 35h
  1761.   AL     = interrupt number
  1762.  
  1763. Out:
  1764.   always successful:
  1765.     ES:EBX -> interrupt routine
  1766.  
  1767. Notes:
  1768. ) This function is equivalent to INT 31h function 0204h.
  1769.  
  1770. 3.10 - Function 39h - Create Subdirectory:
  1771. ------------------------------------------
  1772.  
  1773. In:
  1774.   AH     = 39h
  1775.   DS:EDX -> ASCIIZ path name
  1776.  
  1777. Out:
  1778.   if successful:
  1779.     carry flag clear
  1780.  
  1781.   if failed:
  1782.     carry flag set
  1783.     EAX = error code
  1784.  
  1785. 3.11 - Function 3Ah - Remove Subdirectory:
  1786. ------------------------------------------
  1787.  
  1788. In:
  1789.   AH     = 3Ah
  1790.   DS:EDX -> ASCIIZ path name
  1791.  
  1792. Out:
  1793.   if successful:
  1794.     carry flag clear
  1795.  
  1796.   if failed:
  1797.     carry flag set
  1798.     EAX = error code
  1799.  
  1800. 3.12 - Function 3Bh - Set Directory:
  1801. ------------------------------------
  1802.  
  1803. In:
  1804.   AH     = 3Bh
  1805.   DS:EDX -> ASCIIZ path name
  1806.  
  1807. Out:
  1808.   if successful:
  1809.     carry flag clear
  1810.  
  1811.   if failed:
  1812.     carry flag set
  1813.     EAX = error code
  1814.  
  1815. 3.13 - Function 3Ch - Create File:
  1816. ----------------------------------
  1817.  
  1818. In:
  1819.   AH     = 3Ch
  1820.   CX     = attribute
  1821.   DS:EDX -> ASCIIZ path name
  1822.  
  1823. Out:
  1824.   if successful:
  1825.     carry flag clear
  1826.     EAX = handle
  1827.  
  1828.   if failed:
  1829.     carry flag set
  1830.     EAX = error code
  1831.  
  1832. 3.14 - Function 3Dh - Open File:
  1833. --------------------------------
  1834.  
  1835. In:
  1836.   AH     = 3Dh
  1837.   AL     = open code
  1838.   DS:EDX -> ASCIIZ path name
  1839.  
  1840. Out:
  1841.   if successful:
  1842.     carry flag clear
  1843.     EAX = handle
  1844.  
  1845.   if failed:
  1846.     carry flag set
  1847.     EAX = error code
  1848.  
  1849. 3.15 - Function 3Fh - Read From File:
  1850. -------------------------------------
  1851.  
  1852. In:
  1853.   AH     = 3Fh
  1854.   BX     = file handle
  1855.   ECX     = number of bytes to read
  1856.   DS:EDX -> buffer to read to
  1857.  
  1858. Out:
  1859.   if successful:
  1860.     carry flag clear
  1861.     EAX = number of bytes read
  1862.  
  1863.   if failed:
  1864.     carry flag set
  1865.     EAX = error code
  1866.  
  1867. 3.16 - Function 40h - Write To File:
  1868. ------------------------------------
  1869.  
  1870. In:
  1871.   AH     = 40h
  1872.   BX     = file handle
  1873.   ECX     = number of bytes to write
  1874.   DS:EDX -> buffer to write from
  1875.  
  1876. Out:
  1877.   if successful:
  1878.     carry flag clear
  1879.     EAX = number of bytes written
  1880.  
  1881.   if failed:
  1882.     carry flag set
  1883.     EAX = error code
  1884.  
  1885. 3.17 - Function 41h - Delete File:
  1886. ----------------------------------
  1887.  
  1888. In:
  1889.   AH     = 41h
  1890.   DS:EDX -> ASCIIZ path name
  1891.  
  1892. Out:
  1893.   if successful:
  1894.     carry flag clear
  1895.  
  1896.   if failed:
  1897.     carry flag set
  1898.     EAX = error code
  1899.  
  1900. 3.18 - Function 43h - Get/Set File Attributes:
  1901. ----------------------------------------------
  1902.  
  1903. In:
  1904.   AH     = 43h
  1905.   AL     = function code
  1906.   CX     = desired attributes
  1907.   DS:EDX -> ASCIIZ path name
  1908.  
  1909. Out:
  1910.   if successful:
  1911.     carry flag clear
  1912.     CX = current attributes
  1913.  
  1914.   if failed:
  1915.     carry flag set
  1916.     EAX = error code
  1917.  
  1918. 3.19 - Function 47h - Get Directory Path:
  1919. -----------------------------------------
  1920.  
  1921. In:
  1922.   AH     = 47h
  1923.   DL     = drive number
  1924.   DS:ESI -> buffer for path
  1925.  
  1926. Out:
  1927.   if successful:
  1928.     carry flag clear
  1929.     buffer pointer to by DS:ESI is filled with the path
  1930.  
  1931.   if failed:
  1932.     carry flag set
  1933.     EAX = error code
  1934.  
  1935. 3.20 - Function 48h - Allocate Memory Block:
  1936. --------------------------------------------
  1937.  
  1938. In:
  1939.   AH     = 48h
  1940.   BX     = paragraphs to allocate
  1941.  
  1942. Out:
  1943.   if successful:
  1944.     carry flag clear
  1945.     EAX = selector for memory block
  1946.  
  1947.   if failed:
  1948.     carry flag set
  1949.     EAX = error code
  1950.     EBX = maximum paragraphs available
  1951.  
  1952. Notes:
  1953. ) This function allocates ONLY DOS memory below 1MB.
  1954.  
  1955. ) This function is equivalent to INT 31h function 0100h.
  1956.  
  1957. 3.21 - Function 49h - Free Memory Block:
  1958. ----------------------------------------
  1959.  
  1960. In:
  1961.   AH     = 49h
  1962.   ES     = selector for memory block
  1963.  
  1964. Out:
  1965.   if successful:
  1966.     carry flag clear
  1967.     ES = NULL selector (zeroed to prevent loading an invalid selector)
  1968.  
  1969.   if failed:
  1970.     carry flag set
  1971.     EAX = error code
  1972.  
  1973. Notes:
  1974. ) This function is equivalent to INT 31h function 0101h.
  1975.  
  1976. 3.22 - Function 4Ah - Resize Memory Block:
  1977. ------------------------------------------
  1978.  
  1979. In:
  1980.   AH     = 4Ah
  1981.   BX     = total paragraphs to allocate
  1982.   ES     = selector
  1983.  
  1984. Out:
  1985.   if successful:
  1986.     carry flag clear
  1987.  
  1988.   if failed:
  1989.     carry flag set
  1990.     EAX = error code
  1991.     EBX = maximum paragraphs available for specified memory block
  1992.  
  1993. Notes:
  1994. ) This function is equivalent to INT 31h function 0102h.
  1995.  
  1996. 3.23 - Function 4Bh - Sub-Function 00h - Load and Execute Program:
  1997. ------------------------------------------------------------------
  1998.  
  1999. In:
  2000.   AH     = 4Bh
  2001.   AL     = 00h
  2002.   DS:EDX -> path name
  2003.   ES:EBX -> parameter block
  2004.  
  2005. Out:
  2006.   if successful:
  2007.     carry flag clear
  2008.  
  2009.   if failed:
  2010.     carry flag set
  2011.  
  2012. Notes:
  2013. ) In order to overcome DOS's inability to access data over 1 MB, the
  2014.   environment specified in the parameter block will be copied into an
  2015.   intermediate buffer before being passed on to DOS. The buffer will be
  2016.   allocated through DOS function 48h and freed through 49h when the program
  2017.   is done executing. There must be enough available low memory to hold the
  2018.   environment data or an error will occur. Keep this in mind when passing
  2019.   an environment using spawnle() and related functions.
  2020.  
  2021. 3.24 - Function 4Eh - Search for First Filename Match:
  2022. ------------------------------------------------------
  2023.  
  2024. In:
  2025.   AH     = 4Eh
  2026.   CX     = file attribute
  2027.   DS:EDX -> ASCIIZ path name
  2028.  
  2029. Out:
  2030.   if successful:
  2031.     carry flag clear
  2032.  
  2033.   if failed:
  2034.     carry flag set
  2035.     EAX = error code
  2036.  
  2037. Notes:
  2038. ) PMODE/W keeps an internal DTA buffer in low memory that is used to buffer
  2039.   any functions which use the DTA. After calling the real mode DOS function,
  2040.   the data will be transfered into the buffer specified by function 1Ah or
  2041.   the default buffer if function 1Ah was not called.
  2042.  
  2043. 3.25 - Function 4Fh - Search for Next Filename Match:
  2044. -----------------------------------------------------
  2045.  
  2046. In:
  2047.   AH     = 4Fh
  2048.  
  2049. Out:
  2050.   if successful:
  2051.     carry flag clear
  2052.  
  2053.   if failed:
  2054.     carry flag set
  2055.     EAX = error code
  2056.  
  2057. Notes:
  2058. ) PMODE/W keeps an internal DTA buffer in low memory that is used to buffer
  2059.   any functions which use the DTA. After calling the real mode DOS function,
  2060.   the data will be transfered into the buffer specified by function 1Ah or
  2061.   the default buffer if function 1Ah was not called.
  2062.  
  2063. 3.26 - Function 56h - Rename File:
  2064. ----------------------------------
  2065.  
  2066. In:
  2067.   AH     = 56h
  2068.   DS:EDX -> old filename
  2069.   ES:EDI -> new filename
  2070.  
  2071. Out:
  2072.   if successful:
  2073.     carry flag clear
  2074.  
  2075.   if failed:
  2076.     carry flag set
  2077.     EAX = error code
  2078.  
  2079. 3.27 - Function 62h - Get PSP Address
  2080. -----------------------------------------------------
  2081.  
  2082. In:
  2083.   AH     = 62h
  2084.  
  2085. Out:
  2086.   always successful:
  2087.     BX = PSP Selector
  2088.  
  2089. Notes:
  2090. ) This function returns the protected mode PSP selector. Use INT 21h/AH=51h if
  2091.   you require a real mode segment address.
  2092.  
  2093. ------------------------------------------------------------------------------
  2094. --------------- 4 - Supported mouse extended INT 33h functions ---------------
  2095. ------------------------------------------------------------------------------
  2096.  
  2097.   The mouse functions are technically not part of Watcom C/C++ support because
  2098. they are not used by any of the libraries. But we extend the most popular
  2099. functions because they are so widely used. The functions that need to be
  2100. extended are those that require addresses to be passed in segment registers.
  2101. All other mouse functions not listed here will work if they do not take
  2102. segment registers as parameters. This means that in addition to the functions
  2103. listed here, functions like 0000h, 0001h, 0002h, etc... will work. But
  2104. functions like 0012h and 0018h will not work directly from protected mode
  2105. because they pass or return segment registers as parameters or require low
  2106. memory buffering. You may still use those functions, but you must call them
  2107. through DPMI and make sure that any code or data they use resides in low
  2108. memory and the code is real mode code (like DPMI callback if you wish to pass
  2109. control on to protected mode code from there).
  2110.  
  2111. 4.0 - Function 0009h - Define Graphics Cursor:
  2112. ----------------------------------------------
  2113.  
  2114. In:
  2115.   AX     = 0009h
  2116.   BX     = column of cursor hot spot in bitmap
  2117.   CX     = row of cursor hot spot in bitmap
  2118.   ES:EDX -> mask bitmap
  2119.  
  2120. Out:
  2121.   always successful
  2122.  
  2123. 4.1 - Function 000Ch - Define Interrupt Subroutine Parameters:
  2124. --------------------------------------------------------------
  2125.  
  2126. In:
  2127.   AX     = 000Ch
  2128.   CX     = call mask
  2129.   ES:EDX -> FAR routine
  2130.  
  2131. Out:
  2132.   always successful
  2133.  
  2134. Notes:
  2135. ) This function will use a DPMI real mode callback to pass control from real
  2136.   mode to your protected mode interrupt subroutine.
  2137.  
  2138. ) Calling this function with a FAR routine of 0000:00000000 is analogous to
  2139.   calling the real mode mouse driver with an address of 0000:0000 which will
  2140.   undefine the interrupt subroutine.
  2141.  
  2142. 4.2 - Function 0016h - Save Driver State:
  2143. -----------------------------------------
  2144.  
  2145. In:
  2146.   AX     = 0016h
  2147.   BX     = size of buffer
  2148.   ES:EDX -> buffer for driver state
  2149.  
  2150. Out:
  2151.   always successful
  2152.  
  2153. 4.3 - Function 0017h - Restore Driver State:
  2154. --------------------------------------------
  2155.  
  2156. In:
  2157.   AX     = 0017h
  2158.   BX     = size of buffer
  2159.   ES:EDX -> buffer containing saved state
  2160.  
  2161. Out:
  2162.   always successful
  2163.  
  2164. ------------------------------------------------------------------------------
  2165. ------------------------ End of PMODE/W Documentation ------------------------
  2166. ------------------------------------------------------------------------------
  2167.  
  2168.