home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / dos / programo / pmw120.exe / PMODEW.DOC < prev    next >
Text File  |  1995-07-28  |  71KB  |  2,021 lines

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