home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////
- // //
- // 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--;
- }
-
-