⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosfree.cpp

📁 这是一个C++编程文档
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////
//                                                                       //
//            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(&regs, &regs);

    unsigned char bPrevBreak= regs.h.dl;

    regs.h.dl= 0;
    regs.x.ax= 0x3301; // set break state.
    intdos(&regs, &regs);

    // set new psp.

    regs.x.ax= 0x5100;    // get current psp.
    intdos(&regs, &regs);

    unsigned wPrevPSP= regs.x.bx;

    regs.x.bx= _psp;
    regs.x.ax= 0x5000;    // set current psp.
    intdos(&regs, &regs);


    // set new DTA area.

    regs.x.ax= 0x2f00;              // get DTA area.
    intdosx(&regs, &regs, &sregs);
    unsigned wPrevDTAoff= regs.x.bx;
    unsigned wPrevDTAseg= sregs.es;

    sregs.ds= _psp;
    regs.x.dx= 0x80;
    regs.x.ax= 0x1a00;
    intdosx(&regs, &regs, &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(&regs, &regs, &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(&regs, &regs, &sregs);           // set extended error.


    // reset to old DTA area.
    sregs.ds=  wPrevDTAseg;
    regs.x.dx= wPrevDTAoff;
    regs.x.ax= 0x1a00;
    intdosx(&regs, &regs, &sregs);  // set DTA area to old DTA area.


    // reset old psp.
    regs.x.bx= wPrevPSP;
    regs.x.ax= 0x5000;
    intdos(&regs, &regs); // set old psp.


    // re-enable break_checking.

    regs.h.dl= bPrevBreak;
    regs.x.ax= 0x3301;
    intdos(&regs, &regs);

    fInFlag--;
}

// Timer for DOSFREE.
INT8::INT8()
{
    activate(0x8);

    // now check for Dosfree.

    REGS regs;
    SREGS sregs;

    regs.x.ax= 0x3400;
    intdosx(&regs, &regs, &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--;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -