home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * emstest.c *
- * MODULE: EMSLIB *
- * OS: DOS *
- * VERSION: 1.0 *
- * DATE: 09/25/91 *
- * *
- * Copyright (c) 1991 James W. Birdsall. All Rights Reserved. *
- * *
- * Requires emslib.h and emstest.h to compile. *
- * Compiles under Borland C++ 2.0 or MSC 6.00A. *
- * *
- * Regression test and example for EMSLIB. *
- * *
- * This is part one of the regression tester and example for EMSLIB. *
- * The other parts are named EMSTEST2.C and EMSTEST3.C. All three parts *
- * must be compiled and linked together along with the appropriate EMSLIB *
- * library to produce the tester executable. This program compiles under *
- * tiny, small, medium, compact, large, and huge models. Note that it *
- * doesn't quite fit into tiny model; the tiny model tester is actually *
- * three executables. When compiling for tiny model, one of the symbols *
- * TINYPASS1, TINYPASS2, or TINYPASS3 must be defined. See the example *
- * makefiles for further details on what needs to be linked with what *
- * to produce the tiny-model executables. *
- * *
- * To use this tester: just run it. It requires no arguments and produces *
- * output on stdout. It performs nearly 200 tests and parts of it run *
- * quite fast, even on an original IBM PC/XT (4.77 MHz). If you want to *
- * actually read the output, you should redirect the output to a file. *
- * If you just want to see whether the tests all pass, just run it -- *
- * if a test fails, execution aborts immediately. *
- * *
- * Certain types of failure may cause EMSTEST to not deallocate EMS or *
- * conventional memory that it has allocated. This should only occur if *
- * the library itself is malfunctioning (which should never happen to *
- * you, only to me!) or if you are trying a different compiler or *
- * unsupported memory model and the compiler and library are therefore *
- * not communicating properly. It may also happen if you press control- *
- * break. *
- * *
- * To improve speed, some basic functions are coded in in-line assembly *
- * language. The in-line assembly is compatible with Turbo/Borland C[++] *
- * and MSC 6.00A. Since earlier versions of Turbo C required an external *
- * assembler to support in-line assembly, and I don't know whether *
- * earlier versions of MSC supported it at all, the functions also have *
- * alternate C versions. The C versions are compiled by default; to get *
- * the in-line assembly versions, you must define the symbol INLINE_ASM. *
- * *
- * Turbo C and older versions of Turbo C++ do not have the _fmemcmp() and *
- * _fmemset() functions; I don't know about older versions of MSC. If *
- * your compiler does not have these functions, define the symbol *
- * NO_FFUNC and functions in this file will be used instead. *
- * *
- ***************************************************************************/
-
- /*
- ** system includes <>
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
-
-
- /*
- ** custom includes ""
- */
-
- #include "emslib.h"
- #include "emstest.h"
-
-
- /*
- ** local #defines
- */
-
- /*
- ** misc: copyright strings, version macros, etc.
- */
-
- /*
- ** typedefs
- */
-
- /*
- ** global variables
- */
-
- int testno = 1; /* number of test currently being done */
- unsigned char far *frameptr[4]; /* pointers to EMS frames */
- char *gblmsg = ""; /* msg to be printed in test header */
-
-
- /*
- ** static globals
- */
-
- /*
- ** function prototypes
- */
-
- static unsigned char huge *normptr(unsigned char far *norm);
-
-
- /*
- ** functions
- */
-
-
- /***************************************************************************
- * FUNCTION: MAIN *
- * *
- * DESCRIPTION: *
- * *
- * The master function. *
- * *
- * ENTRY: *
- * *
- * None. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- main()
- {
- int status; /* return status from library functions */
-
- /*
- ** check initialization test
- */
- TESTHEADER();
- printf("Making a call to EMMgetversion() before calling EMMlibinit().\n");
- printf("The call should fail.\n");
- EMMgetversion();
- nofailcheck("EMMgetversion()", (int) _EMMerror, NULL, 0, 0);
- weirdcodechk("EMMgetversion()", EMM_NOINIT, NULL, 0, 0);
- TESTTAILER();
-
-
- /*
- ** initialize EMSLIB
- */
- TESTHEADER();
- printf("Calling EMMlibinit().\n");
- printf("Should succeed if Expanded Memory Manager is present.\n");
- status = EMMlibinit();
- switch (status)
- {
- case EMMOOPS:
- printf("EMMlibinit() failed, code 0x%X.\n",
- (unsigned int) _EMMerror);
- exit(3);
- break;
-
- case NOEMM:
- printf("EMMlibinit() did not find an Expanded Memory Manager.\n");
- exit(3);
- break;
-
- case 0:
- printf("EMMlibinit() returned OK.\n");
- weirdcodechk("EMMlibinit()", 0, NULL, 0, 0);
- break;
-
- default:
- printf("EMMlibinit() returned strange value %d.\n", status);
- exit(3);
- break;
- }
- TESTTAILER();
-
- /*
- ** The following section of code is included only in the first tiny-model
- ** executable and in non-tiny-model executables.
- */
- #ifndef TINYPASS2
- #ifndef TINYPASS3
-
- /*
- ** test version call
- */
- TESTHEADER();
- printf("Testing EMMgetversion().\n");
- printf("Results should match value in _EMMversion.\n");
- status = EMMgetversion();
- weirdcodechk("EMMgetversion()", 0, NULL, 0, 0);
- if (status != (int) _EMMversion)
- {
- printf("EMMgetversion() [0x%X] and _EMMversion [0x%X] differ.\n",
- status, (unsigned int) _EMMversion);
- exit(3);
- }
- printf("EMS version %d.%d.\n", ((status >> 4) & 0xF), (status & 0xF));
- TESTTAILER();
-
-
- /*
- ** test allocation functions
- */
- do_alloc_tests(1L);
- do_alloc_tests(16384L);
- do_alloc_tests(55555L);
- do_alloc_tests(0L);
-
- do_palloc_tests(1);
- do_palloc_tests(5);
-
- #endif
- #endif
-
- /*
- ** test frame functions -- included in all executables
- */
- do_frame_tests();
-
- /*
- ** The following section of code is included only in the first tiny-model
- ** executable and in non-tiny-model executables.
- */
- #ifndef TINYPASS2
- #ifndef TINYPASS3
-
- /*
- ** test name functions
- */
- do_name_tests();
-
- /*
- ** do mapping tests
- */
- do_map_tests();
-
- /*
- ** test the save/restore facility
- */
- do_sr_tests();
-
- #endif
- #endif
-
- /*
- ** The following section of code is included only in the second tiny-model
- ** executable and in non-tiny-model executables.
- */
- #ifndef TINYPASS1
- #ifndef TINYPASS3
-
- /*
- ** test copies of <= one page, frame caching on
- */
- gblmsg = " SHORT COPY TESTS";
- do_shortcopy_tests();
- gblmsg = "";
-
- /*
- ** test frame cache control
- */
- TESTHEADER();
- printf("Testing frame caching enable/disable.\n");
- if (_EMMframecache == 0)
- {
- printf("Frame caching is supposed to be on by default, seems to ");
- printf("be off.\n");
- exit(3);
- }
- _EMMdisc();
- weirdcodechk("_EMMdisc()", 0, NULL, 0, 0);
- if (_EMMframecache != 0)
- {
- printf("_EMMdisc() did not disable frame caching.\n");
- exit(3);
- }
- _EMMenc();
- weirdcodechk("_EMMenc()", 0, NULL, 0, 0);
- if (_EMMframecache == 0)
- {
- printf("_EMMenc() did not enable frame caching.\n");
- exit(3);
- }
- printf("Flag and function calls correspond OK.\n");
- TESTTAILER();
-
- /*
- ** test copies of <= one page, frame caching off
- */
- _EMMdisc();
- gblmsg = " SHORT COPY TESTS WITH FRAME CACHING OFF";
- do_shortcopy_tests();
- _EMMenc();
-
- #endif
-
- /*
- ** The following section of code is included only in the third tiny-model
- ** executable and in non-tiny-model executables.
- */
- #ifndef TINYPASS2
-
- /*
- ** test copies of > 1 page, frame caching on
- */
- _EMMenc();
- gblmsg = " LONG COPY TESTS";
- do_longcopy_tests();
-
- /*
- ** test copies of > 1 page, frame caching off
- */
- _EMMdisc();
- gblmsg = " LONG COPY TESTS WITH FRAME CACHING OFF";
- do_longcopy_tests();
- gblmsg = "";
- _EMMenc();
-
- #endif
- #endif
-
- /* end and cleanup */
- printf(">>>END\n");
- printf("All tests succeeded.\n");
-
- exit(0);
- } /* end of main() */
-
-
- /***************************************************************************
- * FUNCTION: DO_FRAME_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests EMSLIB calls EMMgetnumframe(), *
- * EMMgetframeaddr(), and EMMgetsinfraddr(). *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- * Fills in the frameptr[] global array. *
- * *
- ***************************************************************************/
- void do_frame_tests(void)
- {
- frameinfo *framebuf;
- int frames;
- int status;
- int loop;
- unsigned int segaddr;
-
- /* get number of frames */
- TESTHEADER();
- printf("Getting number of frames with EMMgetnumframe().\n");
- if (_EMMversion < 0x40)
- {
- printf("Should be exactly 4.\n");
- }
- else
- {
- printf("Should be 4 or more.\n");
- }
- frames = EMMgetnumframe();
- weirdcodechk("EMMgetnumframe()", 0, NULL, 0, 0);
- if (frames < 4)
- {
- printf("EMMgetnumframe() returned OK but indicates only %d frames.\n",
- frames);
- exit(3);
- }
- if ((_EMMversion < 0x40) && (frames != 4))
- {
- printf("EMMgetnumframe() returned OK but indicates wrong number of\n");
- printf(" frames (%d) for this version.\n", frames);
- exit(3);
- }
- printf("EMMgetnumframe() returned OK, %d frames.\n", frames);
- TESTTAILER();
-
- /* allocate memory for frame address buffer */
- framebuf = (frameinfo *) calloc(frames, sizeof(frameinfo));
- if (framebuf == (frameinfo *) NULL)
- {
- printf("OOPS! Couldn't allocate a buffer. Aborting.\n");
- exit(3);
- }
-
- /* get frame segment addresses */
- TESTHEADER();
- printf("Getting frame address info with EMMgetframeaddr().\n");
- printf("Should succeed.\n");
- status = EMMgetframeaddr(framebuf);
- TRIPLECHECK("EMMgetframeaddr()", status, 0, framebuf, 0, 0);
- printf("EMMgetframeaddr() returned OK, checking info returned...\n");
- for (loop = 0; loop < frames; loop++)
- {
- /* check for valid frame number */
- if (framebuf[loop].frameno >= frames)
- {
- printf("Frame number in slot %d is bad (%u).\n", loop,
- framebuf[loop].frameno);
- free(framebuf);
- exit(3);
- }
- /* check that frame segment address is on a page (16K) boundary */
- if ((framebuf[loop].segaddr & 0x3FF) != 0)
- {
- printf(
- "Frame segment %u, slot %d, frame number %u, not page aligned.\n",
- framebuf[loop].segaddr, loop, framebuf[loop].frameno);
- free(framebuf);
- exit(3);
- }
- /* if one of frames 0-3, save the address */
- if (framebuf[loop].frameno < 4)
- {
- frameptr[framebuf[loop].frameno] = (unsigned char far *)
- MK_FP(framebuf[loop].segaddr, 0);
- }
- }
- printf("Info returned checks out OK.\n");
- TESTTAILER();
-
- /* now test EMMgetsinfraddr() */
- TESTHEADER();
- printf("Testing EMMgetsinfraddr() against data from EMMgetframeaddr().\n");
- printf("Should succeed.\n");
- /* loop through framebuf, calling EMMgetsinfraddr() on each */
- for (loop = 0; loop < frames; loop++)
- {
- segaddr = EMMgetsinfraddr(framebuf[loop].frameno);
- weirdcodechk("EMMgetsinfraddr()", 0, framebuf, 0, 0);
- if (segaddr != framebuf[loop].segaddr)
- {
- printf("EMMgetsinfraddr(%u) succeeded but returned %u, not %u.\n",
- framebuf[loop].frameno, segaddr, framebuf[loop].segaddr);
- free(framebuf);
- exit(3);
- }
- }
- printf("EMMgetsinfraddr() returned all addresses OK.\n");
- TESTTAILER();
-
- /* clean up */
- free(framebuf);
-
- return;
- } /* end of do_frame_tests() */
-
-
- /*
- ** The following section of code is included only in the first tiny-model
- ** executable and in non-tiny-model executables.
- */
- #ifndef TINYPASS2
- #ifndef TINYPASS3
-
-
- /***************************************************************************
- * FUNCTION: DO_ALLOC_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests EMSLIB calls EMMcoreleft(), EMMalloc(), and *
- * EMMfree(). *
- * *
- * ENTRY: *
- * *
- * bytes - number of bytes of EMS to try to allocate. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void do_alloc_tests(unsigned long bytes)
- {
- unsigned long emsfree, emsfree2;
- unsigned long pagelen;
- int handle;
-
- /* get bytes value rounded up to nearest page, or 1 page if bytes == 0 */
- if (bytes != 0L)
- {
- pagelen = bytes + 16383L;
- pagelen &= 0xFFFFC000L;
- }
- else
- {
- pagelen = 16384L;
- }
-
- /* test coreleft */
- TESTHEADER();
- printf("Testing EMMcoreleft().\n");
- printf("Result should be multiple of 16384.\n");
- emsfree = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree, (emsfree / 16384L));
- TESTTAILER();
-
- /* make sure enough free */
- if (emsfree < (MINFREE * 16384L))
- {
- printf("Insufficient free EMS to perform all tests. Aborting.\n");
- exit(1);
- }
-
- /* test allocation */
- TESTHEADER();
- printf("Testing EMMalloc(%lu).\n", bytes);
- printf("Should succeed. Free EMS should drop by %lu bytes (%lu pages).\n",
- pagelen, (pagelen / 16384L));
- handle = test_EMMalloc(bytes);
- printf("EMMalloc() returned OK.\n");
- emsfree2 = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree2, (emsfree2 / 16384L));
- if ((emsfree - emsfree2) != pagelen)
- {
- printf("EMMalloc(%lu) caused free to drop weirdly from %lu to %lu.\n",
- bytes, emsfree, emsfree2);
- EMMfree(handle);
- exit(3);
- }
- TESTTAILER();
-
- /* test free */
- TESTHEADER();
- printf("Testing EMMfree() on handle just returned by EMMalloc().\n");
- printf(
- "Should succeed. Free EMS should increase by %lu bytes (%lu pages).\n",
- pagelen, (pagelen / 16384L));
- test_EMMfree(handle);
- printf("EMMfree() returned OK.\n");
- emsfree2 = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree2, (emsfree2 / 16384L));
- if (emsfree2 != emsfree)
- {
- printf("Freeing handle returned by EMMalloc() did not restore\n");
- printf(" free EMS count -- was %lu originally, now %lu.\n", emsfree,
- emsfree2);
- exit(3);
- }
- TESTTAILER();
-
- return;
- } /* end of do_alloc_tests() */
-
-
- /***************************************************************************
- * FUNCTION: DO_PALLOC_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests EMSLIB calls EMMcoreleft(), EMMallocpages(), *
- * and EMMfree(). *
- * *
- * ENTRY: *
- * *
- * pages - number of pages of EMS to try to allocate. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void do_palloc_tests(int pages)
- {
- unsigned long emsfree, emsfree2;
- unsigned long pagelen;
- int handle;
-
- /* convert pages to bytes */
- pagelen = 16384L * pages;
-
- /* test coreleft */
- TESTHEADER();
- printf("Testing EMMcoreleft().\n");
- printf("Result should be multiple of 16384.\n");
- emsfree = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree, (emsfree / 16384L));
- TESTTAILER();
-
- /* make sure enough free */
- if (emsfree < (MINFREE * 16384L))
- {
- printf("Insufficient free EMS to perform all tests. Aborting.\n");
- exit(1);
- }
-
- /* test allocation */
- TESTHEADER();
- printf("Testing EMMallocpages(%d).\n", pages);
- printf("Should succeed. Free EMS should drop by %lu bytes (%lu pages).\n",
- pagelen, (pagelen / 16384L));
- handle = test_EMMallocpages(pages);
- printf("EMMallocpages() retured OK.\n");
- emsfree2 = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree2, (emsfree2 / 16384L));
- if ((emsfree - emsfree2) != pagelen)
- {
- printf(
- "EMMallocpages(%d) caused free to drop weirdly from %lu to %lu.\n",
- pages, emsfree, emsfree2);
- EMMfree(handle);
- exit(3);
- }
- TESTTAILER();
-
- /* test free */
- TESTHEADER();
- printf("Testing EMMfree() on handle just returned by EMMallocpages().\n");
- printf(
- "Should succeed. Free EMS should increase by %lu bytes (%lu pages).\n",
- pagelen, (pagelen / 16384L));
- test_EMMfree(handle);
- printf("EMMfree() returned OK.\n");
- emsfree2 = test_EMMcoreleft();
- printf("EMMcoreleft() returned OK, shows %lu bytes (%lu pages) free.\n",
- emsfree2, (emsfree2 / 16384L));
- if (emsfree2 != emsfree)
- {
- printf("Freeing handle returned by EMMallocpages() did not restore\n");
- printf(" free EMS count -- was %lu originally, now %lu.\n", emsfree,
- emsfree2);
- exit(3);
- }
- TESTTAILER();
-
- return;
- } /* end of do_palloc_tests() */
-
-
- /***************************************************************************
- * FUNCTION: DO_NAME_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests EMSLIB calls EMMgetname() and EMMsetname(). *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void do_name_tests(void)
- {
- char name[9];
- int handle, status;
-
- TESTHEADER();
- printf("Testing EMMsetname() and EMMgetname().\n");
- if (_EMMversion < 0x40)
- {
- printf(
- "EMMsetname() should fail, EMMgetname() return empty buffer.\n");
- }
- else
- {
- printf("Should succeed.\n");
- }
- /* allocate some EMS to assign a name to */
- handle = test_EMMalloc(16384);
- printf("Calling EMMsetname() with name ABCDEFGH.\n");
- status = EMMsetname(handle, "ABCDEFGH");
- if (_EMMversion < 0x40)
- {
- nofailcheck("EMMsetname()", status, NULL, handle, 0);
- weirdretchk("EMMsetname()", status, NULL, handle, 0);
- weirdcodechk("EMMsetname()", EMM_BADVERS, NULL, handle, 0);
- printf("EMMsetname() failed OK.\n");
- }
- else
- {
- TRIPLECHECK("EMMsetname()", status, 0, NULL, handle, 0);
- printf("EMMsetname() succeeded.\n");
- }
- printf("Now calling EMMgetname().\n");
- status = EMMgetname(handle, name);
- TRIPLECHECK("EMMgetname()", status, 0, NULL, handle, 0);
- if (_EMMversion < 0x40)
- {
- if (farmemcheck((unsigned char far *) name, 9, '\0') != 0)
- {
- printf("A character in name is not null.\n");
- EMMfree(handle);
- exit(3);
- }
- }
- else
- {
- if (strcmp(name, "ABCDEFGH") != 0)
- {
- printf("Got name %s back.\n", name);
- EMMfree(handle);
- exit(3);
- }
- }
- printf("EMMgetname() succeeded.\n");
- test_EMMfree(handle);
- TESTTAILER();
-
- return;
- } /* end of do_name_tests() */
-
-
- /***************************************************************************
- * FUNCTION: DO_MAP_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests EMSLIB call EMMmappage(). *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void do_map_tests(void)
- {
- int handle1, handle2;
- int loop;
- int status;
-
- /* first, allocate some EMS to map */
- handle1 = test_EMMallocpages(6);
- handle2 = test_EMMallocpages(2);
-
- /* initial test of EMMmappage() */
- TESTHEADER();
- printf("Calling EMMmappage(frameno = 0, first handle, logpage = 0).\n");
- printf("Should succeed.\n");
- test_EMMmappage(0, handle1, 0);
- printf("EMMmappage() returned OK.\n");
- TESTTAILER();
-
- /* calling EMMmappage() with a bad logical page number */
- TESTHEADER();
- printf("Calling EMMmappage(frameno = 0, first handle, logpage = 6).\n");
- printf("Should fail.\n");
- status = EMMmappage(0, handle1, 6);
- nofailcheck("EMMmappage()", status, NULL, handle1, handle2);
- weirdretchk("EMMmappage()", status, NULL, handle1, handle2);
- weirdcodechk("EMMmappage()", EMM_BADLOGPAGE, NULL, handle1, handle2);
- printf("EMMmappage() failed OK.\n");
- TESTTAILER();
-
- TESTHEADER();
- printf("Writing data pattern to page 0, first handle... ");
- FMEMSET(frameptr[0], 0, 16384);
- printf("Verifying... ");
- if (farmemcheck(frameptr[0], 16384, 0) != 0)
- {
- printf("Verify failed!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- printf("OK.\n");
- printf("Calling EMMmappage(frameno = 0, first handle, logpage = 1).\n");
- test_EMMmappage(0, handle1, 1);
- printf("EMMmappage() returned OK.\n");
- printf("Writing data pattern to page 1, first handle... ");
- FMEMSET(frameptr[0], 1, 16384);
- printf("Verifying... ");
- if (farmemcheck(frameptr[0], 16384, 1) != 0)
- {
- printf("Verify failed!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- printf("OK.\n");
- printf("Now mapping page 0 back, see if it's still OK.\n");
- test_EMMmappage(0, handle1, 0);
- printf("EMMmappage() returned OK, verifying contents... ");
- if (farmemcheck(frameptr[0], 16384, 0) != 0)
- {
- printf("Verify failed!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- printf("OK.\n");
- printf("EMMmappage() looks like it's doing something.\n");
- TESTTAILER();
-
- TESTHEADER();
- printf("Testing mapping of all frames...\n");
- printf("Filling rest of allocated pages with unique patterns... ");
- for (loop = 2; loop < 6; loop++)
- {
- test_EMMmappage(0, handle1, loop);
- FMEMSET(frameptr[0], loop, 16384);
- if (farmemcheck(frameptr[0], 16384, (unsigned char) loop) != 0)
- {
- printf("Verify failed on handle 1, page %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- test_EMMmappage(0, handle2, 0);
- FMEMSET(frameptr[0], 0x10, 16384);
- if (farmemcheck(frameptr[0], 16384, 0x10) != 0)
- {
- printf("Verify failed on handle 2, page 0!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- test_EMMmappage(0, handle2, 1);
- FMEMSET(frameptr[0], 0x11, 16384);
- if (farmemcheck(frameptr[0], 16384, 0x11) != 0)
- {
- printf("Verify failed on handle 2, page 1!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- printf("Done.\n");
- printf("Mapping handle 1 pages 0-3 in frames 0-3 respectively... ");
- for (loop = 0; loop < 4; loop++)
- {
- test_EMMmappage(loop, handle1, loop);
- }
- printf("Done.\n");
- printf("Verifying contents... ");
- for (loop = 0; loop < 4; loop++)
- {
- if (farmemcheck(frameptr[loop], 16384, (unsigned char) loop) != 0)
- {
- printf("Verify failed for frame %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- printf("OK.\n");
- printf("Mapping handle 1 pages 0-3 in frames 0-3 in reverse... ");
- for (loop = 0; loop < 4; loop++)
- {
- test_EMMmappage(loop, handle1, (3 - loop));
- }
- printf("Done.\n");
- printf("Verifying contents... ");
- for (loop = 0; loop < 4; loop++)
- {
- if (farmemcheck(frameptr[loop], 16384, (unsigned char)(3 - loop)) != 0)
- {
- printf("Verify failed for frame %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- printf("OK.\n");
- printf(
- "Mapping handle 1 pages 0-3 in frames 0-3 except page 5 in frame 2... ");
- for (loop = 0; loop < 4; loop++)
- {
- test_EMMmappage(loop, handle1, loop);
- }
- test_EMMmappage(2, handle1, 5);
- printf("Done.\n");
- printf("Verifying contents... ");
- for (loop = 0; loop < 4; loop++)
- {
- if (farmemcheck(frameptr[loop], 16384,
- (unsigned char)((loop != 2) ? loop : 5)) != 0)
- {
- printf("Verify failed for frame %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- printf("OK.\n");
- TESTTAILER();
-
- TESTHEADER();
- printf("Final mapping test... two handles at once!\n");
- printf("Mapping handle2 page 1 in frame 0.\n");
- printf(" handle1 page 4 in frame 1.\n");
- printf(" handle1 page 0 in frame 2.\n");
- printf(" handle2 page 0 in frame 3.\n");
- test_EMMmappage(0, handle2, 1);
- test_EMMmappage(1, handle1, 4);
- test_EMMmappage(2, handle1, 0);
- test_EMMmappage(3, handle2, 0);
- printf("Mapping done. Verifying... ");
- if (farmemcheck(frameptr[0], 16384, 0x11) != 0)
- {
- printf("Verify failed for frame 0.\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- if (farmemcheck(frameptr[1], 16384, 4) != 0)
- {
- printf("Verify failed for frame 1.\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- if (farmemcheck(frameptr[2], 16384, 0) != 0)
- {
- printf("Verify failed for frame 2.\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- if (farmemcheck(frameptr[3], 16384, 0x10) != 0)
- {
- printf("Verify failed for frame 3.\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- printf("OK.\n");
- TESTTAILER();
-
- /* clean up */
- test_EMMfree(handle1);
- test_EMMfree(handle2);
-
- return;
- } /* end of do_map_tests() */
-
-
- /***************************************************************************
- * FUNCTION: DO_SR_TESTS *
- * *
- * DESCRIPTION: *
- * *
- * This function tests the EMSLIB mapping save/restore functions: *
- * EMMsrinit(), EMMsave(), EMMrestore(). *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void do_sr_tests(void)
- {
- void *savehandle;
- int handle1, handle2;
- int status;
- int loop;
-
- /* first, allocate some EMS and fill with unique patterns */
- handle1 = test_EMMallocpages(6);
- handle2 = test_EMMallocpages(2);
- for (loop = 0; loop < 6; loop++)
- {
- test_EMMmappage(0, handle1, loop);
- FMEMSET(frameptr[0], loop, 16384);
- if (farmemcheck(frameptr[0], 16384, (unsigned char) loop) != 0)
- {
- printf("Verify failed on handle 1, page %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- test_EMMmappage(0, handle2, 0);
- FMEMSET(frameptr[0], 0x10, 16384);
- if (farmemcheck(frameptr[0], 16384, 0x10) != 0)
- {
- printf("Verify failed on handle 2, page 0!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- test_EMMmappage(0, handle2, 1);
- FMEMSET(frameptr[0], 0x11, 16384);
- if (farmemcheck(frameptr[0], 16384, 0x11) != 0)
- {
- printf("Verify failed on handle 2, page 1!\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
-
- TESTHEADER();
- printf(
- "Testing save/restore facility. Calling EMMsave() before EMMsrinit().\n");
- printf("Should fail.\n");
- savehandle = EMMsave();
- nofailcheck("EMMsave()", (int) _EMMerror, NULL, handle1, handle2);
- weirdcodechk("EMMsave()", EMM_NOSR, NULL, handle1, handle2);
- printf("EMMsave() failed OK.\n");
- TESTTAILER();
-
- TESTHEADER();
- printf("Calling EMMsrinit().\nShould succeed.\n");
- status = EMMsrinit(malloc);
- TRIPLECHECK("EMMsrinit()", status, 0, NULL, handle1, handle2);
- printf("EMMsrinit() succeeded; save/restore facility initialized.\n");
- TESTTAILER();
-
- TESTHEADER();
- printf("Testing EMMsave().\n");
- printf("Mapping handle 1 pages 0-3 in frames 0-3 respectively.\n");
- for (loop = 0; loop < 4; loop++)
- {
- test_EMMmappage(loop, handle1, loop);
- }
-
- printf("Calling EMMsave() to save current configuration.\n");
- printf("Should succeed.\n");
- savehandle = (void *) NULL;
- savehandle = EMMsave();
- if (savehandle == (void *) NULL)
- {
- printf("EMMsave() did not return anything, code 0x%X.\n",
- (unsigned int) _EMMerror);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- weirdcodechk("EMMsave()", 0, NULL, handle1, handle2);
- printf("EMMsave() succeeded.\n");
- TESTTAILER();
-
- printf("Changing configuration.\n");
- test_EMMmappage(0, handle2, 1);
- test_EMMmappage(1, handle1, 4);
- test_EMMmappage(2, handle1, 0);
- test_EMMmappage(3, handle2, 0);
-
- TESTHEADER();
- printf("Calling EMMrestore() to restore previous configuration.\n");
- printf("Should succeed.\n");
- status = EMMrestore(savehandle);
- TRIPLECHECK("EMMrestore()", status, 0, NULL, handle1, handle2);
- printf("EMMrestore() returned OK, verifying contents... ");
- for (loop = 0; loop < 4; loop++)
- {
- if (farmemcheck(frameptr[loop], 16384, (unsigned char) loop) != 0)
- {
- printf("Verify failed for frame %d.\n", loop);
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- exit(3);
- }
- }
- printf("OK.\n");
- TESTTAILER();
-
- printf("Cleaning up.\n");
- test_EMMfree(handle1);
- test_EMMfree(handle2);
- free(savehandle);
-
- return;
- } /* end of do_sr_tests() */
-
- #endif
- #endif
-
-
- /*
- ** The following group of functions {test_EMM*()} are wrapper functions
- ** that call the EMSLIB function named and perform preliminary checks on
- ** the return values. This keeps code size down since the check only has
- ** to be coded in one place.
- */
-
- /***************************************************************************
- * FUNCTION: TEST_EMMCORELEFT *
- * *
- * DESCRIPTION: *
- * *
- * This function calls EMSLIB function EMMcoreleft() and checks the *
- * return value to see if it is a multiple of 16384 (the EMS page *
- * size). *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Returns the value returned by EMMcoreleft(). *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- unsigned long test_EMMcoreleft(void)
- {
- unsigned long emsfree;
-
- /* call EMMcoreleft and check error code */
- emsfree = EMMcoreleft();
- weirdcodechk("EMMcoreleft()", 0, NULL, 0, 0);
-
- /* check if free byte count is multiple of 16384 */
- if ((emsfree % 16384L) != 0)
- {
- printf("EMMcoreleft() returned strange number %lu.\n", emsfree);
- exit(3);
- }
-
- return emsfree;
- } /* end of test_EMMcoreleft() */
-
-
- /***************************************************************************
- * FUNCTION: TEST_EMMALLOC *
- * *
- * DESCRIPTION: *
- * *
- * This function calls EMSLIB function EMMalloc() and checks the *
- * return codes. *
- * *
- * ENTRY: *
- * *
- * bytes - bytes of EMS to allocate *
- * *
- * EXIT: *
- * *
- * Returns the handle returned by EMMalloc(). *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int test_EMMalloc(unsigned long bytes)
- {
- int handle;
-
- /* call EMMalloc() and check the return */
- handle = EMMalloc(bytes);
- weirdcodechk("EMMalloc()", 0, NULL, 0, 0);
-
- return handle;
- } /* end of test_EMMalloc() */
-
-
- /***************************************************************************
- * FUNCTION: TEST_EMMALLOCPAGES *
- * *
- * DESCRIPTION: *
- * *
- * This function calls EMSLIB function EMMallocpages() and checks the *
- * return codes. *
- * *
- * ENTRY: *
- * *
- * pages - pages of EMS to allocate *
- * *
- * EXIT: *
- * *
- * Returns the handle returned by EMMallocpages(). *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int test_EMMallocpages(int pages)
- {
- int handle;
-
- /* call EMMallocpages() and check the return */
- handle = EMMallocpages(pages);
- weirdcodechk("EMMallocpages()", 0, NULL, 0, 0);
-
- return handle;
- } /* end of test_EMMallocpages() */
-
-
- /***************************************************************************
- * FUNCTION: TEST_EMMFREE *
- * *
- * DESCRIPTION: *
- * *
- * This function calls EMSLIB function EMMfree() and checks the *
- * return codes. *
- * *
- * ENTRY: *
- * *
- * handle - EMS handle to be freed *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void test_EMMfree(int handle)
- {
- int status;
-
- /* call EMMfree() and check the return */
- status = EMMfree(handle);
- TRIPLECHECK("EMMfree()", status, 0, NULL, 0, 0);
-
- return;
- } /* end of test_EMMfree() */
-
-
- /***************************************************************************
- * FUNCTION: TEST_EMMMAPPAGE *
- * *
- * DESCRIPTION: *
- * *
- * This function calls EMSLIB function EMMmappage() and checks the *
- * return codes. *
- * *
- * ENTRY: *
- * *
- * frameno - frame number to map page into *
- * handle - handle of page to be mapped *
- * logpage - page number to map *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void test_EMMmappage(int frameno, int handle, int logpage)
- {
- int status;
-
- /*
- ** do sanity check on frame number, just in case -- we shouldn't be
- ** trying to map into frames other than standard 0 through 3.
- */
- if ((frameno < 0) || (frameno > 3))
- {
- printf("Sanity check failed, trying to map to frame %d, aborting.\n",
- frameno);
- EMMfree(handle);
- exit(3);
- }
-
- /* call EMMmappage() and check return */
- status = EMMmappage(frameno, handle, logpage);
- TRIPLECHECK("EMMmappage()", status, 0, NULL, handle, 0);
-
- return;
- } /* end of test_EMMmappage() */
-
-
- /*
- ** The following group of functions are used to speed up return checking
- ** and keep code size down, since the return check only has to be coded
- ** in one place. They are used in various macros to further compact and
- ** clarify the code.
- */
-
- /***************************************************************************
- * FUNCTION: WEIRDRETCHK *
- * *
- * DESCRIPTION: *
- * *
- * This function checks to see if the status value passed to it is *
- * either 0 or EMMOOPS, and assumes something has gone wrong if it *
- * is not. If something has gone wrong, does some clean up before *
- * exiting. *
- * *
- * ENTRY: *
- * *
- * function - name of function which may have goofed *
- * status - status value to check *
- * tofree1 - conventional memory block to be freed on exit. Not *
- * freed if NULL. *
- * tofree2 - EMS handle to be freed on exit. Not freed if 0. *
- * tofree2 - another EMS handle to be freed on exit. Not freed if 0. *
- * *
- * EXIT: *
- * *
- * Void, or may not return. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void weirdretchk(char *function, int status, void *tofree1, int tofree2,
- int tofree3)
- {
- if ((status != EMMOOPS) && (status != 0))
- {
- printf("%s returned weird value %d, code 0x%X.\n", function, status,
- (unsigned int) _EMMerror);
- if (tofree1 != (void *) NULL)
- {
- free(tofree1);
- }
- if (tofree2 != 0)
- {
- EMMfree(tofree2);
- }
- if (tofree3 != 0)
- {
- EMMfree(tofree3);
- }
- exit(3);
- }
-
- return;
- } /* end of weirdretchk() */
-
-
- /***************************************************************************
- * FUNCTION: WEIRDCODECHK *
- * *
- * DESCRIPTION: *
- * *
- * This function checks to see if the EMSLIB error code value matches *
- * the expected value, and assumes something has gone wrong if it *
- * does not. If something has gone wrong, does some clean up before *
- * exiting. *
- * *
- * ENTRY: *
- * *
- * function - name of function which may have goofed *
- * expected - expected value of _EMMerror *
- * tofree1 - conventional memory block to be freed on exit. Not *
- * freed if NULL. *
- * tofree2 - EMS handle to be freed on exit. Not freed if 0. *
- * tofree2 - another EMS handle to be freed on exit. Not freed if 0. *
- * *
- * EXIT: *
- * *
- * Void, or may not return. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void weirdcodechk(char *function, int expected, void *tofree1, int tofree2,
- int tofree3)
- {
- if ((int) _EMMerror != expected)
- {
- printf("%s returned unexpected code 0x%X.\n", function,
- (unsigned int) _EMMerror);
- if (tofree1 != (void *) NULL)
- {
- free(tofree1);
- }
- if (tofree2 != 0)
- {
- EMMfree(tofree2);
- }
- if (tofree3 != 0)
- {
- EMMfree(tofree3);
- }
- exit(3);
- }
-
- return;
- } /* end of weirdcodechk() */
-
-
- /***************************************************************************
- * FUNCTION: FAILCHECK *
- * *
- * DESCRIPTION: *
- * *
- * This function checks to see if the status value passed to it is *
- * EMMOOPS and exits if it is. failcheck() is used when a function *
- * is expected to succeed. Does some clean up before exiting. *
- * *
- * ENTRY: *
- * *
- * function - name of function which may have goofed *
- * status - status value to be checked *
- * tofree1 - conventional memory block to be freed on exit. Not *
- * freed if NULL. *
- * tofree2 - EMS handle to be freed on exit. Not freed if 0. *
- * tofree2 - another EMS handle to be freed on exit. Not freed if 0. *
- * *
- * EXIT: *
- * *
- * Void, or may not return. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void failcheck(char *function, int status, void *tofree1, int tofree2,
- int tofree3)
- {
- if (status == EMMOOPS)
- {
- printf("%s failed, code 0x%X.\n", function, (unsigned int) _EMMerror);
- if (tofree1 != (void *) NULL)
- {
- free(tofree1);
- }
- if (tofree2 != 0)
- {
- EMMfree(tofree2);
- }
- if (tofree3 != 0)
- {
- EMMfree(tofree3);
- }
- exit(3);
- }
-
- return;
- } /* end of failcheck() */
-
-
- /***************************************************************************
- * FUNCTION: NOFAILCHECK *
- * *
- * DESCRIPTION: *
- * *
- * This function checks to see if the status value passed to it is *
- * 0 and exits if it is. nofailcheck() is used when a function is *
- * expected to fail. Does some clean up before exiting. *
- * *
- * ENTRY: *
- * *
- * function - name of function which may have goofed *
- * status - status value to be checked *
- * tofree1 - conventional memory block to be freed on exit. Not *
- * freed if NULL. *
- * tofree2 - EMS handle to be freed on exit. Not freed if 0. *
- * tofree2 - another EMS handle to be freed on exit. Not freed if 0. *
- * *
- * EXIT: *
- * *
- * Void, or may not return. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void nofailcheck(char *function, int status, void *tofree1, int tofree2,
- int tofree3)
- {
- if (status == 0)
- {
- printf("%s did not fail.\n", function);
- if (tofree1 != (void *) NULL)
- {
- free(tofree1);
- }
- if (tofree2 != 0)
- {
- EMMfree(tofree2);
- }
- if (tofree3 != 0)
- {
- EMMfree(tofree3);
- }
- exit(3);
- }
-
- return;
- } /* end of nofailcheck() */
-
-
- /*
- ** The following functions are utility functions used to fill and check
- ** blocks of memory and perform other basic services. Many are coded in
- ** in-line assembly language to improve speed. The in-line assembly is
- ** compatible with both Turbo/Borland C[++] and MSC 6.00A. If your compiler
- ** does not support in-line assembly, or the compiler requires an external
- ** assembler which you do not have, the functions contain alternate C code.
- ** In fact, in order to get the in-line assembly, you must define the symbol
- ** INLINE_ASM.
- */
-
-
- /***************************************************************************
- * FUNCTION: FARMEMCHECK *
- * *
- * DESCRIPTION: *
- * *
- * This function scans a block of memory looking for bytes which do *
- * not match checkchar. *
- * *
- * ENTRY: *
- * *
- * buffer - pointer to block of memory to scan *
- * len - length of block *
- * checkchar - value which should be matched *
- * *
- * EXIT: *
- * *
- * Returns 0 if all bytes match, nonzero if mismatch found. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int farmemcheck(unsigned char far *buffer, unsigned int len,
- unsigned char checkchar)
- {
- int retval = 0;
- unsigned char huge *temp;
-
- /* normalize far pointer and turn into huge pointer */
- temp = normptr(buffer);
-
- #ifdef INLINE_ASM
- ASM push bx /* preserve registers */
- ASM push cx
- ASM push si
- ASM push ds
- ASM lds si, [temp] /* load pointer into DS:SI */
- ASM mov cx, [len] /* load length into CX */
- ASM mov bl, [checkchar] /* load match value into BX */
- looptop:
- ASM lodsb /* load next byte into AL */
- ASM cmp al, bl /* test against BL */
- ASM jne nomatch /* if not equal, exit loop */
- ASM loop looptop /* otherwise loop */
- ASM jmp match
- nomatch:
- ASM mov retval, 1 /* return nonzero on mismatch */
- match:
- ASM pop ds /* restore register values */
- ASM pop si
- ASM pop cx
- ASM pop bx
- #else
- for (; len; len--, temp++) /* do the same thing in C */
- {
- if (*temp != checkchar)
- {
- retval = 1;
- break;
- }
- }
- #endif
-
- return retval;
- } /* end of farmemcheck() */
-
-
- /***************************************************************************
- * FUNCTION: FARINCWORDFILL *
- * *
- * DESCRIPTION: *
- * *
- * Fill a region of memory with incrementing word (16 bit) values. *
- * Always starts at 0 value. *
- * *
- * ENTRY: *
- * *
- * buffer - pointer to block of memory *
- * len - length of block, must be even *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void farincwordfill(unsigned char far *buffer, unsigned int len)
- {
- unsigned char huge *temp;
- #ifndef INLINE_ASM
- int loop;
- int huge *filler;
- #endif
-
- /* turn length in bytes into length in words, convert pointer */
- len /= 2;
- temp = normptr(buffer);
-
- #ifdef INLINE_ASM
- ASM push ax /* preserve registers */
- ASM push cx
- ASM push di
- ASM push es
- ASM les di, [temp] /* load pointer into ES:DI */
- ASM mov cx, [len] /* load length into CX */
- ASM xor ax, ax /* zero AX */
- loop2top:
- ASM stosw /* store AX in memory, DI += 2 */
- ASM inc ax /* increment AX */
- ASM loop loop2top /* loop */
- ASM pop es /* restore register values */
- ASM pop di
- ASM pop cx
- ASM pop ax
- #else
- /* do the same thing in C */
- for (loop = 0, filler = (int huge *) temp; loop < len; loop++)
- {
- *filler = loop;
- }
- #endif
-
- return;
- } /* end of farincwordfill() */
-
-
- /***************************************************************************
- * FUNCTION: FARINCWORDCHECK *
- * *
- * DESCRIPTION: *
- * *
- * Scans a block of memory to make sure contents are incrementing *
- * word values. *
- * *
- * ENTRY: *
- * *
- * buffer - pointer to block of memory *
- * len - length of block of memory, must be even *
- * *
- * EXIT: *
- * *
- * Returns 0 if contents are OK, nonzero if mismatch found. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int farincwordcheck(unsigned char far *buffer, unsigned int len)
- {
- int retval = 0;
- unsigned char huge *temp;
- #ifndef INLINE_ASM
- int loop;
- int huge *filler;
- #endif
-
- /* convert length in bytes to length in words, convert pointer */
- len /= 2;
- temp = normptr(buffer);
-
- #ifdef INLINE_ASM
- ASM push ax /* preserve register values */
- ASM push bx
- ASM push cx
- ASM push si
- ASM push ds
- ASM lds si, [temp] /* load pointer into DS:SI */
- ASM mov cx, [len] /* load length into CX */
- ASM xor bx, bx /* zero BX */
- ASM dec bx /* decrement BX, ready for loop */
- loop3top:
- ASM inc bx /* increment BX to next value */
- ASM lodsw /* load next word into AX */
- ASM cmp ax, bx /* compare word in AX and BX */
- ASM loope loop3top /* loop while words are equal */
- ASM je done /* exited loop -- if last cmp */
- /* was equal, jump to end, else */
- ASM mov retval, 1 /* mismatch, set nonzero retval */
- done:
- ASM pop ds /* restore register values */
- ASM pop si
- ASM pop cx
- ASM pop bx
- ASM pop ax
- #else
- /* do the same thing in C */
- for (loop = 0, filler = (int huge *) temp; loop < len; loop++)
- {
- if (*filler != loop)
- {
- retval = 1;
- break;
- }
- }
- #endif
-
- return retval;
- } /* end of farincwordcheck() */
-
-
- /***************************************************************************
- * FUNCTION: FARINCLONGFILL *
- * *
- * DESCRIPTION: *
- * *
- * Fills a region of memory with incrementing longword (32 bit) *
- * values. This function was not coded in assembly because it has *
- * to handle regions > 64K, which is a pain in the neck. *
- * *
- * ENTRY: *
- * *
- * buffer - pointer to block of memory *
- * len - length of block of memory, must be multiple of 4 *
- * start - value to start incrementing from *
- * *
- * EXIT: *
- * *
- * Void. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void farinclongfill(unsigned char far *buffer, unsigned long len,
- unsigned long start)
- {
- unsigned long loop;
- unsigned long huge *filler;
-
- /* convert length in bytes to length in longwords */
- len /= 4;
- /* fill */
- for (loop = 0L, filler = (unsigned long huge *) normptr(buffer);
- loop < len; loop++, filler++)
- {
- *filler = start++;
- }
-
- return;
- } /* end of farinclongfill() */
-
-
- /***************************************************************************
- * FUNCTION: FARINCLONGCHECK *
- * *
- * DESCRIPTION: *
- * *
- * Scans a region of memory checking that it contains incrementing *
- * longword values. This function was not coded in assembly because *
- * it has to handle regions > 64K, which is a pain in the neck. *
- * *
- * ENTRY: *
- * *
- * buffer - pointer to block of memory *
- * len - length of block of memory *
- * start - value to start incrementing from *
- * *
- * EXIT: *
- * *
- * Returns 0 if values OK, nonzero if mismatch found. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int farinclongcheck(unsigned char far *buffer, unsigned long len,
- unsigned long start)
- {
- unsigned long loop;
- unsigned long huge *filler;
- int retval = 0;
-
- /* convert length in bytes to length in longwords */
- len /= 4;
- /* scan */
- for (loop = 0L, filler = (unsigned long huge *) normptr(buffer);
- loop < len; loop++, filler++)
- {
- if (*filler != start++)
- {
- retval = 1;
- break;
- }
- }
-
- return retval;
- } /* end of farinclongcheck() */
-
-
- /***************************************************************************
- * FUNCTION: GET_TICK *
- * *
- * DESCRIPTION: *
- * *
- * Retrieves the current timer count via BIOS call. For use when *
- * timing copies. The timer ticks 18.2 times per second. The value *
- * returned by this function has a jitter of -0,+(1/18.2) seconds. *
- * *
- * ENTRY: *
- * *
- * Void. *
- * *
- * EXIT: *
- * *
- * Returns the timer count. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- unsigned long get_tick(void)
- {
- unsigned long retval;
-
- #ifdef INLINE_ASM
- ASM push cx /* push register values */
- ASM push dx
- ASM xor ah, ah /* AH = 00h, get count call */
- ASM int 1Ah /* make call */
- ASM mov WORD PTR [retval + 2], cx /* save returned value */
- ASM mov WORD PTR [retval], dx
- ASM pop dx
- ASM pop cx
- #else
- union REGS r;
-
- /* do the same thing in C */
- r.h.ah = 0x0;
- int86(0x1A, &r, &r);
- retval = r.x.cx;
- retval <<= 16;
- retval |= r.x.dx;
- #endif
-
- return retval;
- } /* end of get_tick() */
-
-
- /*
- ** The following group of functions is the same in spirit as the preceding
- ** group, but already exist in the libraries of some compilers. These
- ** functions are only used if the symbol NO_FFUNC is defined, which should
- ** only be done when the compiler's library does not already contain these
- ** functions.
- */
- #ifdef NO_FFUNC
-
- /***************************************************************************
- * FUNCTION: FMEMCMP *
- * *
- * DESCRIPTION: *
- * *
- * A replacement _fmemcmp() function for compilers which do not have *
- * it in their libraries. Compares two regions of memory. *
- * *
- * ENTRY: *
- * *
- * buf1 - pointer to first region *
- * buf2 - pointer to second region *
- * n - length of regions *
- * *
- * EXIT: *
- * *
- * Returns 0 on match, negative if mismatch byte in buf1 is less than *
- * corresponding byte in buf2, positive if vice versa. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- int Fmemcmp(void far *buf1, void far *buf2, unsigned int n)
- {
- unsigned char huge *temp1, huge *temp2;
- int retval = 0;
- #ifndef INLINE_ASM
- int loop;
- #endif
-
- /* normalize pointers */
- temp1 = normptr((unsigned char far *) buf1);
- temp2 = normptr((unsigned char far *) buf2);
-
- #ifdef INLINE_ASM
- ASM push cx /* preserve register values */
- ASM push di
- ASM push si
- ASM push ds
- ASM push es
- ASM lds si, [temp1] /* load first pointer in DS:SI */
- ASM les di, [temp2] /* load second pointer in ES:DI */
- ASM mov cx, [n] /* load length in CX */
- ASM repz cmpsb /* compare while equal */
- ASM jcxz alldone /* if CX is 0, all were equal */
- ASM ja higher /* not equal, set return value */
- ASM mov [retval], -1
- ASM jmp alldone
- higher:
- ASM mov [retval], 1
- alldone:
- ASM pop es /* restore register values */
- ASM pop ds
- ASM pop si
- ASM pop di
- ASM pop cx
- #else
- /* do the same thing in C */
- for (loop = 0; loop < n; loop++, temp1++, temp2++)
- {
- if (*temp1 == *temp2)
- {
- continue;
- }
- retval = (int) (*temp1 - *temp2);
- break;
- }
- #endif
-
- return retval;
- } /* end of Fmemcmp() */
-
-
- /***************************************************************************
- * FUNCTION: FMEMSET *
- * *
- * DESCRIPTION: *
- * *
- * A replacement _fmemset() function for compilers which do not have *
- * it in their libraries. Sets a region of memory to a particular *
- * value. *
- * *
- * ENTRY: *
- * *
- * s - pointer to region of memory *
- * c - byte value to set memory to *
- * n - length of region *
- * *
- * EXIT: *
- * *
- * Returns s. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- void Fmemset(void far *s, int c, unsigned int n)
- {
- unsigned char huge *temp;
-
- /* normalize pointer */
- temp = normptr((unsigned char far *) s);
-
- #ifdef INLINE_ASM
- /* if length is odd, use slower way */
- if ((n % 2) == 1)
- {
- ASM push ax /* preserve register values */
- ASM push cx
- ASM push di
- ASM push es
- ASM les di, [temp] /* load pointer into ES:DI */
- ASM mov al, BYTE PTR [c] /* load value into AL */
- ASM mov cx, [n] /* load length into CX */
- ASM rep stosb /* store value in memory */
- ASM pop es /* restore register values */
- ASM pop di
- ASM pop cx
- ASM pop ax
- }
- else
- {
- /* otherwise use faster way, storing entire words at once */
- /* convert length in bytes to length in words */
- n /= 2;
- ASM push ax /* preserve register values */
- ASM push cx
- ASM push di
- ASM push es
- ASM les di, [temp] /* load pointer into ES:DI */
- ASM mov al, BYTE PTR [c] /* load value into AL */
- ASM mov ah, al /* load value into AH too */
- ASM mov cx, [n] /* load length into CX */
- ASM rep stosw /* store value in memory by words */
- ASM pop es /* restore register values */
- ASM pop di
- ASM pop cx
- ASM pop ax
- }
- #else
- /* do the same thing in C */
- for (; n; n--, temp++)
- {
- *temp = c;
- }
- #endif
-
- return;
- } /* end of Fmemset() */
-
- #endif
-
-
- /***************************************************************************
- * FUNCTION: NORMPTR (STATIC) *
- * *
- * DESCRIPTION: *
- * *
- * Normalizes a far pointer -- reduces the offset to the smallest *
- * possible value (somewhere between 0 and 0xF) by adding to the *
- * segment. *
- * *
- * ENTRY: *
- * *
- * norm - pointer to be normalized *
- * *
- * EXIT: *
- * *
- * Returns normalized pointer. *
- * *
- * CONSTRAINTS/SIDE EFFECTS: *
- * *
- ***************************************************************************/
- static unsigned char huge *normptr(unsigned char far *norm)
- {
- unsigned char huge *retval = (unsigned char huge *) norm;
-
- #ifdef INLINE_ASM
- ASM push cx /* preserve register values */
- ASM push di
- ASM push si
- ASM mov si, WORD PTR [retval] /* load offset into SI */
- ASM mov di, si /* load offset into DI too */
- ASM mov cl, 4 /* load 4 into CL */
- ASM shr di, cl /* shift DI right by 4, which */
- /* converts it to a segment */
- ASM add WORD PTR [retval + 2], di /* add to segment in pointer */
- ASM and si, 0Fh /* zero all but lowest nibble */
- /* of offset */
- ASM mov WORD PTR [retval], si /* put offset back in pointer */
- ASM pop si /* restore register values */
- ASM pop di
- ASM pop cx
- #else
- unsigned int segment, offset;
-
- /* do the same thing in C -- extract segment and offset from pointer */
- segment = FP_SEG(retval);
- offset = FP_OFF(retval);
- /* add high three nibbles of offset to segment */
- segment += (offset >> 4);
- /* preseve only lowest nibble of offset */
- offset &= 0xF;
- /* reconstruct pointer from modified segment and offset */
- retval = MK_FP(segment, offset);
- #endif
-
- return retval;
- } /* end of static normptr() */
-
-