home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / vrac / pmw100.zip / PMODEW.DOC < prev    next >
Text File  |  1994-11-21  |  64KB  |  1,784 lines

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