home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
ISC366.ZIP
/
DOSFREE
/
DOSFREE.CPP
next >
Wrap
C/C++ Source or Header
|
1993-09-01
|
6KB
|
248 lines
///////////////////////////////////////////////////////////////////////////
// //
// File: DosFree.cpp //
// started on: 28/7/93 //
// //
///////////////////////////////////////////////////////////////////////////
// //
// DosFree allows you to use dos within your TSRs. Just derive from //
// this class and call func. Go and your dos-free application //
// overloading func. AppFunc will run as soon as dos is free. //
// //
///////////////////////////////////////////////////////////////////////////
// //
// by Ofer Laor (AKA LeucroTTA) //
// //
///////////////////////////////////////////////////////////////////////////
#include "dosfree.h"; // DOSFREE.
#include <dos.h>; // disable, REGS, SREGS, intdos, intdosx.
// Abort/Retry/Fail==> Fail.
void TRAP24::isr(IREGS& regs)
{
regs.h.al= 3;
}
// start up.
DOSFREE::DOSFREE()
{
fRunning= 0; // start by not running.
// now enlarge the stack that ISC uses.
disable();
reallocStack(5500);
enable();
}
// run AppFunc as soon as possible.
void DOSFREE::Go(void)
{
fRunning= 1;
}
// application should overload this function.
void DOSFREE::AppFunc(void)
{
// Do nothing....
}
// local function - insures that AppFunc is running in "protected DOS" session.
void DOSFREE::ShellFunc(void)
{
static int fInFlag= 0;
if (fInFlag|| !fRunning) // prevent recursion + is app supposed to run?
return;
fInFlag++;
REGS regs;
SREGS sregs;
// now disable break_checking.
regs.x.ax= 0x3300; // get break state.
intdos(®s, ®s);
unsigned char bPrevBreak= regs.h.dl;
regs.h.dl= 0;
regs.x.ax= 0x3301; // set break state.
intdos(®s, ®s);
// set new psp.
regs.x.ax= 0x5100; // get current psp.
intdos(®s, ®s);
unsigned wPrevPSP= regs.x.bx;
regs.x.bx= _psp;
regs.x.ax= 0x5000; // set current psp.
intdos(®s, ®s);
// set new DTA area.
regs.x.ax= 0x2f00; // get DTA area.
intdosx(®s, ®s, &sregs);
unsigned wPrevDTAoff= regs.x.bx;
unsigned wPrevDTAseg= sregs.es;
sregs.ds= _psp;
regs.x.dx= 0x80;
regs.x.ax= 0x1a00;
intdosx(®s, ®s, &sregs); // set DTA to psp:0x80.
// deactivate for next time (once per go)..
fRunning= 0;
// HANDLE EXTENDED ERRORS (and traps!).
// DOS 3.1 and up!
regs.x.ax= 0x5900; // get extended error info.
regs.x.bx= 0;
intdosx(®s, ®s, &sregs);
struct {
unsigned ax;
unsigned bx;
unsigned cx;
unsigned dx;
unsigned si;
unsigned di;
unsigned ds;
unsigned es;
unsigned dummy[3];
} ErrorRegs;
ErrorRegs.ax= regs.x.ax;
ErrorRegs.bx= regs.x.bx;
ErrorRegs.cx= regs.x.cx;
ErrorRegs.dx= regs.x.dx;
ErrorRegs.si= regs.x.si;
ErrorRegs.di= regs.x.di;
ErrorRegs.es= sregs.es;
ErrorRegs.ds= sregs.ds;
ErrorRegs.dummy[0]= ErrorRegs.dummy[1]= ErrorRegs.dummy[2]= 0;
// SET TRAPS --> THIS MIGHT NOT WORK IN LARGER MEM MODELS!!!!!
TrapCBreak.activate(0x1b);
TrapMSDOSCriticalError.activate(0x23);
TrapAbortRetryFail.activate(0x24);
//////////////////////////////////////////////////////////////////////
// run application.
AppFunc();
//////////////////////////////////////////////////////////////////////
// RESTORE OLD TRAPS.
TrapCBreak.deactivate();
TrapMSDOSCriticalError.deactivate();
TrapAbortRetryFail.deactivate();
// RESTORE EXTENDED ERRORS .
regs.x.dx= FP_OFF((void far *)&ErrorRegs);
sregs.ds= FP_SEG((void far *)&ErrorRegs);
regs.x.ax= 0x5d0a;
intdosx(®s, ®s, &sregs); // set extended error.
// reset to old DTA area.
sregs.ds= wPrevDTAseg;
regs.x.dx= wPrevDTAoff;
regs.x.ax= 0x1a00;
intdosx(®s, ®s, &sregs); // set DTA area to old DTA area.
// reset old psp.
regs.x.bx= wPrevPSP;
regs.x.ax= 0x5000;
intdos(®s, ®s); // set old psp.
// re-enable break_checking.
regs.h.dl= bPrevBreak;
regs.x.ax= 0x3301;
intdos(®s, ®s);
fInFlag--;
}
// Timer for DOSFREE.
INT8::INT8()
{
activate(0x8);
// now check for Dosfree.
REGS regs;
SREGS sregs;
regs.x.ax= 0x3400;
intdosx(®s, ®s, &sregs);
// inDOS flag (*inDOS> 0 when forground is using DOS).
inDOS= (char far *)MK_FP(sregs.es, regs.x.bx);
}
// Timer interrupt routine, checks for DOS-free on the forground session.
void INT8::isr(void)
{
// call old interrupt vector.
old_vect();
static int fInFlag= 0;
// disallow recursion.
if (fInFlag)
return;
fInFlag++;
// allow DOSFREE to hook into the Timer also.
TimerHook();
// run the shell function (provided that DOS is free).
if (!*inDOS)
ShellFunc();
fInFlag--;
}
// DOS idle interrupt vector.
void INT28::isr(void)
{
// keep all the other TSRs in the background working.
old_vect();
static int fInFlag= 0;
// diallow any recursion.
if (fInFlag)
return;
fInFlag++;
// allow DOSFREE to hook into the DOS idle usage.
DosIdleHook();
// run the shell function.
ShellFunc();
fInFlag--;
}