home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-06 | 38.8 KB | 1,125 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
- swap()
-
-
- Version 2.0
- September 6, 1990
-
-
- Copyright (C) 1990
- by Marty Del Vecchio
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This package (swap) includes an MS-DOS assembly-language routine that
- can be called from a C program. It will swap most of the current
- program to extended memory (supplied by an XMS driver, such as
- HIMEM.SYS), expanded memory (EMS version 3.2 or 4.0), or disk, thus
- freeing up more memory for DOS. It will then execute another program
- in its place, and re-load the original program to its original state.
- This allows large DOS programs to execute other programs without the
- original program taking up DOS memory.
-
-
-
-
-
-
-
- Table of Contents
-
-
- I. Introduction . . . . . . . . . . . . . . . . . . . 1
-
- II. File List . . . . . . . . . . . . . . . . . . . .
-
- III. Functional Description . . . . . . . . . . . . . .
- A. DOS Memory Management . . . . . . . . . . . .
- B. How swap() Works . . . . . . . . . . . . . .
- C. Swapping to Different Media . . . . . . . . .
- 1. Extended Memory . . . . . . . . . . . .
- 2. Expanded Memory . . . . . . . . . . . .
- 3. DOS Disk File . . . . . . . . . . . . .
-
- IV. Calling the swap() Routine . . . . . . . . . . . .
- A. The swap() Return Code . . . . . . . . . . .
- B. Program File to Execute . . . . . . . . . . .
- C. Program Command Line . . . . . . . . . . . .
- D. EXEC Return Code Pointer . . . . . . . . . .
- E. Swap File Name . . . . . . . . . . . . . . .
-
- V. Customizing swap() . . . . . . . . . . . . . . . .
- A. Memory Model . . . . . . . . . . . . . . . .
- B. Swap Locations . . . . . . . . . . . . . . .
- C. Swap Order . . . . . . . . . . . . . . . . .
-
- VI. Information . . . . . . . . . . . . . . . . . . .
-
-
-
-
-
- I. Introduction
-
- Most DOS programmers have figured out how to load and execute another
- DOS program from inside their own program (using the DOS EXEC system call).
- Almost invariably, they discover a rather large problem: with their
- original program loaded in memory, there is little memory left over in which
- to run the child program. Often, there is not enough memory to run even a
- DOS shell.
-
- This package provides a solution to that problem. The swap() routine
- will swap the original program to extended memory, expanded memory, or disk,
- then free up that memory. It will then execute the DOS program specified by
- the caller. When that program terminates, the original program is loaded
- back into memory, and it continues execution.
-
- By default, the swap() routine will attempt to swap the current program
- to extended memory;if that fails, it will try expanded memory; if that
- fails, it will try a DOS disk file. By re-assembling the routine in
- (SWAP.ASM), the programmer can specify which combination of the above media
- to attempt to swap to, and in which order the swapping shall be attempted.
- Details are provided in Chapter V.
-
- These routines have been tested with DOS versions 3.30 and 4.01. They
- have been tested with Turbo C version 2.0, Microsoft C version 5.10, and
- Turbo C++ version 1.0. All of these compilers comply with the Microsoft DOS
- standard segment naming and ordering convention (called DOSSEG in MASM). If
- your C compiler does not support this convention, please contact me: these
- routines should be adaptable to any compiler.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 1
-
-
-
-
-
-
- II. File List
-
- The following files should be found in this release:
-
- SWAP.DOC This file. Documentation for use of the swap() routine.
- SWAP.ASM The assembly-language source file for the swap()
- routines. Requires the Microsoft Macro Assembler
- version 5.10 to assemble.
- SWAP.H Header file for SWAP.ASM. Contains function prototypes
- and constant definitions needed to use swap().
-
- SWAPS.OBJ swap() assembled for Small memory model.
- SWAPM.OBJ swap() assembled for Medium memory model.
- SWAPC.OBJ swap() assembled for Compact memory model.
- SWAPL.OBJ swap() assembled for Large memory model.
-
- SWAPXMS.OBJ swap() assembled for Small memory model, will only
- attempt to swap to XMS extended memory.
- SWAPEMS.OBJ swap() assembled for Small memory model, will only
- attempt to swap to EMS expanded memory.
- SWAPMEM.OBJ swap() assembled for Small memory model, will attempt to
- swap to extended memory, then expanded.
- SWAPDISK.OBJ swap() assembled for Small memory model, will only
- attempt to swap to DOS disk file.
-
- SWAP.MAK MAKE file to create all possible combinations of swap()
- routine (memory model vs. swap location).
-
- SWAPTEST.C Sample program that uses swap(). Demonstrates how to
- call swap().
- SWAPTEST.MSC MAKE file to create SWAPTEST.EXE with Microsoft C
- version 5.10.
- SWAPTEST.LNK Linker response file for SWAPTEST.EXE and Microsoft C.
- SWAPTEST.PRJ Project file to create SWAPTEST.EXE with Turbo C version
- 2.0.
- SWAPTEST.OBJ Object module file for SWAPTEST.C, compiled with
- Microsoft C version 5.10.
- SWAPTEST.EXE Sample executable demonstrating swap(), compiled with
- Microsoft C version 5.10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 2
-
-
-
-
-
-
- III. Functional Description
-
-
- A. DOS Memory Management
-
- The functionality of swap() depends on the simplicity and
- predictability of the DOS memory management system. The same system that
- was introduced in DOS version 1.0 in 1981 is still in use in DOS 4.01,
- released in 1989.
-
- Basically, DOS has 640K of memory to manage: the hex addresses from
- 0000 to 9FFF (understanding DOS segments is not a requirement of this
- package!). Once DOS is loaded, there is one large block of free memory. In
- front of this block is a 16-byte header called a Memory Control Block (MCB),
- which contains information about the block such as how large it is.
-
- Whenever a DOS program is loaded and executed, DOS allocates part of
- this block of memory and assigns it to the program. The program's block of
- memory gets its own MCB, and the remaining memory gets another MCB. DOS
- functions 48 hex (allocate memory block), 49 hex (free memory block), and 4A
- hex (change size of memory block) all affect the chain of memory blocks
- maintained by DOS.
-
- Here is a map of what happens when FATHER.EXE, a mythical example
- program, is loaded into DOS and then executes a child program (CHILD.EXE):
-
- Before executing CHILD Address While executing CHILD
- +------------------------+ 0000 +------------------------+
- + + + +
- + Used by DOS, TSRs + + Used by DOS, TSRs +
- +------------------------+ 2000 +------------------------+
- + + + +
- + FATHER.EXE, the + + FATHER.EXE +
- + current program + + +
- +------------------------+ 4000 +------------------------+
- + + + +
- + DOS Free Memory + + CHILD.EXE, the +
- + + + current program +
- + + + +
- + + 6000 + +
- + + + +
- + + + +
- + + + +
- + + + +
- + + +------------------------+
- + + + +
- + + + DOS Free Memory +
- + + + +
- + + + +
- +------------------------+ 9FFF +------------------------+
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 3
-
-
-
-
-
-
-
- As you can see, when CHILD.EXE is executed, DOS splits up the large
- "DOS Free Memory" block into two smaller blocks--one used by CHILD, and the
- other still marked as free. And notice that while CHILD is running, FATHER
- is still occupying a large block of DOS memory. This puts a limit on the
- size program that CHILD can be.
-
- In this picture, since there is free memory immediately after CHILD,
- CHILD can call DOS system function 4A hex to increase the size of its memory
- block. A program can always decrease the size of its memory block, as long
- as it no longer accesses information outside of its block. And finally, a
- program can call DOS system function 48 hex to allocate a new block of
- memory, if any DOS free memory exists.
-
-
- B. How swap() Works
-
- As stated above, DOS memory management is very predictable. The swap()
- routine takes advantage of this predictability in the following manner.
- Assume that the FATHER.EXE program above uses swap() to execute CHILD.EXE.
-
- 1) swap() takes the contents of the memory block that FATHER occupies
- and saves it outside of DOS memory (to extended memory, expanded
- memory, or disk).
-
- 2) swap() calls DOS system function 4A hex to shrink the size of
- FATHER's memory block. It makes this block as small as possible
- while still keeping the swap() routine in memory.
-
- 3) swap() calls DOS system function 4B hex to execute the CHILD.EXE
- program (as specified by the caller).
-
- 4) When CHILD.EXE terminates, swap() again calls DOS system function
- 4A hex, this time to restore FATHER's block to the same size it
- was before swap() was called.
-
- 5) Finally, swap() retrieves the original contents of FATHER's memory
- block (saved in step 1) and restores the FATHER.EXE program to its
- original state.
-
- The key here is step 4. We assume that the CHILD program is not a
- Terminate and Stay Resident (TSR) program, and that when it terminates, the
- memory it occupied is again free. If this is the case, the DOS system call
- 4A will predictably let us grow our memory block back to its original size.
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 4
-
-
-
-
-
-
- Following are maps of what happens in the above process:
-
- Before FATHER While CHILD is After CHILD ends
- executes CHILD executing and FATHER is restored
- +-------------------+-------------------+-------------------+ 0000
- + DOS, TSRs, etc. + DOS, TSRs, etc. + DOS, TSRs, etc. +
- +-------------------+-------------------+-------------------+ 2000
- + FATHER.EXE + FATHER (swap code)+ FATHER.EXE +
- + (original +-------------------+ (restored + 3000
- + size) + + to original +
- + + CHILD.EXE + size) +
- + + + +
- + + + +
- +-------------------+ +-------------------+ 6000
- + + + +
- + DOS Free Memory + + DOS Free Memory +
- + + + +
- + +-------------------+ +
- + + + +
- + + DOS Free Memory + +
- + + + +
- + + + +
- + + + +
- + + + +
- + + + +
- + + + +
- +-------------------+-------------------+-------------------+
-
- There are several restrictions on use of the swap() routine, but the
- bottom line is that swap() lets you free all but about 2 kilobytes
- (depending on memory model) of your program's memory for use by another
- program. Guidelines for using swap() are described in Chapter IV.
-
-
- C. Swapping to Different Media
-
- The swap() routine can be configured to swap your program to extended
- memory, expanded memory, or disk. This behavior can be customized, as
- discussed in Chapter V. This section details how swap() deals with each
- media.
-
-
- 1. Extended Memory
-
- Extended memory is a term used to describe memory available on 80286-
- and 80386-based personal computers that is not DOS memory. On such a PC,
- the first megabyte of memory (0K to 1024K) is used for DOS memory, system
- BIOS, adapter BIOS and memory, etc. Memory above 1024K is called extended
- memory. It is generally not used by DOS, which is designed to run on the
- 8086 processor, which can only address the first 1024K of memory.
-
- Until recently, there had been no standard way of allocating,
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 5
-
-
-
-
-
-
- addressing, and using this memory. Access to extended memory depended to
- some extent on a vendor's hardware design. The main problem was ownership
- of this memory--there was no standard way that one program (such as a disk
- cache) could tell another program that it owned a block of extended memory.
-
- Recently, however, the eXtended Memory Specification (XMS) was released
- by Microsoft and other companies. The XMS spec described a driver that
- controlled all of extended memory, and defined a programming interface to
- that driver that applications could use to allocate, use, and free extended
- memory. Microsoft ships such a driver (called HIMEM.SYS) with its Windows
- programs, and it is generally available on bulletin boards.
-
- In order for swap() to use extended memory, HIMEM.SYS (or an
- equivalent) must be loaded. If a system has extended memory, but is not
- running HIMEM.SYS, swap() will not be able to see the memory, and cannot use
- it.
-
- When swap() tries to use XMS extended memory, it first checks to see if
- HIMEM.SYS (or an equivalent) is loaded. It does this by calling the
- multiplex interrupt (2F hex) with 4300 hex in AX. If HIMEM.SYS is loaded,
- it returns 80 hex in AL.
-
- Once swap() confirms that HIMEM.SYS is loaded, it calculates how much
- extended memory it needs, and calls XMS function 09, allocate extended
- memory block. If this call fails (there is not enough extended memory
- free), the swap to extended memory fails. If the allocate call succeeds,
- swap() will call XMS function 0B hex, move extended memory block. It sets
- up a request packet to copy the contents of the current program's memory
- block into the extended memory block it has just allocated.
-
- The swap() routine will then shrink its DOS memory block, call the DOS
- EXEC function to execute the requested program, and restore the DOS memory
- block to its original size. Details on this are found in Chapter III.
-
- Once the executed program terminates, swap() again calls XMS function
- 0B hex to copy the contents of the program from extended memory back into
- the DOS memory block. Finally, XMS function 0A hex is called to free the
- allocated extended memory, and swap() returns to the caller.
-
- At this point, the original program resides in DOS memory just as it
- did before the call to swap(), and swap() has completely cleaned up its
- usage of XMS extended memory.
-
-
- 2. Expanded Memory
-
- Expanded memory is a special kind of memory that can be added to any
- PC, but that does not exist in the processor's address space. Lotus, Intel,
- and Microsoft (LIM) defined a specification of how to provide expanded
- memory in a PC and how to access it from an application program. The
- original specification was called LIM EMS 3.2, and it was updated to version
- 4.0 later. The swap() routine can use either version.
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 6
-
-
-
-
-
-
-
- Expanded memory is provided in a system in 16-kilobyte (16K) blocks
- called pages. An application can allocate and free any number of pages in
- units referred to by handles. When the application wants to copy data to or
- from a page, it asks the EMS driver to map that page into the PC's address
- space. The EMS driver has at a minimum four locations where it can map a
- page of expanded memory. These locations are found in the first megabyte of
- the PC address space, between 640K and 1 megabyte.
-
- When swap() tries to use EMS memory, it first checks to see if an EMS
- driver is loaded. It does this by looking at interrupt vector 67 hex. The
- string "EMM0XXXX" should be found 13 bytes after that vector address. If it
- is, an EMS driver is loaded.
-
- Once swap() confirms that an EMS driver is loaded, it calculates how
- many 16K expanded memory pages it needs, and calls EMS function 43 hex,
- allocate expanded memory pages. If this call fails (there is not enough
- expanded memory free), the swap to expanded memory fails.
-
- If this call succeeds, swap() will copy the contents of the current
- program to the expanded memory block in 16K blocks. To do this, swap() must
- repeatedly call EMS function 44 hex, map EMS pages to physical memory.
- After mapping each page (page 0, 1, etc.), swap() simply does a memory copy
- of 16K bytes. This process is repeated until the entire program has been
- saved to expanded memory.
-
- The swap() routine will then shrink its DOS memory block, call the DOS
- EXEC function to execute the requested program, and restore the DOS memory
- block to its original size. Details on this are found in Chapter III.
-
- Once the executed program terminates, swap() again calls EMS function
- 44 hex to map the expanded memory into physical memory. It will copy the
- contents of the program from expanded memory back into the DOS memory area
- in 16K blocks. Finally, EMS function 45 hex is called to free the allocated
- expanded memory, and swap() returns to the caller.
-
- At this point, the original program resides in DOS memory just as it
- did before the call to swap(), and swap() has completely cleaned up its
- usage of EMS expanded memory.
-
-
- 3. DOS Disk File
-
- The swap() routine can also use the DOS file system to temporarily save
- the contents of a program. Although swapping to a disk file is much slower
- than swapping to extended or expanded memory, it is just as effective.
-
- The name of the disk file to swap to is provided by the caller as a
- parameter (see Chapter IV). The swap() routine will call DOS function 3C
- hex to create the file (or truncate it if it already exists). The file will
- be hidden to provide a small amount of protection for the file. If this
- create fails, the swap to disk fails.
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 7
-
-
-
-
-
-
-
- Once the file is created, the swap() routine follows a procedure
- similar to the one outlined above in the description for swapping to EMS.
- The original program will be swapped in 32K blocks to the disk file, and the
- data will be written with DOS function 40 hex. If any call to this function
- fails, it most likely means that the disk is full. If this happens, swap()
- will delete the file and the swap to disk fails. Otherwise, swap() will
- continue to write 32K blocks until the entire program is saved.
-
- The swap() routine will then shrink its DOS memory block, call the DOS
- EXEC function to execute the requested program, and restore the DOS memory
- block to its original size. Details on this are found in Chapter III.
-
- When the executed program terminates, swap() will call DOS function 3D
- hex to open the swap file. If the file is not there, swap() cannot restore
- the original program. If this is the case, swap() will print an error
- message to the screen and terminate the program.
-
- If the file is there, swap() will simply read 32K chunks from the disk
- file into the DOS memory block using DOS function 3F hex. It will do this
- until the entire contents of the original program are restored. It will
- then call DOS function 41 hex to delete the swap file.
-
- At this point, the original program resides in DOS memory just as it
- did before the call to swap(), and swap() has completely cleaned up its
- usage of DOS file system.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 8
-
-
-
-
-
-
- IV. Calling the swap() Routine
-
- The swap() routine is designed to be called in a C program. This is
- the function prototype for swap():
-
- int swap (char *program_name,
- char *command_line,
- char *exec_return,
- char *swap_fname);
-
- For example, to execute a DOS command shell and display a directory of
- the C: drive, you would call swap() this way:
-
- swap_ret = swap ("C:\\COMMAND.COM", "/C dir c:",
- &exec_ret, "swap.fil");
-
- When building a program with swap(), you should put the swap() object
- module as early in the linker list as possible. In Turbo C, it should be
- the first line in the project file (see SWAPTEST.PRJ). For Microsoft C, it
- should be the first object module in the link line (or linker response file,
- see SWAPTEST.LNK).
-
- The swap() routine also returns an int return code to the caller.
- Following are descriptions for this return code and each of these
- parameters.
-
-
- A. The swap() Return Code
-
- The swap() function returns an integer signifying the success or
- failure of the swap and execute. There are four possible return codes,
- defined in SWAP.H and here:
-
- 0: SWAP_OK Success--current program swapped, new program
- executed, and original program restored.
- 1: SWAP_NO_SHRINK Unable to shrink DOS memory block size. This
- indicates an error in the DOS Memory Control Block
- chain. This is unlikely.
- 2: SWAP_NO_SAVE Unable to save the program to any one of extended
- memory, expanded memory, or disk (depending on
- which functions were assembled). The new program
- was not executed.
- 3: SWAP_NO_EXEC Unable to execute the new program. If swap()
- returns this code, the parameter exec_return (see
- below) contains the DOS error code.
-
- In addition to these return codes, there is another type of error that
- can occur in swap() that cannot be returned to the caller. If swap() is
- unable to restore the original program after calling the DOS EXEC function,
- it cannot return to the caller, because the caller no longer exists in DOS
- memory!
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 9
-
-
-
-
-
-
- This error can occur for various reasons. If the program was swapped
- to disk, and the disk file was erased by the executed program, swap() has
- nothing to restore. In addition, errors encountered in the XMS or EMS
- driver can cause this.
-
- If this happens, swap() takes the only recourse it can. It prints the
- following message to the screen (the standard error location):
-
- SWAP: Unable to restore program.
-
- It then calls the DOS terminate function (4C hex) and returns 255 (FF hex)
- as the return code. This code can be queried using the DOS ERRORLEVEL
- function. For example, take this batch file:
-
- Echo About to execute program that demonstrates swap():
- swaptest
- if errorlevel 255 echo ERROR--swap() was unable to restore program!
-
-
- B. Program File to Execute
-
- The first parameter, program_name, is a pointer to a null-terminated
- string that contains the full path and file name of the program to be
- executed. For example, if you wanted to execute a program called TEST.EXE
- which is located in C:\UTIL, you must call swap() this way:
-
- swap_ret = swap ("C:\\UTIL\\TEST.EXE", "", &exec_ret, "swap.fil");
-
- The swap() routine will NOT perform any of the following functions:
-
- -- Search the DOS PATH environment variable for a program to execute
- -- Redirect input or output with "<" or ">"
- -- Execute a batch file
-
- These functions cannot be performed by swap() because they are functions of
- the DOS command processor (COMMAND.COM), and not of the DOS EXEC function
- that swap() uses. In order to do any of these things, you must explicitly
- invoke the command processor with the "/C" parameter, which tells
- COMMAND.COM to execute the following command. For example, to execute a DIR
- command and redirect the output to "DIR.OUT", you would call swap() this
- way:
-
- char *comspec;
- comspec = getenv ("COMSPEC");
- swap_ret = swap (comspec, "/C dir >dir.out", &exec_ret, "swap.fil");
-
- The getenv() function is available in Turbo C and Microsoft C to search
- the current environment for a string. We use it here to determine where the
- DOS command processor is.
-
- When passing the program name parameter to swap(), remember that the
- "\" character, used by DOS as a directory and file name separator, is used
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 10
-
-
-
-
-
-
- by C to indicate an escape character. Thus, to specify the file
- C:\UTIL\TEST.EXE, you must pass it as "C:\\UTIL\\TEST.EXE".
-
- The program to be executed MUST NOT be a Terminate and Stay Resident
- (TSR) program. If it is, swap() will not be able to grow the original
- program's DOS memory block back to its original size, and thus the original
- program cannot be re-loaded.
-
- Finally, remember that the name of the program file to be executed can
- be up to 127 characters (not including the null byte) long. It is the
- responsibility of the caller to ensure that the file name is not longer than
- 127 characters.
-
-
- C. Program Command Line
-
- The second parameter passed to swap() is the command line for the
- program to be run. It is a pointer to a null-terminated string that can be
- between 0 and 127 characters (not including the null byte). This string
- should NOT include the name of the program to be executed--that should be
- passed as a separate parameter as described above.
-
- For example, to call PKZIP.EXE and have it store files in TEST.ZIP, you
- would call swap() this way:
-
- swap_ret = swap ("C:\\UTIL\\PKZIP.EXE", "-r -P test.zip *.*",
- &exec_ret, "swap.fil");
-
- It is the responsibility of the caller to ensure that the command line
- parameter string is not longer than 127 characters.
-
-
- D. EXEC Return Code Pointer
-
- The exec_return is a pointer to a char (8-bit value) where swap() will
- return information from the DOS EXEC function. What is stored in this
- location depends on whether the swap() routine was successful or not.
-
- If swap() is successful (and returns 0, SWAP_OK described above),
- exec_return contains the return code of the executed program. This is the
- same value used in the DOS ERRORLEVEL comparison. For example, if you
- execute PKUNZIP.EXE, and it gives the return code 0, meaning success, the
- byte pointed to by exec_return will be set to 0 by swap().
-
- If swap() is unsuccessful when trying to execute the new program (and
- returns 3, SWAP_NO_EXEC), swap() will place the DOS error code returned by
- EXEC in this value. According to the DOS technical reference manual, this
- code will be one of the following (as defined in SWAP.H):
-
- 0x01: BAD_FUNC Bad DOS function number--unlikely
- 0x02: FILE_NOT_FOUND File not found--couldn't find program_name
- 0x05: ACCESS_DENIED Access denied--couldn't open program_name
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 11
-
-
-
-
-
-
- 0x08: NO_MEMORY Insufficient memory to run program_name
- 0x0A: BAD_ENVIRON Invalid environment segment--unlikely
- 0x0B: BAD_FORMAT Format invalid--unlikely
-
- Here is an example of how to handle error codes:
-
- char swap_ret, exec_ret;
-
- swap_ret = swap ("C:\\UTIL\\PKUNZIP.EXE", "D:TEST.ZIP",
- &exec_ret, "swap.fil");
- switch (swap_ret)
- {
- case SWAP_OK: printf ("Successful, program returned %d.",
- (int)exec_ret);
- break;
- case SWAP_NO_SHRINK: printf ("Unable to shrink DOS memory block.");
- break;
- case SWAP_NO_SAVE: printf ("Unable to save program.");
- break;
- case SWAP_NO_EXEC: printf ("EXEC call failed. DOS error is: ");
- switch (exec_ret)
- {
- case BAD_FUNC:
- printf ("Bad function.\n"); break;
- case FILE_NOT_FOUND:
- printf ("File not found.\n"); break;
- case ACCESS_DENIED:
- printf ("Access denied.\n"); break;
- case NO_MEMORY:
- printf ("Insufficient memory.\n"); break;
- case BAD_ENVIRON:
- printf ("Bad environment.\n"); break;
- case BAD_FORMAT:
- printf ("Bad format.\n"); break;
- }
- break;
- }
-
-
- E. Swap File Name
-
- The final parameter, swap_fname, is a pointer to a null-terminated
- string that contains the name of a DOS file to swap the program to. This is
- only needed if the version of swap() you are using will try to swap to disk
- (see Chapter V). If your version of swap() does not swap to disk at all,
- you can pass the null string (""). This parameter will only be used if
- swap() actually does try to swap to disk.
-
- This file name need not be a complete drive, directory, and path name.
- If the drive is not specified, it will be placed on the current drive; if
- the directory is not specified, it will be placed in the current directory.
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 12
-
-
-
-
-
-
- It is up to the caller to choose a safe file name for swapping. You
- should not choose the name of a file that already exists, as that file's
- contents will be lost when swap() truncates it. Because of this, you should
- be very careful not to specify the same file name for two different programs
- that use swap().
-
- For example, if you have a program called A.EXE which uses swap to call
- program B.EXE, which uses swap() to call program C.EXE, you must choose
- different swap file names. If you use the same name (such as
- "C:\\SWAP.FIL") for both, you will have a problem. When A.EXE executes
- B.EXE, c:\swap.fil will be created, and will contain the contents of A.EXE.
- When B.EXE executes C.EXE and swaps to c:\swap.fil, the original contents of
- the file will be erased and replaced with the contents of B.EXE. When C.EXE
- terminates, c:\swap.fil will be read and deleted. Then when B.EXE
- terminates, the swap() routine in A.EXE will not find c:\swap.fil, and
- cannot reload A.EXE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 13
-
-
-
-
-
-
- V. Customizing swap()
-
-
- As stated above, the default configuration for swap() is a Small memory
- model function that attempts to swap in the following order:
-
- 1) XMS extended memory
- 2) EMS expanded memory
- 3) DOS disk file
-
- You can use the included source file (SWAP.ASM) and the Microsoft Macro
- Assembler (MASM) version 5.10 to create a customized version of the swap()
- routine. To assemble the default version of swap(), you would execute MASM
- this way:
-
- masm swap /mx;
-
- This will create SWAP.OBJ. You must include "/mx" on the MASM command line
- to tell the assembler to maintain the case of all variables and functions
- declared there. This allows the C program to access these items.
-
- This chapter describes how to create a customized version of swap().
-
-
- A. Memory Model
-
- The swap() routine supports four different C memory models, as defined
- by Microsoft C and Turbo C. The memory model specifies the number of
- segments for code and data, and therefore the size of a code or data
- pointer. These memory models are:
-
- Small One code segment, one data segment
- Medium Multiple code segments, one data segment
- Compact One code segment, multiple data segments
- Large Multiple code segments, multiple data segments
-
- The swap() source file (SWAP.ASM) can be configured to support any of
- these memory models with a command-line parameter to MASM. The parameter is
- "/D" followed by the memory model name. For example, to create a Large-
- model version of swap, you would assemble SWAP.ASM this way:
-
- masm swap /DLarge;
-
- This will create SWAP.OBJ that supports the Large memory model. Case does
- not matter when specifying the memory model. If no model is specified, the
- Small model is assumed.
-
- In addition to the above memory models, the Huge model should also be
- supported by assembling swap() for the Large model.
-
-
- B. Swap Locations
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 14
-
-
-
-
-
-
-
- The swap() routine will swap a program to extended memory, expanded
- memory, or disk file. If you do not want swap() to swap to all of these
- locations, you can re-assemble a custom version. However, it is more
- flexible to allow swap() to try all three locations, and the extra code
- needed is minimal.
-
- This is also done with the "/D" switch to MASM, followed by one of the
- following: "xms" for extended memory, "ems" for expanded memory, and "disk"
- for disk file. For example, to assemble a version of swap() that only
- attempts to swap to extended memory, you would say:
-
- masm swap /Dxms;
-
- To assemble a version of swap() that attempts to swap to extended or
- expanded memory, you would say:
-
- masm swap /Dxms /Dems;
-
-
- C. Swap Order
-
- By default, swap() attempts to swap the original program to extended
- memory; if that fails, to expanded memory; and if that fails, to disk.
- Naturally, it will only try each location if that location was specified
- (see B. above).
-
- If you want to change the order in which swap() attempts to save the
- program, you must change the source file SWAP.ASM manually. Towards the end
- of the file, there is a routine called save_program. It contains three
- blocks of code:
-
- ; ********************************************************************
- IFDEF USE_XMS
- IF1
- %out -- XMS extended memory
- ENDIF
- call save_xms ; Try saving to XMS extended memory
- jnc save_ok ; Carry clear == success, all done
- ENDIF
- ; ********************************************************************
-
-
- ; ********************************************************************
- IFDEF USE_EMS
- IF1
- %out -- EMS expanded memory
- ENDIF
- call save_ems ; Try saving to EMS expanded memory
- jnc save_ok ; Carry clear == success, all done
- ENDIF
- ; ********************************************************************
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 15
-
-
-
-
-
-
-
-
- ; ********************************************************************
- IFDEF USE_DISK
- IF1
- %out -- DOS disk file
- ENDIF
- call save_disk ; Try saving to DOS disk file
- jnc save_ok ; Carry clear == success, all done
- ENDIF
- ; ********************************************************************
-
- These blocks are separated by lines of asterisks. If you wanted swap()
- to try expanded memory, then extended memory, then disk, you would move the
- middle block (IFDEF USE_EMS to ENDIF) before the middle block. This is
- easily accomplished with most text editors.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 16
-
-
-
-
-
-
- VI. Information
-
- The original version of swap() was released as SWAP100.ZIP on April 1,
- 1990. That version supported swapping to expanded memory and to disk, and
- only the Small memory model was supported.
-
- Since then, I have had several requests to support more memory models.
- After prodding from people such as Norman Hamer (Seattle) and William Wood
- (Burke, VA), I finally found the time to do this. In addition, I added
- support for XMS extended memory, and also made the swap() routine
- configurable as described in Chapter V.
-
- This version of swap(), like the previous version, is hereby released
- into the public domain for free use by anybody and everybody. However, all
- the contents of this package still remain:
-
- Copyright (C) 1990 by Marty Del Vecchio. All Rights Reserved.
-
-
- I am not requesting a donation from anybody who uses the contents of
- this package. I just ask that everybody who does use swap() realize the
- amount of work that went into coding it, and appreciate the fact that I
- fully commented and released the source code for free.
-
- Everything in this package is provided with no warranties whatsoever,
- express nor implied, for any functionality or fitness for a specific
- purpose. The author will not be held responsible for any damages whatsoever
- resulting from the use of this package, and will not be held responsible if
- the package does not perform. User beware!
-
- My home address is:
-
- Marty Del Vecchio
- 99 Marlboro Road
- Southborough, MA 01772
-
- My home phone number is:
-
- (508) 485-9718
-
- My internet mail address is:
-
- marty@bsn.mceo.dg.com
-
- My main bulletin board is:
-
- Channel 1 BBS
- Boston, MA
- (617) 354-8873
-
-
-
-
-
- SWAP.DOC Copyright (C) 1990 by Marty Del Vecchio 17
-
-
-