Category : Files from Magazines
Archive   : TSRPLUS.ZIP
Filename : TSRINIT.C

 
Output of file : TSRINIT.C contained in archive : TSRPLUS.ZIP

/* --------- tsrinit.c --------- */

/*
* The discardable TSR initialization code. Its memory is
* returned to DOS when the program becomes resident.
*/

#include "tsr.h"

static void writetsr(void);
static void load_tsr(void);
static void intercept_mouse(void);

void dispstr(char *);
void dispnum(int n);
extern char codeend;

static BOOL compare(char far *s1, char *s2)
{
while (*s2 && *s1 == *s2)
s1++, s2++;
return *s2 == '\0';
}

void main(void)
{
unsigned sizeprogram;

/* --------- DOS exec parameter block ---------- */
struct pblk {
unsigned env;
unsigned cmdoff;
unsigned cmdseg;
unsigned fcb1off;
unsigned fcb1seg;
unsigned fcb2off;
unsigned fcb2seg;
} pb = { 0, 0, 0, 0x5c, 0, 0x6c };

char far *argv = MK_FP(_psp, 0x80);
char far *env = MK_FP(peek(_psp, 0x2c),0);
int clen;
void interrupt (*int0)(void);
int rtn = 0;
BOOL sw = TRUE;
char path[64];
char *cp = path, *cp1 = NULL, *cp2 = SwapPath;
char pn[] = OVERLAYFILE;
char cmdline[] = {0, '\r'};
unsigned ax, opt;

/* ------ test if TSRPLUS is already resident ----- */
_AX = PLUSIDENT;
geninterrupt(TSRPLUSINT);
if (_AL == 0xff) {
dispstr("\r\nAlready resident\a\r\n");
return;
}

/* -------- find the TEMP environment variable ------- */
while (*env) {
if (compare(env, "TEMP")) {
env += 4;
while (*env == ' ' || *env == '=')
env++;
while ((*cp2 = *env) != '\0')
cp2++, env++;
}
while (*env)
env++;
env++;
}
/* ------- get the path to where program runs from ------- */
env += 3;
while (*env) {
if (*env == '\\')
cp1 = cp+1;
*cp++ = *env++;
}
if (cp1)
strcpy(cp1, pn);

/* ------- get command line arguments --------- */
clen = *argv++;

while (clen > 0) {
while (clen > 0 && *argv == ' ') {
argv++;
--clen;
}
opt = *argv;
if (opt >= 'a' && opt <= 'z') /* cheap toupper */
opt -= 0x20;
switch (opt) {
case '+': /* --- next argument is positive --- */
sw = TRUE;
break;
case '-': /* --- next argument is negative --- */
sw = FALSE;
break;
case 'X': /* --- use XMS for swap --- */
UseXMS = sw;
break;
case 'E': /* --- use EMS for swap --- */
UseEMM = sw;
break;
case 'P': /* --- swap file disk path --- */
sw = TRUE;
argv++;
--clen;
cp = SwapPath;
while (clen && *argv != ' ' && *argv != '\r') {
*cp++ = *argv++;
--clen;
}
--argv;
clen++;
break;
default:
break;
}
argv++;
--clen;
}

if (*SwapPath) {
char lcn[] = "000";
char *cp = SwapPath + strlen(SwapPath);
if (*(cp-1) != '\\')
*cp++ = '\\';
strcpy(cp, SWAPFILE);
#ifdef NETWARE
/* ------ get logical connection number ------ */
_AH = 0xdc;
geninterrupt(DOS);
lcn[1] = _CL;
lcn[2] = _CH;
#endif
strcat(cp, lcn);
}

/* ---------- get xms and emm indicators ------------ */
xms = xms_present();
emm = (emm_present() && emm_working());
if (emm)
frame = emm_pageframe();

if (_CS > 0xa000) {
dispstr("\a\r\nCannot loadhigh\r\n");
return;
}

/* ------ get address of DOS busy flag ---- */
_AH = 0x34;
geninterrupt(DOS);
dossegmnt = _ES;
dosbusy = _BX;

/* ----- get address of resident program's dta ----- */
mydta = getdta();
/* --------- get mouse IRQ to intercept on popup ------- */
intercept_mouse();
/* ------------ prepare for residence ------------ */

newvectors(vectors);
sendvectors();

/* ------ compute program size ------- */
highmemory = _CS + ((unsigned)&codeend / 16);
sizeprogram = highmemory - _psp;

/* ------ adjust MCB for TSRPLUS ------- */
_ES = _psp;
_BX = sizeprogram;
_AX = 0x4a00;
geninterrupt(DOS);

/* ----- set these vectors so they'll be swapped in ----- */
newvectors(critvects);
/*
* load program in before TSRPLUS becomes resident
*/
swaperror = FALSE;
int0 = getvect(0);
pb.fcb1seg = _DS;
pb.fcb2seg = _DS;
pb.cmdseg = _DS;
pb.env = peek(_psp, 0x2c);
pb.cmdoff = (unsigned) cmdline;
_ES = _DS;
_DX = (unsigned) path;
_BX = (unsigned) &pb;
_AX = 0x4b00;
geninterrupt(DOS);
ax = _AX;
if (_FLAGS & CARRYBIT)
rtn = -1;
else {
/* ----- test the return code ------- */
_AH = 0x4d;
geninterrupt(DOS);
ax = _AX;
if ((ax & 0xff) != 0)
rtn = -1;
}
if (swaperror)
rtn = -1;
setvect(0, int0);
oldvectors(critvects);
if (rtn == -1) {
dispstr("\a\r\nCannot load " OVERLAYFILE);
if (swaperror)
dispstr(": Error building swap file\r\n");
else if (ax == 8)
dispstr(": Insufficient memory\r\n");
resterm(FALSE);
}
else {
/* ------ this will be tsrplus's stack when it pops up ------ */
tsrss = _SS;
tsrsp = _SP;

/* ------- get current PSP size from MCB ------- */
RunningSize = peek(_psp-1, 3);

running = FALSE;

/* ------ recompute program size ------- */
sizeprogram = _CS+((unsigned) main >> 4)-_psp;
if ((unsigned) main % 4)
sizeprogram++;

/* ----- terminate and stay resident ------- */
_DX = sizeprogram;
_AX = 0x3100;
geninterrupt(DOS);
}
}

/* ------- register a TSR --------- */
int register_tsr(struct swap_header far *sw)
{
swap = *sw;
load_tsr();
if (swaperror)
return -1;
registered = TRUE;
return 0;
}

/* ------ load the TSR file into EMM swap area or onto disk -------- */
static void load_tsr(void)
{
long swapsize, pg;
unsigned blksize;
int pages;

length = allocsize();

/* ---- compute swap file size ----- */
swapsize = length;
swapsize *= 16;
swapsize += 2048;
swapsize += (620L * 1024L);

/* ---- compute XMS blocks needed ---- */
blksize = (unsigned) (swapsize / 1024);
if (swapsize % 1024)
blksize++;

/* ---- compute EMM pages needed ---- */
pg = swapsize / 16384;
if (swapsize % 16384)
pg++;
pages = (int) pg;

/* ----- test for enough EMM pages available ----- */
if (UseEMM && emm && emm_pages_available() >= pages)
/* ------ allocate the EMM pages -------- */
emmhandle = emm_allocate(pages)+1;
/* ----- test for enough XMS available ----- */
if (!emmhandle && UseXMS && xms && xms_available() >= blksize)
xmshandle = xms_allocate(blksize);

dispstr(" Swapping ");
if (emmhandle)
dispstr("to EMS");
else if (xmshandle)
dispstr("to XMS");
else {
if (!*SwapPath) {
swaperror = TRUE;
dispstr("disabled\r\n");
return;
}
/* -------- use a disk file for swap -------- */
dispstr("to disk\r\n");
_fmode = O_BINARY;
if ((diskhandle = _creat(SwapPath, 0)) == -1) {
swaperror = TRUE;
diskhandle = 0;
dispstr(" failed\r\n");
return;
}
_close(diskhandle);
}
dispstr("\r\n");
openswaps();
writetsr();
closeswaps();
if (swaperror && diskhandle)
unlink(SwapPath);
}

/* ---- write the TSR image to the swap file ---- */
static void writetsr(void)
{
writecode(0);
writevectors(0);
}

static void intercept_mouse(void)
{
unsigned char far *ms;
MouseIRQ = 8;
/* --------- test for mouse driver present --------- */
ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4));
MouseSegment = FP_SEG(ms);
if (ms != NULL && *ms != 0xcf) {
/* --- mouse driver is present, prepare to disable its IRQ --- */
_CX = 0;
_AX = 36;
geninterrupt(MOUSE);
MouseIRQ += _CL;
}
}

void dispstr(char *s)
{
unsigned oldbp;
_DI = _DI;
while (*s) {
oldbp = _BP;
_AH = 0xe;
_AL = *s;
_BX = 0;
geninterrupt(0x10);
_BP = oldbp;
s++;
}
}

void dispnum(int n)
{
static char s[] = "0000";
int i = 4;
while (i) {
int j = n & 0xf;
n >>= 4;
if (j < 0xa)
j += '0';
else
j = j - 10 + 'a';
s[--i] = j;
}
dispstr(s);
}