home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / memory / xmsif / xmstest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-14  |  52.8 KB  |  1,191 lines

  1. /***************************************************************************
  2. *   xmstest.c                                                              *
  3. *   MODULE:  XMSIF                                                         *
  4. *   OS:      DOS                                                           *
  5. *   VERSION: 1.2                                                           *
  6. *   DATE:    11/14/92                                                      *
  7. *                                                                          *
  8. *   Copyright (c) 1992 James W. Birdsall. All Rights Reserved.             *
  9. *                                                                          *
  10. *   Requires xmsif.h, testutil.h, and xmstest.h to compile.                *
  11. *   Compiles under Borland C++ 2.0, Turbo C 2.0, MSC 6.00A, MSC/C++ 7.0.   *
  12. *                                                                          *
  13. *   Regression test and example for XMSIF.                                 *
  14. *                                                                          *
  15. *   This file is part one of the regression tester and example for XMSIF.  *
  16. *   The other parts are named EMSTEST2.C and EMSTEST3.C. All three parts   *
  17. *   must be compiled and linked together along with the appropriate XMSIF  *
  18. *   library to produce the tester executable. This program compiles under  *
  19. *   tiny, small, medium, compact, large, and huge models.                  *
  20. *                                                                          *
  21. *   To use this tester: in general, just run it. Depending on what XMS     *
  22. *   driver you have, you may need to use the "-q" option. HIMEM.SYS does   *
  23. *   not require this option; QEMM 5.1* does; I don't know about other XMS  *
  24. *   drivers. If you haven't used it and should, or should use it and       *
  25. *   haven't, the tester can detect this and will abort with a message      *
  26. *   suggesting you do the opposite of whatever you did. For more detail on *
  27. *   what this option actually does, see below. The tester produces output  *
  28. *   on stdout. It performs 70+ tests, depending on the exact configuration *
  29. *   of your system, and parts of it run quite fast. If you want to read    *
  30. *   all the output, you should redirect the output to a file (but first    *
  31. *   you should probably run it straight to get an idea of how long it      *
  32. *   takes on your machine). If you just want to see whether the tests all  *
  33. *   pass, just run it -- if a test fails, execution aborts immediately.    *
  34. *                                                                          *
  35. *   Certain types of failure may cause XMSTEST to not deallocate memory    *
  36. *   that it has allocated. This should only occur if the library itself is *
  37. *   malfunctioning (which should never happen to you, only to me!) or if   *
  38. *   you are trying a different compiler or unsupported memory model and    *
  39. *   the compiler and library are therefore not communicating properly. It  *
  40. *   may also happen if you press control-break.                            *
  41. *                                                                          *
  42. *                                                                          *
  43. *   The actions XMSTEST takes may be broken down into two parts: EMB tests *
  44. *   and UMB tests. In the first part, it tests the XMM* functions which    *
  45. *   operate on extended memory blocks (EMBs). In the second part, it tests *
  46. *   the UMB* functions which operate on upper memory blocks (UMBs). Before *
  47. *   doing any of this, it tries to initialize XMSIF, which checks for the  *
  48. *   presence of an XMS driver, and aborts if there isn't one. Then it      *
  49. *   starts the first part, performing various preliminary tests on EMBs.   *
  50. *   If it determines that there isn't a large enough EMB free, it reports  *
  51. *   this and skips the copying function tests (tests of _XMMcopy() and     *
  52. *   _XMMicopy()), otherwise it performs the copying function tests. Then   *
  53. *   it starts the second part by trying to determine whether your system   *
  54. *   has UMBs. If it does not, it reports this fact and skips the rest of   *
  55. *   the UMB tests. If it does, it performs the rest of the UMB tests. If   *
  56. *   you see a message about "another broken system", that means that your  *
  57. *   XMS driver's support of UMBs is somewhat flaky, and the workarounds    *
  58. *   already built into XMSIF were unable to cover the problem. In this     *
  59. *   case, it will perform the rest of the UMB tests but is unable to check *
  60. *   that the functions actually did anything -- i.e. it can check the      *
  61. *   return code from the function, but cannot independently verify via     *
  62. *   other functions that the desired effect was actually achieved. See the *
  63. *   XMSIF documentation for a description of problems seen in the UMB      *
  64. *   support of various XMS drivers.                                        *
  65. *                                                                          *
  66. *   The "-q" option covers for some unusual behavior observed in QEMM      *
  67. *   5.1* which may also occur in other XMS drivers which provide EMS       *
  68. *   services as well. In QEMM's case, when extended memory is allocated,   *
  69. *   the total amount of XMS still available is decreased by the allocation *
  70. *   size rounded up to the nearest _16K_ (the EMS page size) instead of to *
  71. *   the nearest 1K (the XMS minimum allocation unit). HIMEM.SYS does not   *
  72. *   display this behavior. The "-q" option tells XMSTEST to expect a drop  *
  73. *   of a multiple of 16K after an allocation instead of a multiple of 1K.  *
  74. *   While XMSTEST can easily detect the difference, this option was added  *
  75. *   so that XMSTEST would know which multiple was expected and could       *
  76. *   detect incorrect drops more reliably.                                  *
  77. *                                                                          *
  78. *   The "-w" option covers for some different unusual behavior observed    *
  79. *   in DOS windows running under MS Windows 3.1 (it is not known whether   *
  80. *   Windows 3.0 does the same thing). In this case, when extended memory   *
  81. *   is allocated, the total amount of XMS still available is decreased by  *
  82. *   the allocation size rounded up to the nearest _4K_ (the 803/486 memory *
  83. *   management page size). The "-w" option tells XMSTEST to expect a drop  *
  84. *   of a multiple of 4K after an allocation instead of a multiple of 1K.   *
  85. *   While XMSTEST can easily detect the difference, this option was added  *
  86. *   so that XMSTEST would know which multiple was expected and could       *
  87. *   detect incorrect drops more reliably.                                  *
  88. *                                                                          *
  89. *                                                                          *
  90. *   Turbo C and older versions of Turbo C++ do not have the _fmemcmp() and *
  91. *   _fmemset() functions; I don't know about older versions of MSC. If     *
  92. *   your compiler does not have these functions, define the symbol         *
  93. *   NO_FFUNC and functions in this file will be used instead.              *
  94. *                                                                          *
  95. ***************************************************************************/
  96.  
  97. /*
  98. ** system includes <>
  99. */
  100.  
  101. #include <stdio.h>
  102. #include <stdlib.h>
  103. #include <dos.h>
  104. #include <string.h>
  105. #include <ctype.h>
  106.  
  107.  
  108. /*
  109. ** custom includes ""
  110. */
  111.  
  112. #include "xmsif.h"
  113. #include "xmstest.h"
  114.  
  115. #include "testutil.h"
  116.  
  117. /*
  118. ** local #defines
  119. */
  120.  
  121. /*
  122. ** misc: copyright strings, version macros, etc.
  123. */
  124.  
  125. /*
  126. ** typedefs
  127. */
  128.  
  129. /*
  130. ** global variables
  131. */
  132.  
  133. int testno = 1;                     /* number of test currently being done  */
  134. char *gblmsg = "";                  /* msg to be printed in test header     */
  135.  
  136. int qflag = 0;                      /* running QEMM or not?                 */
  137. int wflag = 0;                      /* running under Windows or not?        */
  138.  
  139.  
  140. /*
  141. ** static globals
  142. */
  143.  
  144. /*
  145. ** function prototypes
  146. */
  147.  
  148. /*
  149. ** functions
  150. */
  151.  
  152.  
  153. /***************************************************************************
  154. *   FUNCTION: MAIN                                                         *
  155. *                                                                          *
  156. *   DESCRIPTION:                                                           *
  157. *                                                                          *
  158. *       The master function.                                               *
  159. *                                                                          *
  160. *   ENTRY:                                                                 *
  161. *                                                                          *
  162. *       None.                                                              *
  163. *                                                                          *
  164. *   EXIT:                                                                  *
  165. *                                                                          *
  166. *       Void.                                                              *
  167. *                                                                          *
  168. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  169. *                                                                          *
  170. ***************************************************************************/
  171. main(int argc, char *argv[])
  172. {
  173.     int status;                     /* return status from library functions */
  174.     unsigned int version;
  175.  
  176.     if (argc > 1)
  177.     {
  178.         if ((argv[1][0] == '-') || (argv[1][0] == '/'))
  179.         {
  180.             if (toupper(argv[1][1]) == 'Q')
  181.             {
  182.                 qflag = 1;
  183.             }
  184.             else if (toupper(argv[1][1]) == 'W')
  185.             {
  186.                 wflag = 1;
  187.             }
  188.             else
  189.             {
  190.                 printf("Usage: XMSTEST [-wq]\n");
  191.                 exit(1);
  192.             }
  193.         }
  194.         else
  195.         {
  196.             printf("Usage: XMSTEST [-wq]\n");
  197.             exit(1);
  198.         }
  199.     }
  200.  
  201.     /* set banner */
  202.     gblmsg = "  PRELIMINARY EMB TESTS";
  203.  
  204.     /*
  205.     ** check initialization test
  206.     */
  207.     TESTHEADER();
  208.     printf("Making a call to XMMgetversion() before calling XMMlibinit().\n");
  209.     printf("The call should fail.\n");
  210.     XMMgetversion();
  211.     nofailcheck("XMMgetversion()", (int) _XMMerror, (void far *) NULL, 0, 0);
  212.     weirdcodechk("XMMgetversion()", XMM_NOINIT, (void far *) NULL, 0, 0);
  213.     TESTTAILER();
  214.  
  215.  
  216.     /*
  217.     ** initialize XMSIF
  218.     */
  219.     TESTHEADER();
  220.     printf("Calling XMMlibinit().\n");
  221.     printf("Should succeed if Extended Memory Manager is present.\n");
  222.     status = XMMlibinit();
  223.     switch (status)
  224.     {
  225.         case XMMOOPS:
  226.             printf("XMMlibinit() failed, code 0x%X.\n",
  227.                                                     (unsigned int) _XMMerror);
  228.             exit(3);
  229.             break;
  230.  
  231.         case NOXMM:
  232.             printf("XMMlibinit() did not find an Extended Memory Manager.\n");
  233.             exit(3);
  234.             break;
  235.  
  236.         case 0:
  237.             printf("XMMlibinit() returned OK.\n");
  238.             weirdcodechk("XMMlibinit()", 0, (void far *) NULL, 0, 0);
  239.             break;
  240.  
  241.         default:
  242.             printf("XMMlibinit() returned strange value %d.\n", status);
  243.             exit(3);
  244.             break;
  245.     }
  246.     TESTTAILER();
  247.  
  248.  
  249.     /*
  250.     ** test version call
  251.     */
  252.     TESTHEADER();
  253.     printf("Testing XMMgetversion().\n");
  254.     printf("Results should match value in _XMMversion.\n");
  255.     version = XMMgetversion();
  256.     weirdcodechk("XMMgetversion()", 0, (void far *) NULL, 0, 0);
  257.     if (version != (int) _XMMversion)
  258.     {
  259.         printf("XMMgetversion() [0x%X] and _XMMversion [0x%X] differ.\n",
  260.                                           version, (unsigned int) _XMMversion);
  261.         exit(3);
  262.     }
  263.     printf("XMS version %d.%02d.\n", ((version >> 8) & 0xFF), (version & 0xFF));
  264.     TESTTAILER();
  265.  
  266.  
  267.     /*
  268.     ** test allocation functions
  269.     */
  270.     if (do_alloc_tests(1L) == 0)
  271.     {
  272.         do_alloc_tests(16384L);
  273.         do_alloc_tests(85555L);
  274.         do_alloc_tests(0L);
  275.  
  276.         /*
  277.         ** test rawcall interface
  278.         */
  279.         do_rawcall_tests();
  280.  
  281.         /*
  282.         ** test copies
  283.         */
  284.         do_copy_tests();
  285.     }
  286.  
  287.     /*
  288.     ** test UMB functions (if possible)
  289.     */
  290.     do_UMB_tests();
  291.  
  292.     /* end and cleanup */
  293.     printf(">>>END\n");
  294.     printf("All tests succeeded.\n");
  295.  
  296.     exit(0);
  297. } /* end of main() */
  298.  
  299.  
  300. /***************************************************************************
  301. *   FUNCTION: DO_ALLOC_TESTS                                               *
  302. *                                                                          *
  303. *   DESCRIPTION:                                                           *
  304. *                                                                          *
  305. *       This function tests XMSIF calls XMMcoreleft(), XMMallcoreleft(),   *
  306. *       XMMalloc(), and XMMfree().                                         *                *
  307. *                                                                          *
  308. *   ENTRY:                                                                 *
  309. *                                                                          *
  310. *       bytes - number of bytes of XMS to try to allocate.                 *
  311. *                                                                          *
  312. *   EXIT:                                                                  *
  313. *                                                                          *
  314. *       Void.                                                              *
  315. *                                                                          *
  316. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  317. *                                                                          *
  318. ***************************************************************************/
  319. int do_alloc_tests(unsigned long bytes)
  320. {
  321.     unsigned long xmsfree, xmsfree2;
  322.     unsigned long xmsallfree, xmsallfree2;
  323.     unsigned long rndlen, mmupagelen, emspagelen;
  324.     unsigned long expected;
  325.     int handle;
  326.  
  327.     /* get bytes value rounded up to nearest K */
  328.     rndlen = ((bytes + 1023L) & 0xFFFFFC00);
  329.     /* get bytes value rounded up to nearest 4K */
  330.     mmupagelen = ((bytes + 4095L) & 0xFFFFF000);
  331.     /* get bytes value rounded up to nearest 16K */
  332.     emspagelen = ((bytes + 16383L) & 0xFFFFC000);
  333.  
  334.     /* determine expected length */
  335.     if (qflag != 0)
  336.     {
  337.         expected = emspagelen;
  338.     }
  339.     else if (wflag != 0)
  340.     {
  341.         expected = mmupagelen;
  342.     }
  343.     else
  344.     {
  345.         expected = rndlen;
  346.     }
  347.  
  348.     /* test coreleft */
  349.     TESTHEADER();
  350.     printf("Testing XMMcoreleft().\n");
  351.     printf("Result should be multiple of 1024.\n");
  352.     xmsfree = test_XMMcoreleft();
  353.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  354.                                                   xmsfree, (xmsfree / 1024L));
  355.     TESTTAILER();
  356.  
  357.     /* test allcoreleft */
  358.     TESTHEADER();
  359.     printf("Testing XMMallcoreleft().\n");
  360.     printf("Result should be multiple of 1024 and >= XMMcoreleft().\n");
  361.     xmsallfree = test_XMMallcoreleft();
  362.     if (xmsallfree >= xmsfree)
  363.     {
  364.         printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  365.                                              xmsallfree, (xmsallfree / 1024L));
  366.     }
  367.     else
  368.     {
  369.         printf("XMMallcoreleft() returned low value %lu.\n", xmsallfree);
  370.         exit(3);
  371.     }
  372.  
  373.     /* make sure enough free */
  374.     if (xmsallfree < MINFREE)
  375.     {
  376.         printf("Insufficient free XMS to perform all tests. Aborting EMB tests.\n");
  377.         return 1;
  378.     }
  379.     /* enough free, but is it unfragmented enough to be useable? */
  380.     if (xmsfree < MINFREE)
  381.     {
  382.         /* largest block isn't big enough -- can't finish tests */
  383.         printf("XMS too fragmented to perform all tests. Aborting EMB tests.\n");
  384.         return 1;
  385.     }
  386.  
  387.     /* test allocation */
  388.     TESTHEADER();
  389.     printf("Testing XMMalloc(%lu).\n", bytes);
  390.     printf("Should succeed. Free XMS should drop by %lu bytes (%luK).\n",
  391.                                                  expected, (expected / 1024L));
  392.     handle = test_XMMalloc(bytes);
  393.     printf("XMMalloc() returned OK.\n");
  394.     xmsfree2 = test_XMMcoreleft();
  395.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  396.                                                  xmsfree2, (xmsfree2 / 1024L));
  397.     xmsallfree2 = test_XMMallcoreleft();
  398.     printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  399.                                            xmsallfree2, (xmsallfree2 / 1024L));
  400.     if ((xmsallfree - xmsallfree2) != expected)
  401.     {
  402.         printf("XMMalloc(%lu) caused total free to drop from %lu to %lu.\n",
  403.                                                bytes, xmsallfree, xmsallfree2);
  404.         if ((xmsallfree - xmsallfree2) == emspagelen)
  405.         {
  406.             if (emspagelen == mmupagelen)
  407.             {
  408.                 printf("Try using the -q or -w switches.\n");
  409.             }
  410.             else
  411.             {
  412.                 printf("Try using the -q switch.\n");
  413.             }
  414.         }
  415.         else if ((xmsallfree - xmsallfree2) == mmupagelen)
  416.         {
  417.             printf("Try using the -w switch.\n");
  418.         }
  419.         else if ((xmsallfree - xmsallfree2) == rndlen)
  420.         {
  421.             printf("Try not using the -%c switch.\n",
  422.                    ((qflag != 0) ? 'q' : 'w'));
  423.         }
  424.         XMMfree(handle);
  425.         exit(3);
  426.     }
  427.     TESTTAILER();
  428.  
  429.     /* test free */
  430.     TESTHEADER();
  431.     printf("Testing XMMfree() on handle just returned by XMMalloc().\n");
  432.     printf("Should succeed. Free XMS should increase by %lu bytes (%luK).\n",
  433.                                                  expected, (expected / 1024L));
  434.     test_XMMfree(handle);
  435.     printf("XMMfree() returned OK.\n");
  436.     xmsfree2 = test_XMMcoreleft();
  437.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  438.                                                  xmsfree2, (xmsfree2 / 1024L));
  439.     xmsallfree2 = test_XMMallcoreleft();
  440.     printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  441.                                            xmsallfree2, (xmsallfree2 / 1024L));
  442.     if (xmsallfree2 != xmsallfree)
  443.     {
  444.         printf("Freeing handle returned by XMMalloc() did not restore\n");
  445.         printf("   total free XMS count -- was %lu originally, now %lu.\n",
  446.                                                       xmsallfree, xmsallfree2);
  447.         exit(3);
  448.     }
  449.     TESTTAILER();
  450.  
  451.     /* make sure enough free */
  452.     if (xmsallfree < MINFREE)
  453.     {
  454.         printf("Insufficient free XMS to perform all tests. Aborting.\n");
  455.         exit(1);
  456.     }
  457.     /* enough free, but is it unfragmented enough to be useable? */
  458.     if (xmsfree < MINFREE)
  459.     {
  460.         /* largest block isn't big enough -- can't finish tests */
  461.         printf("XMS too fragmented to perform all tests. Aborting.\n");
  462.         exit(1);
  463.     }
  464.  
  465.     return 0;
  466. } /* end of do_alloc_tests() */
  467.  
  468.  
  469. /***************************************************************************
  470. *   FUNCTION: DO_RAWCALL_TESTS                                             *
  471. *                                                                          *
  472. *   DESCRIPTION:                                                           *
  473. *                                                                          *
  474. *       This function tests the XMSIF call XMMrawcall().                   *
  475. *                                                                          *
  476. *   ENTRY:                                                                 *
  477. *                                                                          *
  478. *       Void.                                                              *
  479. *                                                                          *
  480. *   EXIT:                                                                  *
  481. *                                                                          *
  482. *       Void.                                                              *
  483. *                                                                          *
  484. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  485. *                                                                          *
  486. ***************************************************************************/
  487. void do_rawcall_tests()
  488. {
  489.     unsigned long xmsfree, xmsallfree;
  490.     struct XMMregs r;
  491.     int status;
  492.  
  493.     /* first, get something to check against */
  494.     xmsfree = test_XMMcoreleft();
  495.     xmsallfree = test_XMMallcoreleft();
  496.     printf("XMMcoreleft: %lu bytes (%luK)  XMMallcoreleft: %lu bytes (%luK)\n",
  497.                  xmsfree, (xmsfree / 1024L), xmsallfree, (xmsallfree / 1024L));
  498.  
  499.     TESTHEADER();
  500.     printf("Testing XMMrawcall() against XMMcoreleft()/XMMallcoreleft().\n");
  501.     printf("Should succeed.\n");
  502.     r.regAX = 0x0800;
  503.     status = XMMrawcall(&r);
  504.     TRIPLECHECK("XMMrawcall()", status, 0, (void far *) NULL, 0, 0);
  505.     if ((r.regAX != (xmsfree / 1024L)) || (r.regDX != (xmsallfree / 1024L)))
  506.     {
  507.         printf("XMMrawcall() returned %uK and %uK.\n", r.regAX, r.regDX);
  508.         exit(3);
  509.     }
  510.     TESTTAILER();
  511.  
  512.     return;
  513. } /* end of do_rawcall_tests() */
  514.  
  515.  
  516. /***************************************************************************
  517. *   FUNCTION: DO_NCOPY1_TESTS                                              *
  518. *                                                                          *
  519. *   DESCRIPTION:                                                           *
  520. *                                                                          *
  521. *       Tests normal copy functions (_XMMcopy() and macros).               *
  522. *                                                                          *
  523. *   ENTRY:                                                                 *
  524. *                                                                          *
  525. *       None.                                                              *
  526. *                                                                          *
  527. *   EXIT:                                                                  *
  528. *                                                                          *
  529. *       Void.                                                              *
  530. *                                                                          *
  531. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  532. *                                                                          *
  533. ***************************************************************************/
  534. void do_ncopy1_tests(void)
  535. {
  536.     int handle = 0;  /* dummy, to make some macros happy */
  537.     unsigned char far *realbuf;
  538.     unsigned char far *guard1, far *guard2, far *guard3;
  539.     unsigned char far *testbuf;
  540.     unsigned char far *testbuf2;
  541.     int status;
  542.  
  543.     /* allocate a conventional memory buffer */
  544.     realbuf = (unsigned char far *) LMALLOC((MINFREE/1024L) + 3);
  545.     if (realbuf == (unsigned char far *) NULL)
  546.     {
  547.         printf("Can't allocate conventional buffer. Aborting.\n");
  548.         exit(3);
  549.     }
  550.  
  551.     /*
  552.     ** Since we can't access EMBs directly, the only way we have of getting
  553.     ** data there is via the copy functions, which we're trying to test. So
  554.     ** the first round of tests will copy data from one half of the
  555.     ** conventional memory to the other, something which we can verify
  556.     ** directly.
  557.     **
  558.     ** Since _XMMcopy is symmetrical, we only need to give one direction
  559.     ** a real workout.
  560.     */
  561.     guard1 = realbuf;
  562.     FMEMSET(guard1, GUARDVAL, 1024);
  563.     testbuf = (unsigned char far *) normptr(guard1 + 1024);
  564.     guard2 = (unsigned char far *) normptr(testbuf + HALFLEN);
  565.     FMEMSET(guard2, GUARDVAL, 1024);
  566.     testbuf2 = (unsigned char far *) normptr(guard2 + 1024);
  567.     guard3 = (unsigned char far *) normptr(testbuf2 + HALFLEN);
  568.     FMEMSET(guard3, GUARDVAL, 1024);
  569.     gblmsg = "  COPY TESTS CONVENTIONAL-CONVENTIONAL";
  570.  
  571.     /* fill first buffer with incrementing words */
  572.     farincwordfill(testbuf, HALFLEN, 0);
  573.     /* fill second buffer with zero */
  574.     FMEMSET(testbuf2, 0, HALFLEN);
  575.  
  576.     /* try an even-length copy from offset 0 to offset 0 */
  577.     TESTHEADER();
  578.     printf("_XMMcopy(): even-length copy from offset 0 to offset 0.\n");
  579.     printf("Should succeed.\n");
  580.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  581.                                                      (unsigned long) testbuf2);
  582.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  583.     GUARDCHECK(0);
  584.     SRCWORDCHECK(testbuf, HALFLEN);
  585.     CPYWORDCHECK(testbuf2, 50);
  586.     ZEROCHECK((testbuf2 + 50), (HALFLEN - 50));
  587.     TESTTAILER();
  588.  
  589.     /* restore destination pattern */
  590.     FMEMSET(testbuf2, 0, HALFLEN);
  591.  
  592.     /* try an even-length copy from offset 0 to arbitrary offset */
  593.     TESTHEADER();
  594.     printf("_XMMcopy(): even-length copy from offset 0 to arbitrary offset.\n");
  595.     printf("Should succeed.\n");
  596.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  597.                                               (unsigned long)(testbuf2 + 477));
  598.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  599.     GUARDCHECK(0);
  600.     SRCWORDCHECK(testbuf, HALFLEN);
  601.     ZEROCHECK(testbuf2, 477);
  602.     MEMCMP(testbuf, (testbuf2 + 477), 50);
  603.     ZEROCHECK((testbuf2 + 477 + 50), ((HALFLEN - 477) - 50));
  604.     TESTTAILER();
  605.  
  606.     /* restore destination pattern */
  607.     FMEMSET(testbuf2, 0, HALFLEN);
  608.  
  609.     /* try an even-length copy from offset 0 to just before the end */
  610.     TESTHEADER();
  611.     printf("_XMMcopy(): even-length copy from offset 0 to just before end.\n");
  612.     printf("Should succeed.\n");
  613.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  614.                                      (unsigned long)(testbuf2 + HALFLEN - 50));
  615.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  616.     GUARDCHECK(0);
  617.     SRCWORDCHECK(testbuf, HALFLEN);
  618.     ZEROCHECK(testbuf2, (HALFLEN - 50));
  619.     CPYWORDCHECK((testbuf2 + HALFLEN - 50), 50);
  620.     TESTTAILER();
  621.  
  622.     /* restore destination pattern */
  623.     FMEMSET(testbuf2, 0, HALFLEN);
  624.  
  625.     /* try an even-length copy from arbitrary offset to arbitrary offset */
  626.     TESTHEADER();
  627.     printf("_XMMcopy(): even-length copy from arbitrary offset to ");
  628.     printf("arbitrary offset.\nShould succeed.");
  629.     status = _XMMcopy(50, 0, (unsigned long)(testbuf + 384), 0,
  630.                                            (unsigned long)(testbuf2 + 33333U));
  631.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  632.     GUARDCHECK(0);
  633.     SRCWORDCHECK(testbuf, HALFLEN);
  634.     ZEROCHECK(testbuf2, 33333U);
  635.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 50);
  636.     ZEROCHECK((testbuf2 + 33333U + 50), ((HALFLEN - 33333U) - 50));
  637.     TESTTAILER();
  638.  
  639.     /* restore destination pattern */
  640.     FMEMSET(testbuf2, 0, HALFLEN);
  641.  
  642.     /* try an even-length copy from just before the end to arbitrary offset */
  643.     TESTHEADER();
  644.     printf("_XMMcopy(): even-length copy from just before end to arbitrary.\n");
  645.     printf("Should succeed.\n");
  646.     status = _XMMcopy(50, 0, (unsigned long)(testbuf + HALFLEN - 50), 0,
  647.                                              (unsigned long)(testbuf2 + 7676));
  648.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  649.     GUARDCHECK(0);
  650.     SRCWORDCHECK(testbuf, HALFLEN);
  651.     ZEROCHECK(testbuf2, 7676);
  652.     MEMCMP((testbuf + HALFLEN - 50), (testbuf2 + 7676), 50);
  653.     ZEROCHECK((testbuf2 + 7676 + 50), ((HALFLEN - 7676) - 50));
  654.     TESTTAILER();
  655.  
  656.     /* restore destination pattern */
  657.     FMEMSET(testbuf2, 0, HALFLEN);
  658.  
  659.  
  660.     /* try an odd-length copy from offset 0 to offset 0 */
  661.     TESTHEADER();
  662.     printf("_XMMcopy(): odd-length copy from offset 0 to offset 0.\n");
  663.     printf("Should succeed.\n");
  664.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  665.                                                      (unsigned long) testbuf2);
  666.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  667.     GUARDCHECK(0);
  668.     SRCWORDCHECK(testbuf, HALFLEN);
  669.     MEMCMP(testbuf, testbuf2, 111);
  670.     ZEROCHECK((testbuf2 + 111), (HALFLEN - 111));
  671.     TESTTAILER();
  672.  
  673.     /* restore destination pattern */
  674.     FMEMSET(testbuf2, 0, HALFLEN);
  675.  
  676.     /* try an odd-length copy from offset 0 to offset misc */
  677.     TESTHEADER();
  678.     printf("_XMMcopy(): odd-length copy from offset 0 to arbitrary offset.\n");
  679.     printf("Should succeed.\n");
  680.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  681.                                               (unsigned long)(testbuf2 + 477));
  682.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  683.     GUARDCHECK(0);
  684.     SRCWORDCHECK(testbuf, HALFLEN);
  685.     ZEROCHECK(testbuf2, 477);
  686.     MEMCMP(testbuf, (testbuf2 + 477), 111);
  687.     ZEROCHECK((testbuf2 + 477 + 111), ((HALFLEN - 477) - 111));
  688.     TESTTAILER();
  689.  
  690.     /* restore destination pattern */
  691.     FMEMSET(testbuf2, 0, HALFLEN);
  692.  
  693.     /* try an odd-length copy from offset 0 to just before the end */
  694.     TESTHEADER();
  695.     printf("_XMMcopy(): odd-length copy from offset 0 to just before end.\n");
  696.     printf("Should succeed.\n");
  697.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  698.                                     (unsigned long)(testbuf2 + HALFLEN - 111));
  699.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  700.     GUARDCHECK(0);
  701.     SRCWORDCHECK(testbuf, HALFLEN);
  702.     ZEROCHECK(testbuf2, (HALFLEN - 111));
  703.     MEMCMP(testbuf, (testbuf2 + HALFLEN - 111), 111);
  704.     TESTTAILER();
  705.  
  706.     /* restore destination pattern */
  707.     FMEMSET(testbuf2, 0, HALFLEN);
  708.  
  709.     /* try an odd-length copy from arbitrary offset to arbitrary offset */
  710.     TESTHEADER();
  711.     printf("_XMMcopy(): odd-length copy from arbitrary offset to ");
  712.     printf("arbitrary offset.\nShould succeed.\n");
  713.     status = _XMMcopy(111, 0, (unsigned long)(testbuf + 384), 0,
  714.                                            (unsigned long)(testbuf2 + 33333U));
  715.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  716.     GUARDCHECK(0);
  717.     SRCWORDCHECK(testbuf, HALFLEN);
  718.     ZEROCHECK(testbuf2, 33333U);
  719.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 111);
  720.     ZEROCHECK((testbuf2 + 33333U + 111), ((HALFLEN - 33333U) - 111));
  721.     TESTTAILER();
  722.  
  723.     /* restore destination pattern */
  724.     FMEMSET(testbuf2, 0, HALFLEN);
  725.  
  726.     /* try an odd-length copy from just before the end to arbitrary offset */
  727.     TESTHEADER();
  728.     printf("_XMMcopy(): odd-length copy from just before end to arbitrary.\n");
  729.     printf("Should succeed.\n");
  730.     status = _XMMcopy(111, 0, (unsigned long)(testbuf + HALFLEN - 111), 0,
  731.                                              (unsigned long)(testbuf2 + 7676));
  732.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  733.     GUARDCHECK(0);
  734.     SRCWORDCHECK(testbuf, HALFLEN);
  735.     ZEROCHECK(testbuf2, 7676);
  736.     MEMCMP((testbuf + HALFLEN - 111), (testbuf2 + 7676), 111);
  737.     ZEROCHECK((testbuf2 + 7676 + 111), ((HALFLEN - 7676) - 111));
  738.     TESTTAILER();
  739.  
  740.     /* restore destination pattern */
  741.     FMEMSET(testbuf2, 0, HALFLEN);
  742.  
  743.  
  744.     /* try a one-byte copy from offset 0 to offset 0 */
  745.     TESTHEADER();
  746.     printf("_XMMcopy(): one-byte copy from offset 0 to offset 0.\n");
  747.     printf("Should succeed.\n");
  748.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  749.                                                      (unsigned long) testbuf2);
  750.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  751.     GUARDCHECK(0);
  752.     SRCWORDCHECK(testbuf, HALFLEN);
  753.     MEMCMP(testbuf, testbuf2, 1);
  754.     ZEROCHECK((testbuf2 + 1), (HALFLEN - 1));
  755.     TESTTAILER();
  756.  
  757.     /* restore destination pattern */
  758.     FMEMSET(testbuf2, 0, HALFLEN);
  759.  
  760.     /* try a one-byte copy from offset 0 to offset misc */
  761.     TESTHEADER();
  762.     printf("_XMMcopy(): one-byte copy from offset 0 to arbitrary offset.\n");
  763.     printf("Should succeed.\n");
  764.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  765.                                               (unsigned long)(testbuf2 + 477));
  766.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  767.     GUARDCHECK(0);
  768.     SRCWORDCHECK(testbuf, HALFLEN);
  769.     ZEROCHECK(testbuf2, 477);
  770.     MEMCMP(testbuf, (testbuf2 + 477), 1);
  771.     ZEROCHECK((testbuf2 + 477 + 1), ((HALFLEN - 477) - 1));
  772.     TESTTAILER();
  773.  
  774.     /* restore destination pattern */
  775.     FMEMSET(testbuf2, 0, HALFLEN);
  776.  
  777.     /* try a one-byte copy from offset 0 to just before the end */
  778.     TESTHEADER();
  779.     printf("_XMMcopy(): one-byte copy from offset 0 to just before end.\n");
  780.     printf("Should succeed.\n");
  781.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  782.                                       (unsigned long)(testbuf2 + HALFLEN - 1));
  783.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  784.     GUARDCHECK(0);
  785.     SRCWORDCHECK(testbuf, HALFLEN);
  786.     ZEROCHECK(testbuf2, (HALFLEN - 1));
  787.     MEMCMP(testbuf, (testbuf2 + HALFLEN - 1), 1);
  788.     TESTTAILER();
  789.  
  790.     /* restore destination pattern */
  791.     FMEMSET(testbuf2, 0, HALFLEN);
  792.  
  793.     /* try a one-byte copy from arbitrary offset to arbitrary offset */
  794.     TESTHEADER();
  795.     printf("_XMMcopy(): one-byte copy from arbitrary offset to ");
  796.     printf("arbitrary offset.\nShould succeed.");
  797.     status = _XMMcopy(1, 0, (unsigned long)(testbuf + 384), 0,
  798.                                            (unsigned long)(testbuf2 + 33333U));
  799.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  800.     GUARDCHECK(0);
  801.     SRCWORDCHECK(testbuf, HALFLEN);
  802.     ZEROCHECK(testbuf2, 33333U);
  803.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 1);
  804.     ZEROCHECK((testbuf2 + 33333U + 1), ((HALFLEN - 33333U) - 1));
  805.     TESTTAILER();
  806.  
  807.     /* restore destination pattern */
  808.     FMEMSET(testbuf2, 0, HALFLEN);
  809.  
  810.     /* try a one-byte copy from just before the end to arbitrary offset */
  811.     TESTHEADER();
  812.     printf("_XMMcopy(): one-byte copy from just before end to arbitrary.\n");
  813.     printf("Should succeed.\n");
  814.     status = _XMMcopy(1, 0, (unsigned long)(testbuf + HALFLEN - 1), 0,
  815.                                              (unsigned long)(testbuf2 + 7676));
  816.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  817.     GUARDCHECK(0);
  818.     SRCWORDCHECK(testbuf, HALFLEN);
  819.     ZEROCHECK(testbuf2, 7676);
  820.     MEMCMP((testbuf + HALFLEN - 1), (testbuf2 + 7676), 1);
  821.     ZEROCHECK((testbuf2 + 7676 + 1), ((HALFLEN - 7676) - 1));
  822.     TESTTAILER();
  823.  
  824.     /*
  825.     ** Clean up.
  826.     */
  827.     LFREE(realbuf);
  828.  
  829.     return;
  830. } /* end of do_ncopy1_tests() */
  831.  
  832.  
  833. /*
  834. ** The following group of functions {test_XMM*()} are wrapper functions
  835. ** that call the XMSIF function named and perform preliminary checks on
  836. ** the return values. This keeps code size down since the check only has
  837. ** to be coded in one place.
  838. */
  839.  
  840.  
  841. /***************************************************************************
  842. *   FUNCTION: TEST_XMMCORELEFT                                             *
  843. *                                                                          *
  844. *   DESCRIPTION:                                                           *
  845. *                                                                          *
  846. *       This function calls XMSIF function XMMcoreleft() and checks the    *
  847. *       return value to see if it is a multiple of 1024 (the minimum XMS   *
  848. *       allocation unit).                                                  *
  849. *                                                                          *
  850. *   ENTRY:                                                                 *
  851. *                                                                          *
  852. *       Void.                                                              *
  853. *                                                                          *
  854. *   EXIT:                                                                  *
  855. *                                                                          *
  856. *       Returns the value returned by XMMcoreleft().                       *
  857. *                                                                          *
  858. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  859. *                                                                          *
  860. ***************************************************************************/
  861. unsigned long test_XMMcoreleft(void)
  862. {
  863.     unsigned long xmsfree;
  864.  
  865.     /* call XMMcoreleft and check error code */
  866.     xmsfree = XMMcoreleft();
  867.     weirdcodechk("XMMcoreleft()", 0, (void far *) NULL, 0, 0);
  868.  
  869.     /* check if free byte count is multiple of 1024 */
  870.     if ((xmsfree % 1024L) != 0)
  871.     {
  872.         printf("XMMcoreleft() returned strange number %lu.\n", xmsfree);
  873.         exit(3);
  874.     }
  875.  
  876.     return xmsfree;
  877. } /* end of test_XMMcoreleft() */
  878.  
  879.  
  880. /***************************************************************************
  881. *   FUNCTION: TEST_XMMALLCORELEFT                                          *
  882. *                                                                          *
  883. *   DESCRIPTION:                                                           *
  884. *                                                                          *
  885. *       This function calls XMSIF function XMMallcoreleft() and checks     *
  886. *       the return value to see if it is a multiple of 1024 (the minimum   *
  887. *       XMS allocation unit).                                              *
  888. *                                                                          *
  889. *   ENTRY:                                                                 *
  890. *                                                                          *
  891. *       Void.                                                              *
  892. *                                                                          *
  893. *   EXIT:                                                                  *
  894. *                                                                          *
  895. *       Returns the value returned by XMMallcoreleft().                    *
  896. *                                                                          *
  897. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  898. *                                                                          *
  899. ***************************************************************************/
  900. unsigned long test_XMMallcoreleft(void)
  901. {
  902.     unsigned long xmsfree;
  903.  
  904.     /* call XMMallcoreleft and check error code */
  905.     xmsfree = XMMallcoreleft();
  906.     weirdcodechk("XMMallcoreleft()", 0, (void far *) NULL, 0, 0);
  907.  
  908.     /* check if free byte count is multiple of 1024 */
  909.     if ((xmsfree % 1024L) != 0)
  910.     {
  911.         printf("XMMallcoreleft() returned strange number %lu.\n", xmsfree);
  912.         exit(3);
  913.     }
  914.  
  915.     return xmsfree;
  916. } /* end of test_XMMallcoreleft() */
  917.  
  918.  
  919. /***************************************************************************
  920. *   FUNCTION: TEST_XMMALLOC                                                *
  921. *                                                                          *
  922. *   DESCRIPTION:                                                           *
  923. *                                                                          *
  924. *       This function calls XMSIF function XMMalloc() and checks the       *
  925. *       return codes.                                                      *
  926. *                                                                          *
  927. *   ENTRY:                                                                 *
  928. *                                                                          *
  929. *       bytes - bytes of XMS to allocate                                   *
  930. *                                                                          *
  931. *   EXIT:                                                                  *
  932. *                                                                          *
  933. *       Returns the handle returned by XMMalloc().                         *
  934. *                                                                          *
  935. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  936. *                                                                          *
  937. ***************************************************************************/
  938. int test_XMMalloc(unsigned long bytes)
  939. {
  940.     int handle;
  941.  
  942.     /* call XMMalloc() and check the return */
  943.     handle = XMMalloc(bytes);
  944.     weirdcodechk("XMMalloc()", 0, (void far *) NULL, 0, 0);
  945.  
  946.     return handle;
  947. } /* end of test_XMMalloc() */
  948.  
  949.  
  950. /***************************************************************************
  951. *   FUNCTION: TEST_XMMFREE                                                 *
  952. *                                                                          *
  953. *   DESCRIPTION:                                                           *
  954. *                                                                          *
  955. *       This function calls XMSIF function XMMfree() and checks the        *
  956. *       return codes.                                                      *
  957. *                                                                          *
  958. *   ENTRY:                                                                 *
  959. *                                                                          *
  960. *       handle - XMS EMB handle to be freed                                *
  961. *                                                                          *
  962. *   EXIT:                                                                  *
  963. *                                                                          *
  964. *       Void.                                                              *
  965. *                                                                          *
  966. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  967. *                                                                          *
  968. ***************************************************************************/
  969. void test_XMMfree(int handle)
  970. {
  971.     int status;
  972.  
  973.     /* call XMMfree() and check the return */
  974.     status = XMMfree(handle);
  975.     TRIPLECHECK("XMMfree()", status, 0, (void far *) NULL, 0, 0);
  976.  
  977.     return;
  978. } /* end of test_XMMfree() */
  979.  
  980.  
  981. /*
  982. ** The following group of functions are used to speed up return checking
  983. ** and keep code size down, since the return check only has to be coded
  984. ** in one place. They are used in various macros to further compact and
  985. ** clarify the code.
  986. */
  987.  
  988. /***************************************************************************
  989. *   FUNCTION: WEIRDRETCHK                                                  *
  990. *                                                                          *
  991. *   DESCRIPTION:                                                           *
  992. *                                                                          *
  993. *       This function checks to see if the status value passed to it is    *
  994. *       either 0 or XMMOOPS, and assumes something has gone wrong if it    *
  995. *       is not. If something has gone wrong, does some clean up before     *
  996. *       exiting.                                                           *
  997. *                                                                          *
  998. *   ENTRY:                                                                 *
  999. *                                                                          *
  1000. *       function - name of function which may have goofed                  *
  1001. *       status   - status value to check                                   *
  1002. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1003. *                  freed if NULL.                                          *
  1004. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1005. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1006. *                                                                          *
  1007. *   EXIT:                                                                  *
  1008. *                                                                          *
  1009. *       Void, or may not return.                                           *
  1010. *                                                                          *
  1011. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1012. *                                                                          *
  1013. ***************************************************************************/
  1014. void weirdretchk(char *function, int status, void far *tofree1, int tofree2,
  1015.                                                                    int tofree3)
  1016. {
  1017.     if ((status != XMMOOPS) && (status != 0))
  1018.     {
  1019.         printf("%s returned weird value %d, code 0x%X.\n", function, status,
  1020.                                                      (unsigned int) _XMMerror);
  1021.         if (tofree1 != (void far *) NULL)
  1022.         {
  1023.             LFREE(tofree1);
  1024.         }
  1025.         if (tofree2 != 0)
  1026.         {
  1027.             XMMfree(tofree2);
  1028.         }
  1029.         if (tofree3 != 0)
  1030.         {
  1031.             XMMfree(tofree3);
  1032.         }
  1033.         exit(3);
  1034.     }
  1035.  
  1036.     return;
  1037. } /* end of weirdretchk() */
  1038.  
  1039.  
  1040. /***************************************************************************
  1041. *   FUNCTION: WEIRDCODECHK                                                 *
  1042. *                                                                          *
  1043. *   DESCRIPTION:                                                           *
  1044. *                                                                          *
  1045. *       This function checks to see if the XMSIF error code value matches *
  1046. *       the expected value, and assumes something has gone wrong if it     *
  1047. *       does not. If something has gone wrong, does some clean up before   *
  1048. *       exiting.                                                           *
  1049. *                                                                          *
  1050. *   ENTRY:                                                                 *
  1051. *                                                                          *
  1052. *       function - name of function which may have goofed                  *
  1053. *       expected - expected value of _XMMerror                             *
  1054. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1055. *                  freed if NULL.                                          *
  1056. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1057. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1058. *                                                                          *
  1059. *   EXIT:                                                                  *
  1060. *                                                                          *
  1061. *       Void, or may not return.                                           *
  1062. *                                                                          *
  1063. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1064. *                                                                          *
  1065. ***************************************************************************/
  1066. void weirdcodechk(char *function, int expected, void far *tofree1, int tofree2,
  1067.                                                                    int tofree3)
  1068. {
  1069.     if ((int) _XMMerror != expected)
  1070.     {
  1071.         printf("%s returned unexpected code 0x%X.\n", function,
  1072.                                                      (unsigned int) _XMMerror);
  1073.         if (tofree1 != (void far *) NULL)
  1074.         {
  1075.             LFREE(tofree1);
  1076.         }
  1077.         if (tofree2 != 0)
  1078.         {
  1079.             XMMfree(tofree2);
  1080.         }
  1081.         if (tofree3 != 0)
  1082.         {
  1083.             XMMfree(tofree3);
  1084.         }
  1085.         exit(3);
  1086.     }
  1087.  
  1088.     return;
  1089. } /* end of weirdcodechk() */
  1090.  
  1091.  
  1092. /***************************************************************************
  1093. *   FUNCTION: FAILCHECK                                                    *
  1094. *                                                                          *
  1095. *   DESCRIPTION:                                                           *
  1096. *                                                                          *
  1097. *       This function checks to see if the status value passed to it is    *
  1098. *       XMMOOPS and exits if it is. failcheck() is used when a function    *
  1099. *       is expected to succeed. Does some clean up before exiting.         *
  1100. *                                                                          *
  1101. *   ENTRY:                                                                 *
  1102. *                                                                          *
  1103. *       function - name of function which may have goofed                  *
  1104. *       status   - status value to be checked                              *
  1105. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1106. *                  freed if NULL.                                          *
  1107. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1108. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1109. *                                                                          *
  1110. *   EXIT:                                                                  *
  1111. *                                                                          *
  1112. *       Void, or may not return.                                           *
  1113. *                                                                          *
  1114. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1115. *                                                                          *
  1116. ***************************************************************************/
  1117. void failcheck(char *function, int status, void far *tofree1, int tofree2,
  1118.                                                                   int tofree3)
  1119. {
  1120.     if (status == XMMOOPS)
  1121.     {
  1122.         printf("%s failed, code 0x%X.\n", function, (unsigned int) _XMMerror);
  1123.         if (tofree1 != (void far *) NULL)
  1124.         {
  1125.             LFREE(tofree1);
  1126.         }
  1127.         if (tofree2 != 0)
  1128.         {
  1129.             XMMfree(tofree2);
  1130.         }
  1131.         if (tofree3 != 0)
  1132.         {
  1133.             XMMfree(tofree3);
  1134.         }
  1135.         exit(3);
  1136.     }
  1137.  
  1138.     return;
  1139. } /* end of failcheck() */
  1140.  
  1141.  
  1142. /***************************************************************************
  1143. *   FUNCTION: NOFAILCHECK                                                  *
  1144. *                                                                          *
  1145. *   DESCRIPTION:                                                           *
  1146. *                                                                          *
  1147. *       This function checks to see if the status value passed to it is    *
  1148. *       0 and exits if it is. nofailcheck() is used when a function is     *
  1149. *       expected to fail. Does some clean up before exiting.               *
  1150. *                                                                          *
  1151. *   ENTRY:                                                                 *
  1152. *                                                                          *
  1153. *       function - name of function which may have goofed                  *
  1154. *       status   - status value to be checked                              *
  1155. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1156. *                  freed if NULL.                                          *
  1157. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1158. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1159. *                                                                          *
  1160. *   EXIT:                                                                  *
  1161. *                                                                          *
  1162. *       Void, or may not return.                                           *
  1163. *                                                                          *
  1164. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1165. *                                                                          *
  1166. ***************************************************************************/
  1167. void nofailcheck(char *function, int status, void far *tofree1, int tofree2,
  1168.                                                                   int tofree3)
  1169. {
  1170.     if (status == 0)
  1171.     {
  1172.         printf("%s did not fail.\n", function);
  1173.         if (tofree1 != (void far *) NULL)
  1174.         {
  1175.             LFREE(tofree1);
  1176.         }
  1177.         if (tofree2 != 0)
  1178.         {
  1179.             XMMfree(tofree2);
  1180.         }
  1181.         if (tofree3 != 0)
  1182.         {
  1183.             XMMfree(tofree3);
  1184.         }
  1185.         exit(3);
  1186.     }
  1187.  
  1188.     return;
  1189. } /* end of nofailcheck() */
  1190.  
  1191.