home *** CD-ROM | disk | FTP | other *** search
- /* DOSSWAP.C - Functions to manage DOS swap areas */
-
- #include <stdlib.h>
- #include <dos.h>
- #include <memory.h>
- #include "tsr.h"
-
- #define GET_DOSSWAP3 0x5d06
- #define GET_DOSSWAP4 0x5d0b
-
- #define SWAP_LIST_LIMIT 20
-
- struct swap_list /* format of DOS 4+ SDA list */
- {
- void far* swap_ptr;
- int swap_size;
- };
-
- /* variables for 3.x swap work */
- static char far * swap_ptr; /* pointer to dos swap area */
- static char far * swap_save; /* pointer to our local save area */
- static int swap_size_indos;
- static int swap_size_always;
- static int size;
-
- /* variables for 4.x swap work */
- static int swap_count; /* count of swappable areas */
- static struct swap_list swp_list[SWAP_LIST_LIMIT]; /*list of swap areas*/
- static char far *swp_save[SWAP_LIST_LIMIT]; /* out save area */
- static int swp_flag[SWAP_LIST_LIMIT]; /* flags if has been swapped */
-
- static int dos_level; /* for level dependent code */
- int dos_critical; /* in critical section, can't swap */
-
- /*****
- Function: InitDosSwap
- Initialize pointers and sizes of DOS swap area. Return zero if success
- *****/
- int InitDosSwap(void)
- {
- union REGS regs;
- struct SREGS segregs;
-
- if ((_osmajor == 3) && (_osminor >= 10))
- dos_level = 3;
- else if (_osmajor >= 4)
- dos_level = 4;
- else
- dos_level = 0;
-
- if (dos_level == 3) /* use 215D06 */
- {
- regs.x.ax = GET_DOSSWAP3;
- intdosx(®s,®s,&segregs);
- /* pointer to swap area is returned in DS:SI */
- FP_SEG(swap_ptr) = segregs.ds;
- FP_OFF(swap_ptr) = regs.x.si;
-
- swap_size_indos = regs.x.cx;
- swap_size_always= regs.x.dx;
-
- size = 0; /* initialize for later */
- return ((swap_save = malloc(swap_size_indos)) == 0);
- }
- /*
- NOTE: Next line changed from version in UNDOCUMENTED DOS, p. 322
- (first printing), where we tested DOS version number with == and
- thereby lose the opportunity to run in DOS 5. This was just the
- sort of thing we had warned against in Chapter 2 of the book!
- */
- else if (dos_level >= 4) /* use 5d0b */
- {
- struct swap_list far *ptr;
- int far *iptr;
- int i;
- regs.x.ax = GET_DOSSWAP4;
- intdosx(®s,®s,&segregs);
- /* pointer to swap list is returned in DS:SI */
- FP_SEG(iptr) = segregs.ds;
- FP_OFF(iptr) = regs.x.si;
- swap_count = *iptr; /* get size of list */
- iptr++;
- ptr = (struct swap_list far *) iptr; /* create point to list */
-
- if (swap_count > SWAP_LIST_LIMIT) /* too many data areas */
- return 2;
-
- /* get pointers and sizes of data areas */
- for (i = 0; i < swap_count; i++)
- {
- swp_list[i].swap_ptr = ptr->swap_ptr;
- swp_list[i].swap_size= ptr->swap_size;
- if (! (swp_save[i] = malloc(swp_list[i].swap_size & 0x7fff)))
- return 3; /* out of memory */
- swp_flag[i] = 0;
- ptr++; /* point to next entry in the list */
- }
- return 0;
- }
- else
- return 1; /* unsupported DOS */
- }
-
- /*****
- Function: SaveDosSwap
- This function will save the dos swap area to a local buffer
- It returns zero on success, non-zero meaning can't swap
- *****/
- int SaveDosSwap(void)
- {
- if (dos_level == 3)
- {
- if (swap_ptr && !dos_critical)
- {
- /* if INDOS flag is zero, use smaller swap size */
- size = (*indos_ptr) ? swap_size_indos : swap_size_always;
-
- movedata(FP_SEG(swap_ptr), FP_OFF(swap_ptr),
- FP_SEG(swap_save), FP_OFF(swap_save),
- size);
- }
- else /* can't swap it */
- return 1;
- }
- else if (dos_level == 4)
- {
- /* loop through pointer list and swap appropriate items */
- int i;
- for (i = 0; i < swap_count; i++)
- {
- if (swp_list[i].swap_size & 0x8000) /* swap always */
- {
- movedata(FP_SEG(swp_list[i].swap_ptr),
- FP_OFF(swp_list[i].swap_ptr),
- FP_SEG(swp_save[i]),
- FP_OFF(swp_save[i]),
- swp_list[i].swap_size & 0x7fff);
- }
- else if (*indos_ptr) /* swap only if dos busy */
- {
- movedata(FP_SEG(swp_list[i].swap_ptr),
- FP_OFF(swp_list[i].swap_ptr),
- FP_SEG(swp_save[i]),
- FP_OFF(swp_save[i]),
- swp_list[i].swap_size);
- }
- }
- }
- else
- return 1;
-
- return 0;
- }
-
- /*****
- Function: RestoreDosSwap
- This function will restore a previously swapped dos data area
- *****/
- void RestoreDosSwap(void)
- {
- if (dos_level == 3)
- {
- /* make sure its already saved and we have a good ptr */
- if (size && swap_ptr)
- {
- movedata(FP_SEG(swap_save), FP_OFF(swap_save),
- FP_SEG(swap_ptr), FP_OFF(swap_ptr), size);
- size = 0;
- }
- }
- else if (dos_level == 4)
- {
- int i;
- for (i = 0; i < swap_count; i++)
- {
- movedata(FP_SEG(swp_save[i]),
- FP_OFF(swp_save[i]),
- FP_SEG(swp_list[i].swap_ptr),
- FP_OFF(swp_list[i].swap_ptr),
- swp_list[i].swap_size);
- swp_flag[i] = 0; /* clear flag */
- }
- }
- }
-