📄 dosswap.c
字号:
/* 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 */
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -