home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l351 / 1.ddi / DOC / LITE286.DOC < prev    next >
Encoding:
Text File  |  1993-02-03  |  68.4 KB  |  1,707 lines

  1.  
  2.  
  3.  
  4.                    286|DOS-Extender Lite User's Guide
  5.  
  6.                          Phar Lap Software, Inc.
  7.                 60 Aberdeen Ave., Cambridge, MA  02138
  8.                tech-support@pharlap.com
  9.                +1 617 661-1510 (Voice)
  10.             +1 617 876-2972 (FAX)
  11.  
  12.             Bulletin Board Service:
  13.                +1 617 661-1009
  14.            300, 1200, 2400, 4800, 9600 baud
  15.             8 data, No parity, 1 stop bit
  16.  
  17.  
  18.  
  19.  
  20.  
  21. Copyright (c) 1992-93 Phar Lap Software, Inc.
  22.  
  23. Third Edition March 1993
  24.  
  25. All rights reserved.  Printed in the United States of America.  No 
  26. part of this publication may be reproduced, stored in a retrieval 
  27. system, or transmitted in any form or by any means, without prior 
  28. written permission of Phar Lap Software, Inc.  Use, duplication, or 
  29. disclosure by the Government is subject to restrictions as set forth 
  30. in subparagraph (c)(1)(ii) of the Rights in Technical Data and 
  31. Computer Software clause at 252.227-7013.
  32.  
  33. Microsoft C/C++ support library, Portions Copyright (c) Microsoft
  34.     Corporation.
  35.  
  36. 286|DOS-Extender(TM), 286|DOS-Extender Lite(TM) and 386|DOS-Extender(TM)
  37.   are trademarks, and Phar Lap(R) is a registered trademark of 
  38.   Phar Lap Software, Inc.
  39. 386MAX(TM) is a trademark of Qualitas, Inc.
  40. AutoCAD(R) is a registered trademark of Autodesk, Inc.
  41. COMPAQ(R) is a registered trademark of Compaq Computer Corporation.
  42. DESQview(TM) and QEMM(TM) are trademarks, and DESQ(R) is a registered 
  43.   trademark of Quarterdeck Office Systems.
  44. PC/XT(TM) is a trademark, and IBM(R), AT(R), PS/2(R), and OS/2(R) are 
  45.   registered trademarks of International Business Machines Corporation.
  46. 287(TM), 386(TM), 387(TM), 486(TM), and i486(TM) are trademarks, and 
  47.   Intel(R) is a registered trademark of Intel Corporation.
  48. Interleaf Publisher(R) is a registered trademark of Interleaf, Inc.
  49. Lotus(R) is a registered trademark of Lotus Development Corporation.
  50. Mathematica(TM) is a trademark of Wolfram Research Inc.
  51. Windows(TM) is a trademark, and Microsoft(R), MS(R), MS-DOS(R), and 
  52.   CodeView(R) are registered trademarks of Microsoft Corporation.
  53.  
  54.              Outline of Contents
  55.  
  56. Introduction           
  57.  
  58.  
  59. Chapter 1    A Quick Tour of 286|DOS-Extender Lite
  60.   1.1 Big Malloc
  61.   1.2 Protected Mode C++
  62.   1.3 Protected Mode MS-DOS
  63.   1.4 BIOS Calls in Protected Mode
  64.   1.5 Compatibility with Industry Standards
  65.   1.6 What's So Protected About Protected Mode?
  66.   1.7 Debugging with CVP7 Under MS-DOS (With the 286|DOS-Extender
  67.       Software Development Kit)
  68.              The Nuts and Bolts of CVW
  69.   1.8 What About Direct Screen Writes?
  70.   1.9 Summary
  71.  
  72.  
  73. Chapter 2    Using 286|DOS-Extender Lite with Microsoft C/C++
  74.   2.1 Differences Between Real- and Protected-Mode CL
  75.   2.2 Linking by Hand
  76.              CL Switches
  77.              LINK Switches
  78.  
  79.  
  80. Chapter 3    Running Protected Mode Applications Under MS-DOS
  81.   3.1 Compatibility
  82.   3.2 LITE286 Requirements
  83.   3.3 Error Messages
  84.   3.4 LITE286 Command Line Options
  85.   3.5 The Phar Lap Application Program Interface (PHAPI)
  86.  
  87.  
  88. Further Reading
  89.  
  90. ------------
  91. Introduction
  92. ------------
  93.  
  94. Welcome to the world beyond 640K!
  95.  
  96. Now, with your FREE 286|DOS-Extender Lite, it's easy to build multi-
  97. megabyte Microsoft Visual C++ and programs!  286|DOS-Extender Lite
  98. is a special trial version of Phar Lap Software's award-winning
  99. 286|DOS-Extender Software Development Kit (SDK).  It enables your
  100. program to break the 640K DOS barrier and access up to 2 MB of memory,
  101. with no need for overlays or EMS.  Your Extended-DOS programs will run
  102. under DOS, DESQview and Windows.
  103.                                 
  104. 286|DOS-Extender Lite includes all the capabilities you need to build 
  105. and run Extended-DOS programs with Microsoft Visual C++ 1.0, Professional
  106. Edition.  However, you may want to purchase Phar Lap's 286|DOS-Extender
  107. SDK if you would like the following features:  debugger support, access
  108. to up to 16 MB of memory, Phar Lap's technical support and extensive
  109. documentation, and the ability to deliver your Extended-DOS application
  110. to customers with Phar Lap's 286|DOS-Extender Run-Time Kit (RTK).  The
  111. following chart outlines the differences between 286|DOS-Extender Lite
  112. and 286|DOS-Extender SDK.  To order your SDK, just fill out the following
  113. coupon or contact Phar Lap.
  114.  
  115. 286|DOS-Extender SDK is available from:    Phar Lap Software, Inc.
  116.                                            60 Aberdeen Avenue
  117.      FREE PHAR LAP T-SHIRT               Cambridge, MA  02138
  118.        WITH EVERY ORDER!                 Phone 617-661-1510
  119.                                            Fax 617-876-2972
  120.  
  121.              286|DOS-EXTENDER LITE VS 286|DOS-EXTENDER SDK
  122.  
  123. 286|DOS-Extender Lite               │    286|DOS-Extender SDK
  124. ════════════════════════════════════╪═════════════════════════════════════
  125. No debugging support                │  Full support for CodeView
  126.                                     │
  127. Programs can use up to 2 MB memory  │  Programs can use up to 16 MB memory
  128.                                     │
  129. 50 pages of documentation on disk   │  700+ pages of printed documentation
  130.                                     │
  131. Technical support for installation  │  Technical support for development
  132.                                     │
  133. Cannot deliver Extended-DOS         │  Add-on run-time kit available for
  134.   programs to customers             │    delivering Extended-DOS programs
  135.                                     │
  136. Several example programs            │  Extensive example programs
  137.                                     │
  138. No spawn function available         │  Supports spawn function
  139.                                     │
  140.  
  141.                      286|DOS-Extender Order Form
  142.  
  143.  
  144. YES!  I would like to order ____ 286|DOS-Extender SDK x $495 each = _______
  145.       Mass. customers add 5% sales tax:                             _______
  146.       Shipping:  $5 U.S. or Canada, $50 overseas:                   _______
  147.       TOTAL =                                                       _______
  148.  
  149. Shipping Address:  (Please provide a street address.  No P.O. boxes.)
  150.       Name:__________________________ Company:_____________________________
  151.       Address:_____________________________________________________________
  152.       City:__________________________ State/Country:__________ Zip:________
  153.       Phone:_________________________ Fax:_________________________________
  154.  
  155. Method of Payment: (Check one)
  156.       ____ Check/money order (US$, US bank)    
  157.       ____ P.O.#(Approval required):_______________________________________
  158.       ____ MasterCard     ____ Visa     ____ American Express
  159.       Credit Card #:__________________________________ Exp. Date:__________
  160.       Cardholder's name:___________________________________________________
  161.  
  162. Return to:  Phar Lap Software, Inc.           FREE PHAR LAP T-SHIRT 
  163.             60 Aberdeen Avenue                  WITH EVERY ORDER!   
  164.             Cambridge, MA  02138
  165.             Phone 617-661-1510
  166.             Fax 617-876-2972
  167.  
  168.  
  169. -------------------------------------
  170. Chapter 1
  171. A Quick Tour of 286|DOS-Extender Lite
  172. -------------------------------------
  173.  
  174.  
  175.    Computers with Intel and Intel-compatible 80286 and later
  176. microprocessors hold a majority share of the IBM PC-compatible 
  177. marketplace.  These machines typically have two or more megabytes of 
  178. memory.  This is in sharp contrast to the situation just a few years 
  179. ago, when the typical PC had an 8088 and less than a megabyte of 
  180. memory.
  181.  
  182.    But MS-DOS has not kept up with these sweeping changes.  While PCs 
  183. are shipping with more memory and better processors, more DOS 
  184. applications than ever run out of memory.
  185.  
  186.    Many users have found that a 2 MB machine, for example, does not 
  187. actually give their applications 2 MB of memory:  applications are 
  188. held back by the 640K limitation imposed by MS-DOS.  You can add 
  189. memory to an IBM AT, PS/2, or 386 clone until you're blue in the 
  190. face, and many DOS applications will nonetheless run out of memory.
  191.  
  192.    These machines have untapped resources.  286|DOS-Extender Lite, Phar 
  193. Lap's 16-bit DOS extender for 80286, 80386, and 80486 PCs, puts all 
  194. this potential energy to work while fully preserving your investments 
  195. in MS-DOS, and Microsoft Visual C++.
  196.  
  197.    Let's look at an example.  Many manuals begin with the "hello 
  198. world" sample program, but to show the power of 286|DOS-Extender Lite 
  199. we need a sample program that suffers from the 640K confines of MS-
  200. DOS.  Such programs are plentiful; almost any DOS program that uses 
  201. large model, huge model, overlays, expanded memory (EMS), or the 
  202. eXtended Memory Specification (XMS), is a good example.  Any such 
  203. program is also a likely candidate for using 286|DOS-Extender Lite!
  204.  
  205.    But short of including 50,000 lines of code in our manual, how can 
  206. we provide a quick look at the problem of running old DOS on the new 
  207. machines?
  208.  
  209.    We can simulate some "programming in the large" issues by using a 
  210. small C program that requires a large amount of memory.  The program 
  211. shown below, BIG.C, attempts to allocate one megabyte of memory, and
  212. to use it as a 512 x 512 two-dimensional array of longs:
  213.  
  214. /* BIG.C */
  215.  
  216. #include <stdlib.h>
  217. #include <stdio.h>
  218. #include <malloc.h>
  219.  
  220. #define NROWS    512
  221. #define NCOLS    512
  222. #define    ARSIZE    ((long)NROWS * sizeof(long [NCOLS]))
  223.  
  224. main()
  225. {
  226.     int i, j;
  227.  
  228.     long (huge * array)[NCOLS];
  229.     array = (long (huge *)[NCOLS]) _halloc ( NROWS, sizeof(long [NCOLS]) );
  230.     if( ! array )
  231.     {
  232.     printf("Can't allocate %lu-byte array, giving up!\n", ARSIZE);
  233.     return 1;
  234.     }
  235.  
  236.     printf("Using %lu-byte array\n", ARSIZE);
  237.  
  238.     for (i=0; i<NROWS; i++)
  239.     {
  240.         for (j=0; j<NCOLS; j++)
  241.             array[i][j] = (long) i * j; /* touch every element */
  242.         printf("%d\r", i);              /* display odometer */
  243.     }
  244.  
  245.     printf("done\n");
  246.     return 0;
  247. }
  248. D:\LITE.30\EXAMPLES>big
  249. Can't allocate 1048576-byte array, giving up!
  250.  
  251.  
  252.    The Visual C++ command-line compiler, CL, can be used to compile 
  253. and link this straightforward C program for plain-vanilla, real-mode 
  254. MS-DOS.  The -AL (large model) switch is used in the CL command line 
  255. to get the maximum amount of available memory:
  256.  
  257. C:\>cl -AL big.c
  258.  
  259.    While CL compiles and links BIG.C without error, the huge allocation
  260. function _halloc must always fail.  Real-mode MS-DOS simply cannot
  261. address, much less allocate, more than one megabyte.  Even if the
  262. computer has 16 megabytes of memory, MS-DOS can only directly
  263. address the first megabyte.
  264.  
  265.    But to run BIG.EXE you don't have to switch to a different 
  266. operating system.  286|DOS-Extender Lite removes the one-megabyte DOS 
  267. barrier, while continuing to run under DOS.  You get to have your cake
  268. and eat it too.
  269.  
  270.    To produce a 286|DOS-Extender Lite version of the BIG program, 
  271. simply compile and link with CL's -Lp switch.  Specifying -Lp tells
  272. the linker to look for protected-mode libraries and create a protected-
  273. mode executable.  Protected-mode executable?  Under DOS?  That's right:
  274.  
  275. C:\>cl -AL -Lp big.c
  276.  
  277. C:\>bind286 big
  278.  
  279. C:\>big
  280. Using 1048576-byte array
  281. done
  282.  
  283.    We just allocated and accessed one megabyte under MS-DOS, in a 
  284. program whose name we typed on the DOS command line -- just like any 
  285. other regular DOS program.  The source code for the program, as we've 
  286. seen, used absolutely standard PC constructs:  no messing with 
  287. special interfaces like EMS or XMS, and no overlays.
  288.  
  289.    It's as if MS-DOS had been turned into a protected-mode operating 
  290. system, or at least into an operating system that can run protected 
  291. mode programs!  This in fact is exactly what 286|DOS-Extender Lite 
  292. does.  Behind the scenes, when BIG is run from the DOS command line, 
  293. the program reinvokes itself under 286|DOS-Extender Lite, which 
  294. resides in a program named LITE286.EXE.  (Incidentally, LITE286.EXE
  295. plus another file, DOSCALLS.DLL, must be somewhere on the path.) 
  296. Running BIG is equivalent to running LITE286 BIG. LITE286 puts the
  297. machine into protected mode, runs BIG, then puts the machine back
  298. into real mode.
  299.  
  300.    Clearly, BIG is not a typical real-mode DOS program.  CL takes
  301. advantage of the linker's ability to produce protected-mode Windows
  302. and OS/2 programs, using it instead to produce protected-mode DOS
  303. programs.  Chapter 2 of this manual explains precisely how this happens;
  304. if you prefer, you can run the compile and link steps yourself (from
  305. MAKE, for example).
  306.  
  307. --------------
  308. 1.1 Big Malloc
  309. --------------
  310.  
  311.    The huge allocation used in BIG.C provides a simple first example of 
  312. 286|DOS-Extender Lite.  In the same way that LITE286 can allocate
  313. large amounts of data, it can also load programs with large amounts of
  314. code, so the huge array is a good simulation of a large program.  Most
  315. C programs do not allocate huge arrays, but many DOS programs do contain
  316. enormous amounts of code.  Such programs often resort to performance-
  317. crippling overlays; BIG shows that, on an 80286 or higher machine with
  318. extended memory, this workaround is not necessary.
  319.  
  320.    BIG.C made life easy for itself by using the "huge" keyword, but 
  321. due to its often poor performance, "huge" is usually avoided in 
  322. commercial PC software.  More typically, large PC applications
  323. dynamically allocate memory via the C malloc() function, via operator
  324. new in C++, or directly via the MS-DOS Allocate Memory Block function
  325. (INT 21h AH=48h).
  326.  
  327.    Our next example program, MEMTEST, does nothing more than run 
  328. malloc() in a loop and touch every byte of the allocated memory.  
  329. When malloc() eventually returns NULL, indicating that memory is 
  330. exhausted, MEMTEST breaks out of the loop.  While clearly the program 
  331. does not do anything useful with the memory it allocates, its 
  332. insatiable appetite for memory is a very good simulation of a large 
  333. application:
  334.  
  335. /* MEMTEST.C */
  336.  
  337. #include <stdlib.h>
  338. #include <stdio.h>
  339. #include <string.h>
  340.  
  341. main()
  342. {
  343.     char *p;
  344.     unsigned long allocs;
  345.  
  346.     for (allocs = 0; ; allocs++)
  347.        if ((p = malloc(1024)) != 0)    /* in 1k blocks */
  348.        {
  349.            memset(p, 0, 1024); /* touch every byte */
  350.            *p = 'x';           /* do something, anything with */
  351.            p[1023] = 'y';      /* the allocated memory      */
  352.            
  353.            if (allocs && (allocs % 1024) == 0)   /* odometer */
  354.                printf("Allocated %u megabytes\r", allocs >> 10);
  355.        }
  356.        else
  357.            break;
  358.  
  359.        printf("Allocated %lu bytes\n", allocs << 10);
  360.        return 0;
  361. }
  362.  
  363.    Using Visual C++, this program can be compiled for real-mode
  364. MS-DOS with the following command lines:
  365.  
  366. C:\>cl -AL memtest.c
  367.  
  368.    This command produces a large model version of MEMTEST.EXE,
  369. allowing maximum memory allocation under real-mode MS-DOS.  On a
  370. COMPAQ 386 with 2 MB of memory, MEMTEST should allocate around 2 MB
  371. of memory (if you don't think this is what MEMTEST should do, you've 
  372. been programming in real mode for too long!).  But of course, here is
  373. what real-mode large model MEMTEST does instead:  
  374.  
  375. C:\>memtest
  376. Allocated 417792 bytes
  377.  
  378.    Only 408 KB available on a 2 MB machine?!  By making better use  
  379. of the DOS 5.0 LOADHIGH, DEVICEHIGH, and DOS=HIGH,UMB statements, or 
  380. by using superb expanded memory managers such as Quarterdeck QEMM or 
  381. Qualitas 386MAX, we could probably have created a better 
  382. configuration, in which MEMTEST might get as much as 610 KB or so.  
  383. But no matter how much we huffed and puffed and fooled with 
  384. CONFIG.SYS, real-mode MEMTEST would never allocate more than one 
  385. megabyte of memory.
  386.  
  387.    Furthermore, even if you do maximize the available DOS memory on 
  388. one machine, there is no guarantee that all (or even most) of a 
  389. program's users will have such an "ideal" configuration.  By 
  390. developing for protected-mode DOS, you can bypass a lot of these 
  391. messy user-configuration issues.
  392.  
  393.    Now, to produce a version of MEMTEST that behaves more sensibly, 
  394. the only thing you need to differently is to run in protected mode:
  395.  
  396. C:\>cl -Lp -AL memtest.c
  397.  
  398. C:\>bind286 memtest
  399.  
  400. C:\>memtest
  401. Allocated 2193408 bytes
  402.  
  403.    We allocated almost 2 MB of memory under MS-DOS!  This is 
  404. dramatically different behavior from the first version of MEMTEST we 
  405. produced, yet we're using the same source code.  Simply recompiling
  406. for 286|DOS-Extender Lite, without source code changes, gives us a
  407. program that runs under DOS yet breaks the 640K barrier, without EMS,
  408. overlays, or other workarounds.  Using 286|DOS-Extender Lite with
  409. Microsoft Visual C++ provides a version of malloc() that transparently
  410. uses extended memory, plus functions such as memset() and pointer
  411. dereferences such as *p and p[1023], which transparently access
  412. extended memory.
  413.  
  414. ----------------------
  415. 1.2 Protected Mode C++
  416. ----------------------
  417.  
  418.    286|DOS-Extender Lite is not limited to programs written in C; C++ 
  419. programs can just as easily run under protected-mode DOS.  For 
  420. example, the C++ operator "new" works in protected-mode DOS exactly
  421. the same as the C malloc() function:  instead of halting somewhere 
  422. around 640K, operator new can be used to allocate up to 2 MB of 
  423. memory under 286|DOS-Extender Lite.  (286|DOS-Extender SDK can 
  424. allocate up to 16 MB.)
  425.  
  426.    Other C++ features, such as the iostream input and output 
  427. operators and static constructors and destructors, work just the way 
  428. one would expect from having used C++ in real-mode DOS.
  429.  
  430.    The next sample program, MEMTEST2.CPP, uses a number of C++ 
  431. features.  The C++ set_new_handler() function is particularly useful; 
  432. it lets MEMTEST2 install a handler that will automatically be called 
  433. when operator new fails.  This considerably simplifies the program's 
  434. main loop:  
  435.  
  436. /* MEMTEST2.CPP */
  437.  
  438. #include <stdlib.h>
  439. #include <iostream.h>
  440. #include <new.h>
  441. #include <string.h>
  442.  
  443. class msg {
  444. public:
  445.     msg()   { cout << "hello from " << __FILE__ << "\n" ; }
  446.     ~msg()  { cout << "bye\n" ; }
  447.     } ;
  448.  
  449. static msg banner;  // test C++ static constructors, destructors
  450.  
  451. static unsigned long bytes = 0;
  452. static unsigned long allocs = 0;
  453. static unsigned blk_size = 10240;
  454.  
  455. int new_fail(size_t )
  456. {
  457.     if (blk_size)
  458.         blk_size >>= 1;  // try to allocate a smaller block
  459.     else
  460.     {   // memory exhausted
  461.         cout << "Allocated " << bytes << " bytes\n" ;
  462.         exit(1);
  463.     }
  464.     return 1;
  465. }
  466.  
  467. void
  468. main(void)
  469. {
  470.     char *p;
  471.  
  472.     _set_new_handler(new_fail);   // called when new fails
  473.  
  474.     for (;;)
  475.     {
  476.        p = new char[blk_size];   // allocate memory
  477.        memset(p, 0, blk_size);   // touch every byte
  478.        *p = 'x';                 // do something, anything with
  479.        p[blk_size-1] = 'y';      //   the allocated memory
  480.            
  481.        bytes += blk_size;
  482.        allocs++;
  483.        if ((allocs % 25) == 0)   // odometer
  484.             cout << "Allocated " << bytes << " bytes\r";
  485.     }
  486. }
  487.  
  488.    We won't even bother showing the real-mode version this time, 
  489. since by now it's pretty obvious how limited real mode is.  To 
  490. compile this C++ program for protected-mode DOS, all you need to
  491. do is add -Lp. 
  492.  
  493. C:\>cl -AL -Lp memtest2.cpp
  494.  
  495. C:\>bind286 memtest2
  496.  
  497. C:\>memtest2
  498. hello from memtest2.cpp
  499. Allocated 2027520 bytes
  500. bye
  501.  
  502.    Because 286|DOS-Extender Lite is compatible with the DPMI 
  503. specification (as well as with every other major memory-management 
  504. specification, including VCPI, XMS, VDS, and INT 15h), this protected 
  505. mode C++ program can allocate up to 2 MB of memory under all modes of 
  506. Windows 3.x:
  507.  
  508. C:\>memtest2
  509. hello from memtest2.cpp
  510. Allocated 2027520 bytes
  511. bye
  512.  
  513. -------------------------
  514. 1.3 Protected Mode MS-DOS
  515. -------------------------
  516.  
  517.    What's really happening here?  We've seen that 286|DOS-Extender 
  518. Lite can load programs with huge arrays, or enormous amounts of code, 
  519. and that protected-mode DOS versions of C functions such as malloc(), 
  520. and of operator new in C++, can dynamically allocate large amounts of 
  521. memory.  How does all this work?
  522.  
  523.    While generally used with C or C++ programs, 286|DOS-Extender Lite
  524. is not a C or C++ library.  286|DOS-Extender Lite does replace some 
  525. startup code and library functions, but this is simply to make the
  526. code protected-mode "clean." The real magic occurs at a lower level.
  527.  
  528.    In essence, 286|DOS-Extender Lite provides MS-DOS (INT 21h) 
  529. functions in protected mode.  Since your program runs in protected 
  530. mode, any software interrupts your program generates -- such as DOS  
  531. calls made by the C run-time library when you call a function such as 
  532. printf() -- occur in protected mode too, and are caught by 
  533. 286|DOS-Extender Lite. 
  534.  
  535.    In most cases, 286|DOS-Extender Lite passes the call down to MS-
  536. DOS, which is still running in real mode.  DOS file I/O functions are 
  537. handled this way, for example:  the 286|DOS-Extender Lite handler for 
  538. these functions reissues (or "reflects") the call in real mode. 
  539.  
  540.    Merely by providing protected-mode surrogates for these functions, 
  541. 286|DOS-Extender Lite allows your program to think that it is running 
  542. under a protected-mode version of MS-DOS.  The program can call INT 
  543. 21h in protected mode without worrying about the fact that its file 
  544. I/O buffers are probably located in extended memory.  286|DOS-
  545. Extender Lite automatically takes care of all the details of 
  546. transferring data between conventional memory (where real-mode DOS 
  547. can get at it) and extended memory (where your protected-mode program 
  548. probably allocated it).
  549.  
  550.    Because 286|DOS-Extender Lite acts as a protected-mode "wrapper" 
  551. around real-mode MS-DOS, you have a completely compatible 
  552. environment.  286|DOS-Extender Lite isn't replacing DOS, so it will 
  553. work with whatever version of DOS you or your customers already have.
  554.  
  555.    Of course, real-mode MS-DOS does not know how to do things like 
  556. run protected-mode programs, allocate extended memory, load dynamic 
  557. link libraries (DLLs), or install protected-mode interrupt handlers.  
  558. Requests such as these are handled by 286|DOS-Extender Lite entirely 
  559. in protected mode.
  560.  
  561.    Memory allocation is a good example.  Rather than use C or C++ 
  562. constructs to allocate memory, the next sample program, DOSMEM.C, 
  563. goes directly to DOS using INT 21h Function 48h (Allocate Memory 
  564. Block).  Typically, a DOS program finds out how much memory is 
  565. available by asking this function for 0FFFFh paragraphs (one 
  566. megabyte).  Real-mode DOS will naturally fail such a request, but it 
  567. will also return the actual number of paragraphs available in the 
  568. largest block of free memory:
  569.  
  570. /*  DOSMEM.C */
  571.  
  572. #include <stdlib.h>
  573. #include <stdio.h>
  574. #include <dos.h>
  575.  
  576. main()
  577. {
  578.     unsigned avail;
  579.     char far *fp;
  580.     _asm mov ah, 48h
  581.     _asm mov bx, 0FFFFh
  582.     _asm int 21h
  583.     _asm jc error
  584.     _asm mov word ptr fp+2, ax
  585.     _asm mov word ptr fp, 0
  586.     *fp = 'x';   /* make sure it's genuine */
  587.     printf("Allocated 0FFFFh paragraphs: %Fp\n", fp);
  588.     return 0;
  589. error:
  590.     _asm mov avail, bx
  591.     printf("Only %04Xh paragraphs available\n", avail);
  592.     return 1;
  593. }
  594.  
  595. C:\>cl dosmem.c
  596.  
  597. C:\>dosmem
  598. Only 4FE9 paragraphs available
  599.  
  600. In protected mode, an amazing thing happens:  a request for 0FFFFh 
  601. paragraphs easily succeeds:
  602.  
  603. C:\>cl -AL -Lp dosmem.c
  604.  
  605. C:\>bind286 dosmem
  606.  
  607. C:\>dosmem
  608. Allocated 0FFFFh paragraphs: 0A3D:0000
  609.  
  610.    Using the exact same INT 21h functional interface as real-mode 
  611. DOS, 286|DOS-Extender Lite provides functionality that DOS alone 
  612. can't provide.  This new functionality is provided to every protected 
  613. mode program running under 286|DOS-Extender Lite.  Thus, 286|DOS-
  614. Extender Lite isn't a library, but an extension to the operating 
  615. system.  (That's why it's called a DOS extender.)
  616.  
  617.    When protected-mode DOSMEM allocates 0FFFFh paragraphs, where does 
  618. this memory come from?  In general, this doesn't matter to the 
  619. program, because it has asked INT 21h Function 48h for memory, and 
  620. has received a value back in the AX register which it can use as the 
  621. basis for a far segment:offset pointer.  In DOSMEM.C, note how a far 
  622. pointer is created with the assembly-language instructions and poked
  623. with the C * dereferencing operator.   Thus, we have immediately usable
  624. memory; it doesn't really matter where it "comes from," nor for that
  625. matter what value INT 21h Function 48h returns in AX.  All we need to
  626. know is that we can use it.
  627.  
  628.    However, the pointer 0A3D:0000 displayed above by DOSMEM in 
  629. protected mode is a little strange.  Paragraph 0A3Dh seems to be too 
  630. low in memory, for example.  But in protected mode the address 
  631. 0A3D:0000 has nothing whatever to do with absolute memory location 
  632. 0A3D0h.  Instead, 0A3Dh is a protected-mode selector that is 
  633. essentially an index into a table of segment descriptors used by the 
  634. chip.  These descriptors in turn contain the base address, size, and 
  635. protection "access rights" of the corresponding segment.  Thus, 
  636. memory management in protected mode is somewhat indirect, but all the 
  637. indirection is managed entirely by the chip, "inside" an instruction 
  638. such as MOV AX, ES:[BX].
  639.  
  640. --------------------------------
  641. 1.4 BIOS Calls in Protected Mode
  642. --------------------------------
  643.  
  644.    To create a useful environment for PC software, it is not 
  645. sufficient merely to provide INT 21h in protected mode.  The ROM BIOS 
  646. calls (INT 10h, INT 16h, and so on) need to be available in protected 
  647. mode too. 
  648.  
  649.    C run-time library functions such as _bios_serialcom(), 
  650. _bios_printer(), and _bios_keybrd() are available in protected mode.  
  651. Furthermore, protected-mode DOS programs can call BIOS functions from 
  652. separate .ASM modules assembled with MASM, or by using inline assembler,
  653. or the int86() and int86x() functions. 
  654.  
  655.    For example, if our MEM sample program did direct screen writes 
  656. (which we will discuss in more detail later in this chapter), it 
  657. might include initialization code such as the following, which uses 
  658. INT 10h Function 0Fh (Get Video Mode):
  659.  
  660. #include <dos.h>
  661.  
  662. #define GET_VIDEO_MODE      0x0F
  663.  
  664. int video_mode(void)
  665. {
  666.     union REGS r;
  667.     r.h.ah = GET_VIDEO_MODE;
  668.     int86(0x10, &r, &r);
  669.     return r.h.al;
  670. }
  671.  
  672. or, using inline assembler, something like this:
  673.  
  674. int video_mode(void)
  675. {
  676.     _asm mov ah, GET_VIDEO_MODE
  677.     _asm int 10h
  678.     _asm xor ah, ah
  679.     // 2 byte quantity returned in AX
  680. }
  681.  
  682.    Both of these varieties of the video_mode() function run just fine in 
  683. protected mode, because 286|DOS-Extender Lite supports INT 10h (BIOS 
  684. Video) in protected mode.
  685.  
  686.    The following list shows all interrupts and functions that are 
  687. supported in protected mode -- the vast majority of DOS (INT 21h) 
  688. and BIOS (INT 10h, INT 16h, etc.) calls: 
  689.  
  690. INT 10h (BIOS Video)      
  691.   Functions 0 through 1Ch 
  692.  
  693. INT 11h (BIOS Equipment Check)
  694.  
  695. INT 12h (Conventional Memory Size) 
  696.  
  697. INT 14h (BIOS Communications)
  698.   Functions 0 through 5  
  699.  
  700. INT 16h (BIOS Keyboard)
  701.   Functions 0 through 12h 
  702.  
  703. INT 17h (BIOS Printer)
  704.   Functions 0 through 2  
  705.  
  706. INT 1Ah (BIOS Time)
  707.   Functions 0 through 80h
  708.  
  709. INT 21h (MS-DOS Functions)
  710.   Functions 0 through 0Eh
  711.   Functions 19h through 30h
  712.   Functions 32h through 43h
  713.   Function 44h (IOCTL)
  714.     Subfunctions 0, 1, 6, 7, 8, 9, 0Ah, 0Bh, 0Eh, and 0Fh
  715.   Functions 45h through 63h
  716.     Because a request to INT 21h Function 48h (Allocate Memory Block)
  717.     for FFFFh paragraphs can succeed in protected mode, this function 
  718.     should be used only for memory allocation, not to determine the 
  719.     amount of available memory.  Use the DosMemAvail() and DosRealAvail() 
  720.     functions instead for this purpose.
  721.   Functions 66h through 6Ch
  722.  
  723. INT 33h (Microsoft Mouse)
  724.  
  725. -----------------------------------------
  726. 1.5 Compatibility with Industry Standards
  727. -----------------------------------------
  728.  
  729.    We have seen that 286|DOS-Extender Lite (that is, LITE286.EXE) 
  730. manages the interface between your protected-mode program and real-
  731. mode MS-DOS.  At the DOS command line, when you type the name of a 
  732. protected-mode .EXE file, LITE286 puts the machine into protected 
  733. mode and launches your program.  Whenever your program makes DOS or 
  734. BIOS calls from protected mode, 286|DOS-Extender Lite handles them 
  735. and/or passes them down to MS-DOS or the ROM BIOS.  When your program 
  736. exits, 286|DOS-Extender Lite puts the computer back into real mode.
  737.  
  738.    But what if the machine wasn't in real mode to begin with?  Many 
  739. 80386 and 80486 computers, for example, will be running software such 
  740. as Microsoft Windows 3.x (Enhanced mode), Microsoft EMM386, 
  741. Quarterdeck DESQview/386, or Qualitas 386MAX.  When these are loaded, 
  742. MS-DOS is running not in real mode but in a one-megabyte protected 
  743. mode that Intel calls "virtual 8086" mode.  Furthermore, users may be 
  744. running programs that use extended memory, such as VDISK, HIMEM, or 
  745. SMARTDrive.
  746.  
  747.    286|DOS-Extender Lite handles all these situations gracefully.  It 
  748. is compatible with all the PC industry standards for protected mode, 
  749. expanded memory (EMS), and extended memory (XMS).  It supports the 
  750. Virtual Control Program Interface (VCPI) and DOS Protected Mode 
  751. Interface (DPMI).  VCPI, a specification developed jointly by 
  752. Quarterdeck Office Systems and Phar Lap Software, allows EMS 
  753. emulators and DOS extenders to coexist; it is an extension to EMS 
  754. 4.0.  DPMI is a specification whose primary goal is compatibility 
  755. between DOS extenders and DOS multitasking environments; DPMI was 
  756. jointly developed by a committee including Microsoft, Intel, IBM, 
  757. Phar Lap, Quarterdeck, Borland, Lotus, Rational Systems, and other 
  758. companies.  
  759.  
  760.    This means that programs developed with 286|DOS-Extender Lite can 
  761. run in a wide variety of DOS environments.
  762.  
  763.    All this compatibility requires no work from you.  There is no 
  764. configuration or "tune" program to run.  286|DOS-Extender Lite 
  765. automatically configures itself each time it runs.  If run under 
  766. Windows 3.x Enhanced mode, for example, the program will 
  767. automatically get virtual memory with no additional effort.  Or if 
  768. you switch from HIMEM.SYS to QEMM386.SYS, you don't have to 
  769. reconfigure 286|DOS-Extender Lite in any way.  
  770.  
  771. ---------------------------------------------
  772. 1.6 What's So Protected About Protected Mode?
  773. ---------------------------------------------
  774.  
  775.    So far we have described the process of compiling for protected 
  776. mode and running under MS-DOS.  The next step in the development 
  777. cycle is debugging.
  778.  
  779.    Returning to the MEM sample program, for example, suppose we 
  780. forgot to check the return value from malloc().  In the C++ version, 
  781. we could use set_new_handler() to catch failed memory allocations.  
  782. But in C, it's simply a mistake to forget to check the return value 
  783. from malloc():
  784.  
  785. for (allocs = 0; ; allocs++)
  786. {
  787.    p = malloc(1024);
  788.    /* BUG:  not checking return value from malloc!*/
  789.    memset(p, 0, 1024);
  790.    *p = 'x';
  791.    p[1023] = 'y';
  792. }
  793.  
  794.    This horrible code runs without complaint in real mode.  In a 
  795. large model program, its probable effect is to repeatedly bash the 
  796. low-memory interrupt vector table.
  797.  
  798.    What happens in protected mode when malloc() fails and we then try 
  799. to dereference (peek or poke) the resulting NULL pointer?  Instead of 
  800. trashing memory, the program halts with a message like this:
  801.  
  802. Fatal error 286.3330: General protection fault detected.
  803. PID=0001  TID=0001  SID=0001  ERRORCODE=0000
  804. AX=0000  BX=0000  CX=0200  DX=0000  SI=056C  DI=0000  BP=2DCC
  805. CS:IP=014F:0CC5   DS=0157  ES=0000  SS:SP=0157:2DCA   FLAGS=3216
  806.  
  807.    The message "General protection fault detected" is an indication 
  808. that the program has in some way violated the rules of protected 
  809. mode.  These rules prevent writing into code segments, executing data 
  810. segments, reading or writing past the end of a segment, or using a 
  811. segment that doesn't belong to you.  
  812.  
  813.    A general protection violation, or GP fault, shows either a bug in 
  814. your program, or an area that needs to be converted so that it will 
  815. work in protected mode.  In either case, the CPU signals a GP fault 
  816. when your program tries to violate protection.  This makes protected 
  817. mode a superb environment for software development:  the hardware 
  818. will help you find bugs and trouble spots.
  819.  
  820.    In the case of the buggy version of MEM, the message "General 
  821. protection fault detected" message alerts us to a bug that the CPU 
  822. found for us:  the program dereferences pointers without checking if 
  823. malloc() succeeded.  If you examine the register dump produced by 
  824. 286|DOS-Extender Lite, you will note that the ES register is set to 
  825. zero, suggesting we tried to dereference a NULL pointer.  This NULL 
  826. pointer checking is not inserted by the compiler:  the Intel 
  827. processor takes care of it in hardware, making it just one example of 
  828. the many checks that the CPU does in protected mode, with no extra 
  829. work on our part.
  830.  
  831. --------------------------------------------------------
  832. 1.7 Debugging with CVP7 Under MS-DOS 
  833.     (With the 286|DOS-Extender Software Development Kit)
  834. --------------------------------------------------------
  835.  
  836.    As explained at the beginning of this file, 286|DOS-Extender Lite 
  837. does not support debugging.  The 286|DOS-Extender SDK, however, 
  838. supports the powerful debugging features of the protected-mode 
  839. CodeView for Windows (CVW).  (286|DOS-Extender includes a
  840. front-end program for CVW, called CVP7.  That's the executable used
  841. in the following examples.)  We would like to take this opportunity
  842. to illustrate the debugging support available with the
  843. 286|DOS-Extender SDK.  
  844.  
  845.    Let's look at the buggy MEM program.  A protected-mode symbolic
  846. debugger like CVW would let us pinpoint the exact location of the bug
  847. in the MEM program (if we didn't already know it).  
  848.  
  849.    We wouldn't run CVW under Windows, though.  Rather, we would use
  850. 286|DOS-Extender to run CVP7 under MS-DOS, right from the DOS prompt,
  851. without Windows.
  852.  
  853.    Just as 286|DOS-Extender runs your protected-mode applications 
  854. under MS-DOS, it can run protected-mode debuggers such CVP7.
  855. (286|DOS-Extender makes this possible through its support for
  856. dynamic link libraries (DLLs).  This feature is explained in the 
  857. documentation for the 286|DOS-Extender SDK.)  CVP7 runs under
  858. DOS because 286|DOS-Extender supplies Windows-emulation libraries
  859. such as KERNEL.DLL, USER.DLL, and WINDEBUG.DLL.
  860.  
  861.    To make symbolic information available for CVP7 under DOS, we would 
  862. use the Visual C++ -Zi switch:  
  863.  
  864. C:\>cl -Zi -AL -Lp buggymem.c
  865.  
  866. The following section provides specifics for debugging CVW.
  867.  
  868. The Nuts and Bolts of CVW
  869. -------------------------
  870.  
  871.    To debug a protected-mode Microsoft program under DOS, run CVP7,
  872. together with your program, under 286|DOS-Extender:
  873.  
  874. C:\>cvp7 buggymem
  875.  
  876.    
  877.    To fully support all of its features, CodeView requires a little
  878. help to get started.  CVP7 is a "wrapper" program supplied with the
  879. 286|DOS-Extender SDK.  CVP7 changes the video mode, adjusts certain
  880. aspects of CVW's execution environment, filters out dangerous CVW
  881. switches, and (finally) invokes CVW4.EXE
  882.  
  883.    If you are familiar with either CodeView or CodeView for Windows,
  884. you can do source-level debugging of protected-mode programs without
  885. having to learn a new debugger.  If you are not familiar with
  886. CodeView, then using 286|DOS-Extender is an excellent way to get
  887. started. Running CodeView in protected mode helps you to catch bugs
  888. as they happen, by signaling General protection ("GP") faults. This
  889. is in contrast to what occurs in real mode, where programs are
  890. allowed to dereference pointers willy-nilly, often corrupting data
  891. structures in obscure, hard-to-find ways.  However you learn
  892. CodeView, you will want to read Microsoft's documentation to
  893. completely understand each command.
  894.  
  895.    If you've used real-mode CV, but have not done much protected-mode
  896. programming, there's only one thing you should be aware of:  
  897. protected-mode selectors don't look quite the same as the real-mode 
  898. paragraph addresses you're used to.  The first time you use CVP7, you
  899. might find yourself asking "What is this strange value I get back 
  900. from malloc()?"  For example, if the value in ES is 049F, don't 
  901. assume it's a bad value:  that's a typical number for a protected 
  902. mode selector.
  903.  
  904.    Additionally, the switches allowed for real- and protected-mode
  905. CodeView differ.  CV's /R switch, which enables the use of 80386
  906. debug registers, is not allowed with CVP7.  Similarly, /E and /X
  907. (expanded and extended memory support, respectively) are not allowed;
  908. CVP7, running as a 286|DOS-Extended program in protected mode, has no
  909. need for these switches.
  910.  
  911.    One feature of real-mode CodeView that is lacking in CVP7 is
  912. the ability to launch a sub-shell via the "!" command or the "FILE"
  913. menu.
  914.  
  915.    Essentially all the other commands in real-mode CodeView work
  916. exactly as you would expect.  Inside CVP7, you can switch between
  917. displaying source code and object code with F3, you can use F2 to
  918. display the current register set, and you can use F9 and F5 to set a
  919. breakpoint and run your program.  If the HELPFILES environment
  920. variable is set correctly, F1 invokes CodeView's built-in help
  921. system.  Of course you may invoke all functions either by pulling
  922. down menus or by typing in the command window, just like real-mode
  923. CodeView or CodeView for Windows.
  924.  
  925.     When debugging BUGGYMEM, if you type "g", malloc would eventually
  926. run out of memory.  CVP7 would run into our offending code, and place
  927. the cursor on the REP STOSW instruction and display this message:
  928.  
  929. Exception #13
  930.  
  931.    Sure enough, forgetting to check the return value from malloc() 
  932. causes an "exception 13" (also known as an INT 0D, a General 
  933. protection violation, or a GP fault).  The register window would show
  934. that the ES segment register holds a value of zero, indicating that
  935. we're trying to do something with a NULL pointer.
  936.  
  937.    In real mode, the interpretation of 0:0 as a NULL pointer is an 
  938. arbitrary convention, because in real mode, 0:0 is a completely 
  939. legitimate address (it holds the address of the divide-by-zero 
  940. interrupt handler).  Protected mode, however, provides hardware 
  941. support for the notion of a NULL pointer.
  942.  
  943.    Where would we be?  By selecting the CVP7 "Calls" menu, and then
  944. navigating the stack view window, we would see that we're somewhere
  945. inside the call to memset() inside main().  This is not surprising,
  946. given that the call to memset() immediately follows the incorrect
  947. use of malloc().
  948.  
  949.    Can you imagine debugging this code without CodeView?  We hope you
  950. will see from this example how much easier protected-mode programming
  951. can be with the features available in the 286|DOS-Extender SDK.
  952.  
  953.   See Microsoft's Visual C++ CodeView Debugger User's Guide for more
  954. information on using CVW4. 
  955.  
  956.  
  957.  
  958. ------------------------------------
  959. 1.8 What About Direct Screen Writes?
  960. ------------------------------------
  961.  
  962.    So far we have seen that straightforward C or C++ code can be run,
  963. without source-code changes, under Phar Lap's 286|DOS-Extender
  964. Lite.  
  965.  
  966.    But while they allocated large amounts of memory, and showed some 
  967. of the benefits of 286|DOS-Extender Lite and the basic process of 
  968. developing applications with 286|DOS-Extender Lite, our MEMTEST 
  969. sample programs are too simple to illustrate all the issues involved 
  970. in PC software development.  The remainder of this chapter quickly 
  971. examines some of the issues pertinent to Microsoft Visual C++.
  972.  
  973.    Clearly, MEMTEST is not a typical PC program.  For example, it 
  974. uses the portable printf() function to display output.  With the 
  975. exception of programs such as compilers and linkers, however, 
  976. applications for the PC tend to use direct screen writes or other 
  977. low-level code.  How well do such programs run under 286|DOS-Extender 
  978. Lite?
  979.  
  980.    We saw earlier that DOS (INT 21h) and BIOS calls are supported in 
  981. protected mode.  Thus, low-level PC code runs as is under 286|DOS-
  982. Extender Lite.
  983.  
  984.    However, the PC programming interface doesn't consist only of DOS 
  985. and BIOS calls.  The ability to peek and poke absolute memory 
  986. locations is also part of the PC programming interface, and this 
  987. ability normally assumes that the program is running in real mode.
  988.  
  989.    Consider direct screen writes, for example.  These assume that
  990. absolute memory locations such as B8000h can be addressed through 
  991. pointers such as B800:0000.  When a program is manipulating an 
  992. address such as B800:0000, it's really interested in absolute memory 
  993. location B8000h.  Similarly, when it manipulates an address such as 
  994. 0040:006C, it's really interested in absolute memory location 46Ch.  
  995. In protected mode the equivalence of B8000h and B800:0000 no longer 
  996. holds.  It is precisely because protected mode throws out this 
  997. equivalence that it can provide more than one megabyte of memory.
  998.  
  999.    Besides the tiny video_mode() function we saw in the discussion of 
  1000. DOS and BIOS calls, a program that does direct screen writes probably 
  1001. would also include code such as the following, which puts the 
  1002. paragraph address of the text mode video display memory (0xB000 or 
  1003. 0xB800) into a global variable.  This code also uses the _MK_FP() 
  1004. macro from DOS.H in to create a far pointer to B000:0000 or to B800:0000:
  1005.  
  1006. unsigned short get_vid_mem(void)
  1007. {
  1008.     int vmode = video_mode();
  1009.     unsigned short seg;
  1010.  
  1011.     if (vmode == 7) /* monochrome */
  1012.     seg = 0xB000;
  1013.     else if ((vmode == 2) || (vmode == 3))
  1014.     seg = 0xB800;
  1015.     else
  1016.     return 0;
  1017.  
  1018.     return seg;
  1019. }
  1020.  
  1021. static BYTE far *vid_mem;   /* use far pointer */
  1022.  
  1023. video_init(void)
  1024. {
  1025.     vid_mem = MK_FP(get_vid_mem(), 0);
  1026. }
  1027.  
  1028. #define SCR(y,x)    (((y) * 160) + ((x) << 1))
  1029.  
  1030. void wrt_str(int y, int x, ATTRIB attr, unsigned char *p)
  1031. {
  1032.     BYTE far *v = vid_mem + SCR(y, x);
  1033.     while (*p)
  1034.     {
  1035.     *v++ = *p++;
  1036.     *v++ = attr;
  1037.     }
  1038. }
  1039.  
  1040.    But if we now try to run a program that includes this code under 
  1041. 286|DOS-Extender Lite, we get another one of those "General 
  1042. protection fault detected" messages, just as if our code contained a 
  1043. bug:
  1044.  
  1045. C:\>cl -AL -Lp memtest3.c
  1046.  
  1047. C:\>bind286 memtest3
  1048.  
  1049. C:\>memtest3
  1050. Fatal error 286.3330:  General protection fault detected.
  1051. PID=0001  TID=0001  SID=0001  ERRORCODE=B800
  1052. AX=0041  BX=0098  CX=01ED  DX=0000  SI=042E  DI=042E  BP=0F08
  1053. CS:IP=022F:01FD   DS=024F  ES=024F  SS:SP=024F:0F06   FLAGS=3206
  1054.  
  1055.    Our code doesn't contain a bug.  However, ERRORCODE=B800 suggests 
  1056. that simply loading the paragraph address of the video display memory 
  1057. into a segment register such as DS or ES isn't going to work in 
  1058. protected mode.
  1059.  
  1060.    It's extremely simple to get this code working in protected mode. 
  1061. To write directly to video memory from protected mode, you need a 
  1062. function call that "maps" absolute memory locations into the address 
  1063. space of your protected-mode program.  The only function that needs 
  1064. to be changed is get_vid_mem(), so that instead of returning 0xB000 
  1065. or 0xB800, it returns a protected-mode selector that maps one of 
  1066. these real-mode paragraph addresses.  To do this, we use the Phar Lap
  1067. API (PHAPI) function DosMapRealSeg(), whose prototype is in PHAPI.H.
  1068.  
  1069. #ifdef DOSX286
  1070. // symbol DOSX286 must be specified on CL command line
  1071. #include <phapi.h>
  1072. #endif
  1073.  
  1074. unsigned short get_vid_mem(void)
  1075. {
  1076.     int vmode = video_mode();
  1077.     unsigned seg;
  1078.  
  1079.     if (vmode == 7)
  1080.     seg = 0xB000;
  1081.     else if ((vmode == 2) || (vmode == 3))
  1082.     seg = 0xB800;
  1083.     else
  1084.     return 0;
  1085.  
  1086.  
  1087. #ifdef DOSX286
  1088. {
  1089.     unsigned short sel;  
  1090.     /*
  1091.        DosMapRealSeg() takes a real mode paragraph address
  1092.        and a count of bytes, and gives back a selector that
  1093.        can be used to address the memory from protected 
  1094.        mode.  Like all PHAPI functions, DosMapRealSeg()
  1095.        returns 0 for success, or a non-zero error code.  Any 
  1096.        other information (such as the selector we're 
  1097.        interested in) is returned via parameters.
  1098.     */
  1099.     if (DosMapRealSeg(seg, (long) 25*80*2, &sel) == 0)
  1100.     return sel;
  1101.     else
  1102.     return 0;
  1103. }
  1104. #endif
  1105.  
  1106.     return seg;
  1107. }
  1108.  
  1109.    In the larger program from which this code was extracted, this was
  1110. the only source-code change needed to get the program running under 
  1111. 286|DOS-Extender Lite.  All the actual direct screen writes ran in 
  1112. protected mode without modification.  Most graphics code can be 
  1113. ported to 286|DOS-Extender Lite in the same way, simply by changing 
  1114. the function that returns the segment number of video memory, to use 
  1115. DosMapRealSeg (0xA000, ...).  Since the PHAPI-specific or
  1116. protected-mode code is inside an #ifdef, the same code can be
  1117. compiled for real mode.  (Note that you must specify -DDOSX286 on the
  1118. CL command line.)
  1119.  
  1120.    When the program is finished with the selector to video memory, it 
  1121. should free it by calling DosFreeSeg():
  1122.  
  1123. DosFreeSeg(FP_SEG(vid_mem));    // segment of far pointer
  1124.  
  1125.    That's all it takes to get direct screen writes working in 
  1126. protected mode.
  1127.  
  1128. -----------
  1129. 1.9 Summary
  1130. -----------
  1131.  
  1132.    Any given program probably will require only a few PHAPI
  1133. functions; the vast majority of your DOS code will work "as is" under
  1134. 286|DOS-Extender Lite.  You can preserve your investment and your
  1135. customer's investment in MS-DOS.
  1136.  
  1137.    286|DOS-Extender Lite turns Microsoft Visual C++ into a toolkit for
  1138. protected-mode DOS development.  Just by adding the -Lp switch to CL,
  1139. your Visual C++ programs break the 640K barrier.
  1140.  
  1141.  
  1142. ------------------------------------------------
  1143. Chapter 2
  1144. Using 286|DOS-Extender with Microsoft Visual C++
  1145. ------------------------------------------------
  1146.  
  1147.    The easiest way to build Microsoft Visual C++ protected-mode programs
  1148. is to use the CL command, with which you are probably already
  1149. familiar:  
  1150.  
  1151. C:\TEST> cl -Lp -AL memtest.c
  1152.  
  1153. C:\TEST> bind286 memtest
  1154.  
  1155. C:\TEST> memtest
  1156.  
  1157.    The -Lp switch instructs CL to link against the protected-mode
  1158. library LLIBCEP.LIB, which should already be installed in
  1159. \LITE286\MSVC\LIB. The -AL switch instructs CL to create a
  1160. large-model program.  Using large model is not a requirement to run
  1161. in protected mode, but it offers the best combination of speed and 
  1162. data-segment size under most conditions.  If your program can fit
  1163. into small model, however, you will obtain better performance by 
  1164. running in real mode.
  1165.  
  1166.    Protected-mode programs are linked against LLIBCEP.LIB and PHAPI.LIB,
  1167. both of which should be in the sub-directory MSVC\LIB of your LITE286
  1168. directory.  (If LLIBCEP.LIB is not present, please review the installation
  1169. instructions, and re-run MKLIB.BAT.)
  1170.  
  1171.    In order for CL to find the 286|DOS-Extender Lite libraries,
  1172. include files, and programs, you must edit three of your environment
  1173. variables.  The LIB environment variable specifies a list of
  1174. directories in which to search for libraries.  The INCLUDE
  1175. environment variable lists the directories containing include files. 
  1176. You must add the LITE286 subdirectory BIN to you PATH variable.  A
  1177. typical set of environment variables would include:
  1178.  
  1179.     C:\> set PATH=c:\;c:\dos;c:\bin;c:\msvc\bin;c:\lite286\bin
  1180.     C:\> set LIB=c:\msvc\lib;c:\lite286\msvc\lib
  1181.     C:\> set INCLUDE=c:\msvc\include;c:\lite286\inc
  1182.  
  1183.  
  1184.  
  1185. ---------------------------------------------------
  1186. 2.1 Differences Between Real- and Protected-Mode CL
  1187. ---------------------------------------------------
  1188.  
  1189.    With 286|DOS-Extender Lite, programming for protected mode is
  1190. surprisingly similar to programming for real mode.  This includes,
  1191. for instance, providing switches to CL.  There are, however, slight
  1192. differences in the command line used to build a protected-mode
  1193. program:
  1194.  
  1195.  The -AH (huge model) and -AT (tiny, or COM model) switches
  1196.   are not supported in protected mode.
  1197.  
  1198.  You may not build p-code programs.  This means you will not use
  1199.   the -Of -Ov -Oq -Gn -Gp and -NQ switches in building protected-
  1200.   mode programs.
  1201.  
  1202.  The various -G switches that specify Windows entry/exit code
  1203.   generation should not be used when compiling 286|DOS-Extender Lite
  1204.   programs.
  1205.  
  1206.  
  1207.  
  1208. -------------------
  1209. 2.2 Linking by Hand
  1210. -------------------
  1211.  
  1212.    Ordinarily, you would use CL to build protected-mode programs.  CL
  1213. invokes the various compiler passes, and then optionally invokes the
  1214. linker.  You may want, however, to run the Microsoft C/C++ linker,
  1215. LINK.EXE, by hand.  If you want to replicate exactly the action of
  1216. CL, the command line is fairly simple:
  1217.  
  1218. C:\> cl -c -AL hand.c
  1219.  
  1220. C:\> link hand.obj,hand.exe/noi,,/nod:llibce.lib llibcep.lib; 
  1221.  
  1222. C:\> bind286 hand
  1223.  
  1224.  
  1225.    The following sections briefly describe each switch, statement, and
  1226. file.  This information is necessary only if you are linking with
  1227. LINK rather than using CL.
  1228.  
  1229.  
  1230. CL Switches
  1231. ------------
  1232.  
  1233.  -c (compile only):  This switch instructs CL to create on object
  1234.   file, but to not run the linker.  The object file that you link
  1235.   against might be created by CL, MASM, or any other tool compatible
  1236.   with the Visual C++ linker and run-time libraries.
  1237.  
  1238.  -AL (large model):  While not strictly required, large model and
  1239.   protected-mode programming go hand in hand.  Real-mode DOS provides
  1240.   a more space-efficient execution environment for small model than
  1241.   does 286|DOS-Extender Lite. 
  1242.  
  1243.  -Lp (protected mode):  Note that this switch is absent from the
  1244.   CL command line.  Since CL is not running LINK, -Lp is not
  1245.   required.
  1246.  
  1247.  
  1248. LINK Switches
  1249. -------------
  1250.  
  1251.    Refer to the Microsoft Visual C++ Command-Line Utilities User's
  1252. Guide for information on LINK command line specifiers.
  1253.  
  1254. The following sample command line links a protected-mode program:
  1255.  
  1256. C:\> link hand.obj,hand.exe/noi,nul,/nod:llibce.lib llibcep.lib; 
  1257.  
  1258.  hand.obj (object list):  All the names that precede the first
  1259.   comma comprise a list of objects to be included in the resulting
  1260.   executable image.  If any file name in this list does not have
  1261.   an extension, .OBJ is assumed.
  1262.  
  1263.  hand.exe (executable image): The file name in this position specifies
  1264.   the name of the resulting image.  The default extension here is
  1265.   .EXE.
  1266.  
  1267.  /noi (no ignore case):  This switch determines the case-significance
  1268.   of external symbols.
  1269.  
  1270.  nul (map file):  LINK can optionally generate a map file.  By naming
  1271.   the NUL device file NUL.MAP, no file is generated.
  1272.  
  1273.  /nod:llibce.lib (no default search):  LINK will search, by default,
  1274.   the set of library names embedded in the object files.  /nod:llibce
  1275.   instructs LINK to avoid searching that library.
  1276.  
  1277.  llibcep.lib (library list):  LLIBCEP is the protected-mode library
  1278.   created during the installation process.  It completely replaces,
  1279.   and is built from, LLIBCE.LIB.
  1280.  
  1281.   For more information about each of the CL and LINK options, please
  1282. consult the Command-Line Utilities User's Guide.
  1283.  
  1284.  
  1285.  
  1286. ------------------------------------------------
  1287. Chapter 3
  1288. Running Protected Mode Applications Under MS-DOS
  1289. ------------------------------------------------
  1290.  
  1291.  
  1292.    So far we have seen that a program produced by CL can be run 
  1293. directly from the DOS command line simply by typing its name, like 
  1294. any other DOS program.  286|DOS-Extender Lite programs can also be 
  1295. run under DOS without a command line, using any of the many 
  1296. alternatives to COMMAND.COM such as the DOSSHELL in DOS 5.
  1297.  
  1298.    By default, a protected-mode program modified by BIND286 includes
  1299. a real-mode "stub" program called GORUN286.  When one of these programs
  1300. is started under DOS, an embedded copy of GORUN286.EXE actually runs
  1301. initially.  GORUN286 is called a stub because its sole job is to restart
  1302. the program under 286|DOS-Extender Lite (LITE286.EXE).  In other words,
  1303. if PHOO.C is compiled with:
  1304.  
  1305. C:\>cl -AL -Lp phoo.c 
  1306.  
  1307. C:\>bind286 phoo
  1308.  
  1309. then running the program by typing its name:
  1310.  
  1311. C:\TEST>phoo
  1312.  
  1313. is equivalent to typing LITE286 followed by the name of the program:
  1314.  
  1315. C:\TEST>lite286 phoo
  1316.  
  1317.    This seems like no big deal:  after all, we've saved only seven 
  1318. letters and a space.  However, by eliminating the need to type those 
  1319. eight keystrokes, we have effectively hidden the DOS extender, and 
  1320. created the useful illusion that MS-DOS is an operating system that 
  1321. runs protected-mode executables.
  1322.  
  1323.    Though usually hidden, the key components of 286|DOS-Extender Lite
  1324. are LITE286.EXE, which loads 16-bit protected-mode .EXE files under 
  1325. MS-DOS, and DOSCALLS.DLL, a dynamic link library (DLL) which contains
  1326. some of the functions used by the protected-mode startup code and
  1327. run-time library.  The directory containing LITE286.EXE, for example
  1328. C:\LITE286\BIN, must be located somewhere on the DOS file-search path
  1329. when you start an executable produced by BIND286.
  1330.  
  1331.    LITE286.EXE puts the computer into protected mode and loads your 
  1332. protected-mode program.  Whenever your program makes DOS (INT 21h) or 
  1333. BIOS requests from protected mode, the DOS extender quickly and 
  1334. invisibly does the work of sending the requests off to MS-DOS or the 
  1335. ROM BIOS, which are running in real mode.  Thus, 286|DOS-Extender 
  1336. Lite is 100% compatible with DOS:  it's not an emulation, but 
  1337. literally an extension of DOS.
  1338.  
  1339. -----------------
  1340. 3.1 Compatibility
  1341. -----------------
  1342.  
  1343.    There is another side to extending MS-DOS.  One of the key 
  1344. services of 286|DOS-Extender Lite, in contrast to any "roll your own" 
  1345. approach to protected mode, is compatibility.
  1346.  
  1347.    We've been assuming that the computer is in real mode, that 
  1348. LITE286 switches it into protected mode, installs some interrupt 
  1349. handlers, spawns your protected-mode program and, when your program 
  1350. completes, puts the computer back into real mode.  
  1351.  
  1352.    But that would involve a simplistic view of the PC world in the 
  1353. 1990s.  Most users of 80386 and 80486 machines are employing memory 
  1354. managers such as EMM386, 386MAX and QEMM, or multitasking window 
  1355. systems such as DESQview or Microsoft Windows 3.x.  When such 
  1356. programs are running, the computer is not in real mode; it's running 
  1357. in a one-megabyte protected mode called virtual 8086 mode.  The 
  1358. assumption that a DOS extender can simply switch the machine from 
  1359. real mode to protected mode does not take into account the fact that 
  1360. many machines won't be in real mode.  Furthermore, users may be 
  1361. running programs such as VDISK or HIMEM or SMARTDrive, which use 
  1362. extended memory.  LITE286 must be able to run your protected-mode 
  1363. program under DOS, yet be highly compatible with any other memory-
  1364. management software a user might be running.  
  1365.  
  1366.    One of the key questions about any protected-mode MS-DOS solution 
  1367. is how compatible it is with all this different software.  Is it 
  1368. compatible with EMM386, 386MAX, and QEMM?  Does it run in a window 
  1369. inside DESQview/386 or Microsoft Windows 3.x Enhanced mode?  What if 
  1370. the machine is already running an expanded memory (EMS) or extended 
  1371. memory (XMS) manager?  What if there are VDISKs or a SMARTDrive?  What 
  1372. if your protected-mode program has been spawned from within a 
  1373. 386|DOS-Extender program such as IBM Interleaf Publisher, 
  1374. Mathematica, or AutoCAD/386?
  1375.  
  1376.    286|DOS-Extender Lite handles all these situations gracefully.  It 
  1377. is compatible with all the PC industry standards for protected mode 
  1378. and extended memory.  In particular, it supports the Virtual Control 
  1379. Program Interface (VCPI) and DOS Protected Mode Interface (DPMI).  
  1380. VCPI is a specification developed jointly by Quarterdeck Office 
  1381. Systems and Phar Lap Software that allows EMS emulators and DOS 
  1382. extenders to coexist; it is an extension to EMS 4.0.  DPMI is a 
  1383. specification whose primary goal is compatibility between DOS 
  1384. extenders and DOS multitasking environments; DPMI was jointly 
  1385. developed by a committee including Microsoft, Intel, IBM, Phar Lap, 
  1386. Quarterdeck, Borland, Lotus, and other companies.  For more details 
  1387. on VCPI and DPMI, plus the old INT 15h and XMS standards, we 
  1388. recommend the book Extending DOS, Second Edition, edited by Ray Duncan
  1389. (Reading MA:  Addison-Wesley, 1991, 538 pp., ISBN 0-201-56798-9).
  1390.  
  1391.    To summarize, programs developed with 286|DOS-Extender Lite 
  1392. can run in a wide variety of environments.  LITE286 takes care of all 
  1393. the messy details of compatibility.  There is no separate 
  1394. configuration or "tune" program to run.
  1395.  
  1396. ------------------------
  1397. 3.2 LITE286 Requirements
  1398. ------------------------
  1399.  
  1400.    LITE286 does have a few modest requirements:
  1401.  
  1402.  If an expanded memory (EMS) handler is installed, it must follow 
  1403.   the EMS 4.0 and VCPI specifications.  Almost all EMS managers 
  1404.   shipping today are VCPI-compatible; if yours isn't, contact the 
  1405.   manufacturer about upgrading to a new version.  (The exception is 
  1406.   IBM PC-DOS 4.01, which has an EMS manager that is not VCPI-
  1407.   compatible.)
  1408.  
  1409.  Microsoft's EMM386, included with DOS 5.0 and Windows 3.x, is 
  1410.   VCPI-compatible, and can therefore be used with 286|DOS-Extender 
  1411.   Lite.  However, the EMM386 NOEMS switch effectively disables VCPI 
  1412.   support, and therefore cannot be used.  We recommend adding the
  1413.   switch FRAME=NONE, which uses no more Upper Memory Blocks than NOEMS,
  1414.   but which does allow VCPI-compatible clients to run.
  1415.  
  1416.  If an extended memory (XMS) manager such as HIMEM.SYS is 
  1417.   installed, we recommend setting a fairly large handle count.  For 
  1418.   example: 
  1419.  
  1420.   DEVICE=C:\WIN30\HIMEM.SYS /NUMHANDLES=127
  1421.  
  1422.  LITE286 will not run in the DOS compatibility box of OS/2 1.x, 
  1423.   because that environment is limited to a maximum of 640K.  However, 
  1424.   it will run in the DOS compatibility boxes of OS/2 2.0, which 
  1425.   provide DPMI support.
  1426.  
  1427.    One important word of warning:  Even though you don't have to 
  1428. explicitly type "LITE286" to run an executable produced by BIND286 
  1429. under MS-DOS, the LITE286.EXE file is necessary.  The directory 
  1430. containing both this file and DOSCALLS.DLL (for example 
  1431. C:\LITE286\BIN) must be located somewhere on the DOS file-search 
  1432. path.  If GORUN286 cannot find LITE286.EXE, it will display the 
  1433. message:
  1434.  
  1435. This program requires Phar Lap's 286|DOS-Extender
  1436.  
  1437.    If LITE286.EXE cannot find DOSCALLS.DLL (which should be located 
  1438. in the same directory as LITE286.EXE), it will display the message:
  1439.  
  1440. Fatal error 286.2190: Load program failed -- File not found -- DOSCALLS.DLL.
  1441.  
  1442.    If you receive either of these messages when trying to run a
  1443. 286|DOS-Extender Lite executable, ensure that your path is correct. 
  1444. For example:
  1445.  
  1446. C:\TEST>set path=c:\bin;c:\LITE286\bin;c:\dos
  1447.  
  1448.    Note that neither LITE286.EXE nor the 286|DOS-Extender Lite DLLs 
  1449. can be shipped to end-users.  In order to prepare programs for 
  1450. redistribution, you must purchase the 286|DOS-Extender Run-Time Kit 
  1451. (RTK), which lets you bind 286|DOS-Extender plus any necessary DLLS 
  1452. into your application (an application may consist of multiple
  1453. executable files, all of which are covered by a single license 
  1454. agreement).
  1455.  
  1456.    With these details out of the way, protected-mode programs will 
  1457. run under MS-DOS.
  1458.  
  1459. ------------------
  1460. 3.3 Error Messages
  1461. ------------------
  1462.  
  1463.    The most common fatal error messages are described briefly in the 
  1464. following sample sessions.
  1465.  
  1466. C:\TEST>LITE286 phoobar
  1467. Fatal error 286.2190:  Load program failed -- File not found -- phoobar.exe.
  1468.  
  1469.    There is no program named PHOOBAR.EXE.  Either you have misspelled 
  1470. the program's name, or it is not located on the path.
  1471.  
  1472.  
  1473. C:\DOS>LITE286 bad
  1474. Fatal error 286.3330:  General protection fault detected.
  1475. PID=0001  TID=0001  SID=0001  ERRORCODE=0000
  1476. AX=0004  BX=0000  CX=0019  DX=008B  SI=00DA  DI=00DA  BP=0BE2
  1477. CS:IP=0237:001D   DS=024F  ES=0000  SS:SP=024F:0BDE   FLAGS=3246
  1478.  
  1479.    Your program violated a rule of protected mode, causing a General 
  1480. protection fault (GP fault).  There is a bug in your program, or a 
  1481. piece of code which must be modified before it can be run in 
  1482. protected mode, or you have unintentionally included real-mode code 
  1483. (for example, real-mode libraries) in the program.
  1484.  
  1485.  
  1486. C:\DOS>LITE286 mem
  1487. Fatal error 286.1000:  System does not have an 80286 (or newer) processor.
  1488.  
  1489.    You have attempted to run a 286|DOS-Extender Lite program on a 
  1490. machine which does not have an 80286 or later processor.
  1491.  
  1492.  
  1493. C:\DOS>LITE286 mem
  1494. Fatal error 286.1020:  This program requires VCPI or DPMI in V86 mode.
  1495.  
  1496.    A program, probably an expanded-memory manager, has put the 
  1497. computer into virtual 8086 mode, but the program does not support 
  1498. either the Virtual Control Program Interface (VCPI) or the DOS 
  1499. Protected Mode Interface (DPMI).  Contact the manufacturer about 
  1500. upgrading to a later version which does support VCPI or DPMI, or 
  1501. remove the program.  Some of the expanded memory simulators with 
  1502. which LITE286 works are:
  1503.  
  1504.      QEMM 4.1 or later (Quarterdeck)
  1505.      386MAX 4.02 or later (Qualitas)
  1506.      CEMM 4.02 or later (COMPAQ)
  1507.      EMM386 (DOS 5.0, Microsoft Windows 3.x versions)
  1508.  
  1509.  
  1510. --------------------------------
  1511. 3.4 LITE286 Command Line Options
  1512. --------------------------------
  1513.  
  1514. What if you want to run your 286|DOS-Extender Lite program on
  1515. hardware that is not 100% IBM-compatible?  What if you need to reserve
  1516. a certain amount of extended memory because some other program 
  1517. doesn't adhere to any of the PC industry's standards for extended
  1518. memory usage?  What if your program does a large amount of file I/O
  1519. and you want LITE286 to use a larger conventional-memory "transfer
  1520. buffer" for DOS and BIOS calls?
  1521.  
  1522.    LITE286 has a number of command line options which can be used in 
  1523. (frankly, rather rare) situations such as these.  If you type 
  1524. LITE286 -help on the DOS command line, a list of these command line 
  1525. options is displayed (the following display is not complete):
  1526.  
  1527. C:\DOS>LITE286 -help
  1528. 286|DOS-Extender Lite: 2.5 -- Copyright (C) 1986-92 Phar Lap Software, Inc.
  1529.       LITE286  switch(es) filename
  1530.  
  1531.      -EXTLIMIT n       Set max. bytes of extended memory used
  1532.      -EXTLOW addr      Set lowest extended memory address used
  1533.      -EXTHIGH addr     Set highest extended memory address used
  1534.      -ISTKSIZE n       Set size of interrupt stacks (1K blocks)
  1535.      -LDTSIZE n        Set number of LDT entries
  1536.      -NISTACK n        Set number of interrupt stacks
  1537.      -REALIMIT n       Set max. bytes of real memory used
  1538.      -SWITCH name      Select mode switch method (AUTO, AT, 386,
  1539.                 SURESWITCH, PS2, INBOARD, 6300, ACER,
  1540.                 VECTRA, VCPI, or FAST)
  1541.      -SWITCHFILE name  Select external switching .BIN file
  1542.      -XFERSIZE n       Set size of transfer buffer (1K blocks)
  1543.  
  1544.    Any LITE286 switch can be set on the DOS command line.  For 
  1545. example, the following runs MYPROG.EXE with a transfer buffer of 16 
  1546. KB:
  1547.  
  1548. C:\TEST>LITE286 -xfersize 16 myprog
  1549.  
  1550.    However, since normally we don't bother typing "LITE286" to run a 
  1551. program produced by BIND286, we need another way to set LITE286 
  1552. command-line options.  For example, the following is equivalent to 
  1553. the LITE286 command line just shown:
  1554.  
  1555. C:\TEST>set RUN286=-xfersize 16
  1556.  
  1557. C:\TEST>myprog
  1558.  
  1559.    Of course, you must have sufficient room in your DOS environment.  
  1560. If you receive an "Out of environment space" message, you need a 
  1561. larger DOS environment.  Add a line such as the following to your 
  1562. CONFIG.SYS file, and reboot:
  1563.  
  1564. SHELL=c:\dos\command.com /p /e:512
  1565.  
  1566.    Note that only LITE286 switches are processed in the LITE286 or 
  1567. application-specific DOS extender environment variables, or in the 
  1568. "configuration block" in an executable.  Any command line switches 
  1569. specific to your program must be handled by your program in the usual 
  1570. way.
  1571.  
  1572. ------------------------------------------------------
  1573. 3.5 The Phar Lap Application Program Interface (PHAPI)
  1574. ------------------------------------------------------
  1575.  
  1576.    The full-blown 286|DOS-Extender SDK comes with extensive support
  1577. for the Phar Lap Application Program Interface (PHAPI), which
  1578. provides protected-mode DOS programs with a set of services in the
  1579. following areas:
  1580.  
  1581.    Creating and changing protected-mode selectors
  1582.  
  1583.    Communication between real and protected mode
  1584.  
  1585.    Dynamic Link Library (DLL) support
  1586.  
  1587.    Interrupt and exception handling
  1588.  
  1589.    DOS memory management
  1590.  
  1591.    80386 paging functions
  1592.  
  1593.  
  1594.    The following functions are part of PHAPI; prototypes for these
  1595. functions appear in PHAPI.H:
  1596.  
  1597. Selector and Memory Management
  1598. ------------------------------
  1599.  
  1600. DosAllocHuge            Allocate huge (> 64k) segment
  1601. DosAllocRealSeg         Allocate segment in conventional memory
  1602. DosAllocSeg             Allocate segment
  1603. DosCreateCSAlias        Create code alias to a data segment
  1604. DosCreateDSAlias        Create data alias to a code segment
  1605. DosFreeSeg              Free segment
  1606. DosGetBIOSSeg           Get selector to the BIOS data area
  1607. DosGetHugeShift         Get selector increment for huge segments
  1608. DosGetPhysAddr          Convert selector:offset to physical address
  1609. DosGetSegDesc           Get segment descriptor
  1610. DosLockSegPages         Lock pages of a segment
  1611. DosMapLinSeg            Map linear address
  1612. DosMapRealSeg           Map real-mode address into protected mode
  1613. DosMapPhysSeg           Map physical address
  1614. DosMemAvail             Get amount of available extended memory
  1615. DosRealAvail            Get amount of available conventional memory
  1616. DosReallocHuge          Resize a huge segment
  1617. DosReallocSeg           Resize a segment
  1618. DosSetSegAttrib         Set access rights of a segment
  1619. DosUnlockSegPages       Unlock pages of a segment
  1620. DosVerifyAccess         Verify segment for read, write, execute
  1621.  
  1622. Interrupts and Exceptions
  1623. -------------------------
  1624.  
  1625. DosChainToProtIntr      Chain to a protected-mode interrupt handler
  1626. DosChainToRealIntr      Chain to a real-mode interrupt handler
  1627. DosGetExceptionHandler  Get exception (e.g., GP fault) handler
  1628. DosGetProtVec           Get protected-mode interrupt vector
  1629. DosGetRealProtVec       Get real- and protected-mode interrupt vector
  1630. DosGetRealVec           Get real-mode interrupt vector
  1631. DosIsProtIntr           Test if interrupt is from protected mode
  1632. DosIsRealIntr           Test if interrupt is from real mode
  1633. DosProtIntr             Generate a protected-mode interrupt from real mode
  1634. DosRealIntr             Generate a real-mode interrupt from protected mode
  1635. DosSetExceptionHandler  Set exception handler
  1636. DosSetPassToProtVec     Set interrupt vector to go to protected-mode handler
  1637. DosSetPassToRealVec     Set interrupt vector to go to real-mode handler
  1638. DosSetProtVec           Set protected-mode interrupt vector
  1639. DosSetRealProtVec       Set real- and protected-mode interrupt vectors
  1640. DosSetRealVec           Set real-mode interrupt vector
  1641. DosVProtIntr            Generate a protected-mode interrupt from real mode
  1642. DosVRealIntr            Generate a real-mode interrupt from protected mode
  1643.  
  1644. Mixing Real- and Protected-Mode Code
  1645. ------------------------------------
  1646.  
  1647. DosFreeProtStack        Free a protected-mode stack
  1648. DosFreeRealStack        Free a real-mode stack
  1649. DosProtFarCall          Call a protected-mode function from real mode
  1650. DosProtFarJump          Jump to protected mode from real mode
  1651. DosProtToReal           Convert a protected- to a real-mode address
  1652. DosRealFarCall          Call a real-mode function from protected mode
  1653. DosRealFarJump          Jump to real-mode from protected mode
  1654. DosRealToProt           Convert a real- to a protected-mode address
  1655. DosVProtFarCall         Call a protected-mode function from real mode
  1656. DosVProtFarJump         Jump to protected mode from real mode
  1657. DosVRealFarCall         Call a real-mode function from protected mode
  1658. DosVRealFarJump         Jump to real-mode from protected mode
  1659.  
  1660. Dynamic Linking
  1661. ---------------
  1662.  
  1663. DosEnumMod              Enumerate the currently-loaded modules
  1664. DosEnumProc             Enumerate the functions in a DLL
  1665. DosFreeModule           Free a DLL
  1666. DosGetModHandle         Get the module handle of a DLL
  1667. DosGetModName           Get the filename of a DLL
  1668. DosGetProcAddr          Get the selector:offset of a function in a DLL
  1669. DosGetRealProcAddr      Get the real-mode address of a function in a DLL
  1670. DosLoadModule           Load a DLL
  1671. DosSetProcAddr          Set the address of a function in a DLL
  1672.  
  1673. Miscellaneous
  1674. -------------
  1675.  
  1676. DosExecPgm              Start a new protected- or real-mode process
  1677. DosExit                 Exit from a program
  1678. DosExitList             Register an exit routine
  1679. DosGetMachineMode       Get processor mode
  1680. DosIsPharLap            Test if running under 286|DOS-Extender
  1681. DosPTrace               Debug a child program
  1682.  
  1683. ---------------
  1684. Further Reading
  1685. ---------------
  1686.  
  1687. Developers using 286|DOS-Extender Lite may be interested in the
  1688. following books:
  1689.  
  1690. The second edition of the book Extending DOS, edited by Ray Duncan. 
  1691. Chapter 4, on 16-bit protected-mode DOS extenders, contains over 70 
  1692. pages devoted largely to 286|DOS-Extender.  Other chapters describe
  1693. 32-bit protected-mode DOS extenders, the VCPI and DPMI specifications,
  1694. and other topics in protected-mode DOS programming:
  1695.  
  1696. Ray Duncan et al., Extending DOS: A Programmer's Guide to Protected-
  1697. Mode DOS, Second Edition, Reading MA: Addison-Wesley, 1991, 538 pp., 
  1698. ISBN 0-201-56798-9.  
  1699.  
  1700. Al Williams' survey of DOS Extenders, DOS and Windows Protected Mode.
  1701. This book describes nearly every 16- and 32-bit DOS extender available,
  1702. with working examples of how to write programs for each one.  It also
  1703. includes a previous version of 286|DOS-Extender Lite.
  1704.  
  1705. Al Williams, DOS and Protected Mode: Programming with DOS Extenders in C,
  1706. Reading MA: Addison-Wesley, 1993, 503 pp., ISBN 0-201-63218-7.
  1707.