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

 
Output of file : TSR.C contained in archive : TSRPLUS.ZIP
/* --------- tsr.c --------- */

/*
* The Turbo C Terminate and Stay Resident (TSR) engine
* The resident part of the code
*/

#define EXTERNS
#include "tsr.h"

/* ------- prototypes -------- */
static void resident_psp(void);
static void interrupted_psp(void);
static void gateway(void);
static void readfile(unsigned, unsigned);
static void writefile(unsigned, unsigned);

/* ---------- TSRPLUSINT (0x2f) communications vector ISR ----------- */
void interrupt int2f(IREGS ir)
{
struct swap_header far *sw = MK_FP(ir.es,ir.bx);
int function = ir.ax & 0xff;

ir.ax = 0;
switch (function) {
case ISLOADED:
/* ---- test for TSRPLUS loaded ---- */
ir.ax = 0xff;
break;
case REGISTER:
/* ----- register a TSR ----- */
if (registered) {
swap.Scancode = sw->Scancode;
swap.Keymask = sw->Keymask;
ir.ax = -1;
break;
}
ir.ax = register_tsr(sw);
break;
case UNLOAD:
/* ------- unload tsrplus ------- */
unloading = 1;
break;
default:
ir.ax = -1;
break;
}
}

/* ---------- break handler ------------ */
static void interrupt newbreak(void)
{
return;
}

/* -------- critical error ISR ---------- */
static void interrupt newcrit(IREGS ir)
{
ir.ax = 0; /* ignore critical errors */
}

/* ------ BIOS disk functions ISR ------- */
static void interrupt newdisk(IREGS ir)
{
diskflag++;
(*olddisk)();
ir.ax = _AX; /* for the register returns */
ir.cx = _CX;
ir.dx = _DX;
ir.es = _ES;
ir.di = _DI;
ir.fl = _FLAGS;
--diskflag;
}

/* ----- keyboard ISR ------ */
static void interrupt newkb(void)
{
unsigned char kbval = inportb(0x60);
if (!hotkeyhit && !running) {
if (swap.Keymask && (peekb(0, 0x417) & 0xf) == swap.Keymask)
if (swap.Scancode == 0 || swap.Scancode == kbval)
hotkeyhit = TRUE;
if (hotkeyhit) {
/* --- reset the keyboard ---- */
kbval = inportb(0x61);
outportb(0x61, kbval | 0x80);
outportb(0x61, kbval);
outportb(0x20, 0x20);
return;
}
}
(*oldkb)();
}

/* ----- timer ISR ------- */
static void interrupt newtimer(void)
{
(*oldtimer)();
if (hotkeyhit && (peekb(dossegmnt, dosbusy) == 0) &&
!diskflag && !isinvideo())
gateway();
}

/* ----- 0x28 ISR -------- */
static void interrupt new28(void)
{
(*old28)();
if (hotkeyhit)
gateway();
}

/* --------- intercepted mouse ISR ----------- */
static void interrupt MouseISR(void)
{
outportb(0x20, 0x20);
}

/* ------ switch psp context from interrupted to TSR ----- */
static void resident_psp(void)
{
_AH = 0x51;
geninterrupt(DOS);
intpsp = _BX;
_BX = _psp;
_AH = 0x50;
geninterrupt(DOS);
}

/* ---- switch psp context from TSR to interrupted ---- */
static void interrupted_psp(void)
{
_BX = intpsp;
_AH = 0x50;
geninterrupt(DOS);
}

/* --------- test if OK to unload --------- */
BOOL OKtoUnload(void)
{
/* ---- test if vectors are the same as when hooked ---- */
struct vectors *vc = vectors;
unsigned seg = _psp;
unsigned sz = peek(seg-1, 3);

/* ---- test if any MCB is above the TSR ---- */
if (peekb(seg+sz, 0) != 0x5a)
return FALSE;
while (vc->vno) {
if (getvect(vc->vno) != vc->newvect)
return FALSE;
vc++;
}
return TRUE;
}

/* ------ execute the resident program ------- */
static void gateway(void)
{
if (!running) {
running = TRUE;
hotkeyhit = FALSE;
intsp = _SP;
intss = _SS;
_SP = tsrsp;
_SS = tsrss;
ctrl_break = getcbrk(); /* get ctrl break setting */
setcbrk(0); /* turn off ctrl break */
intdta = getdta(); /* get interrupted dta */
setdta(mydta); /* set resident dta */
resident_psp(); /* swap psps */

swaperror = FALSE;
/* ----- swap TPA memory for TSR memory ------ */
openswaps();
writecode(1);
writevectors(1);
readvectors(0);

_ES = _DS;
_DX = (unsigned) MouseState;
_CX = 0;
_BX = 0;
_AX = 22;
geninterrupt(MOUSE);

if (MouseSegment > _CS && MouseSegment < 0xa000 &&
MouseIRQ > 9 && MouseIRQ < 16)
setvect(MouseIRQ, MouseISR);

readcode(0);

WaitingSize = peek(_psp-1, 3);
poke(_psp-1, 3, RunningSize);

if (!swaperror) {
/* --------- execute the TSR ------------ */
enable();
(*swap.startptr)();
disable();
}

poke(_psp-1, 3, WaitingSize);

/* ------ swap the TPA memory back in -------- */
readcode(1);
readvectors(1);
closeswaps();

_ES = _DS;
_DX = (unsigned) MouseState;
_CX = 0;
_BX = 0;
_AX = 23;
geninterrupt(MOUSE);

interrupted_psp(); /* reset interrupted psp */
setdta(intdta); /* reset interrupted dta */
setcbrk(ctrl_break); /* reset ctrl break */
if (unloading) { /* if TSR set the unload flag */
if (OKtoUnload())
resterm(TRUE);
else
/* ------ cannot unload at this time ------ */
unloading = FALSE;
}
_SP = intsp; /* reset interrupted stack */
_SS = intss;
running = FALSE; /* reset TSR running semaphore */
}
}

/* ------- TSR unload function ----------- */
void resterm(int freeup)
{
resident_psp();
if (emmhandle)
emm_release(emmhandle-1);
else if (xmshandle)
xms_free(xmshandle);
else
unlink(SwapPath);
/* ----- restore the interrupt vectors ----- */
oldvectors(vectors);
interrupted_psp();
if (freeup) {
freemem(peek(_psp, 0x2c));
freemem(_psp);
}
}

/* ------- set up EMM or disk for swapping --------- */
void openswaps(void)
{
if (emmhandle)
emm_savecontext(emmhandle-1);
else if (!xmshandle)
if ((diskhandle = _open(SwapPath, O_RDWR)) == -1)
swaperror = TRUE;
}

/* ---- restore EMM mapping context or close disk after TSR is done ---- */
void closeswaps(void)
{
if (emmhandle)
emm_restorecontext(emmhandle-1);
else if (diskhandle)
_close(diskhandle);
}

/* ---------- swap vectors between XMS/EMM/swapfile and 0:0 -------- */
void swapvectors(BOOL wh, BOOL dir)
{
unsigned offset = wh ? 1024 : 0;
disable();
if (xmshandle) {
if (dir)
copy_xmstoconv(xmshandle, 0, offset, 1024);
else
copy_convtoxms(xmshandle, 0, offset, 1024);
}
else if (emmhandle) {
emm_map(1, 0, 0, emmhandle-1);
if (dir)
movedata(frame, offset, 0, 0, 1024);
else
movedata(0, 0, frame, offset, 1024);
}
else {
if (lseek(diskhandle, offset, SEEK_SET) == -1)
swaperror = TRUE;
else {
if (dir)
readfile(0, 1024);
else
writefile(0, 1024);
}
}
enable();
}

/* ---------- swap code between XMS/EMM/swapfile and TPA -------- */
void swapcode(BOOL wh, BOOL dir)
{
unsigned codeseg;
long seekadr;
long swapsize;

if (wh) {
if (dir == 0)
swapsize = TPAlength = allocsize();
else
swapsize = TPAlength;
}
else
swapsize = length;
swapsize *= 16;

if (swapsize == 0)
return;

/* ------- compute position of swap data in swap file ------ */
seekadr = (long) length * 16 * wh + 2048;
codeseg = highmemory;

disable();
if (emmhandle) {
int logpg, frameaddr;
logpg = (int) (seekadr / 16384);
frameaddr = (int) (seekadr % 16384);

while (swapsize > 0) {
unsigned len;

if (swapsize < 16384)
len = (unsigned) swapsize;
else
len = 16384;
if (frameaddr)
len = 16384 - frameaddr;
emm_map(1, 0, logpg++, emmhandle-1);
if (dir)
movedata(frame, frameaddr, codeseg, 0, len);
else
movedata(codeseg, 0, frame, frameaddr, len);
codeseg += len / 16;
swapsize -= len;
frameaddr = 0;
}
}
else if (diskhandle) {
unsigned len;
if (lseek(diskhandle, seekadr, SEEK_SET) == -1) {
swaperror = TRUE;
return;
}
while (swapsize > 0) {
if (swapsize < 32768U)
len = (unsigned) swapsize;
else
len = 32768U;
if (dir)
readfile(codeseg, len);
else
writefile(codeseg, len);
codeseg += 2048;
swapsize -= len;
}
}
else {
long len;
while (swapsize > 0) {
if (swapsize < 65536L)
len = swapsize;
else
len = 65536L;
if (dir)
copy_xmstoconv(xmshandle, codeseg, seekadr, len);
else
copy_convtoxms(xmshandle, codeseg, seekadr, len);
seekadr += 65536L;
codeseg += 4096;
swapsize -= len;
}
}
enable();
}

/* ----------- read a swap file record ------------- */
static void readfile(unsigned seg, unsigned len)
{
unsigned holdds = _DS;
_AH = 0x3f;
_CX = len;
_BX = diskhandle;
_DX = 0;
_DS = seg;
geninterrupt(DOS);
_DS = holdds;
swaperror = _AX - len != 0;
}

/* ----------- write a swap file record ------------- */
static void writefile(unsigned seg, unsigned len)
{
unsigned holdds = _DS;
_AH = 0x40;
_CX = len;
_BX = diskhandle;
_DX = 0;
_DS = seg;
geninterrupt(DOS);
_DS = holdds;
swaperror = _AX - len != 0;
}

/* ---- Compute to the end of the MCB chain ---- */
unsigned allocsize(void)
{
unsigned len, owner, dif;
unsigned mcbs = _psp-1;
unsigned size = 0;
while (peekb(mcbs, 0) == 0x4d)
mcbs += peek(mcbs, 3) + 1;
len = peek(mcbs, 3);
owner = peek(mcbs, 1);
if (highmemory <= mcbs) {
size = mcbs-highmemory+1;
if (owner > _psp)
size += len;
}
else if (owner > _psp) {
dif = highmemory-mcbs;
if (len > dif)
size = len-dif;
}
return size;
}



  3 Responses to “Category : Files from Magazines
Archive   : TSRPLUS.ZIP
Filename : TSR.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/