#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <time.h>


// Multi-tasker cooperation class

class tasker {

    union REGS rg;   // General Register values for specific function

    public:
    int mtask;
    unsigned char DVmajor;              // Desqview 'major' revision #
    unsigned char DVminor;              // Desqview 'minor' revision #
    unsigned int DVwinno;               // Desqview window #
    void _fastcall set_mtask (void);
    void _fastcall pause_mtask (void);
    void _fastcall my_sleep (int secs);
    void _fastcall DosSleep (clock_t millisecs);

    private:
    int  _fastcall is_dv (void);
    int  _fastcall is_ddos (void);
    int  _fastcall is_mos (void);
    int  _fastcall is_tv (void);
    int  _fastcall is_os2 (void);
    void _fastcall pause_dv (void);
    void _fastcall pause_ddos (void);
    void _fastcall pause_tv (void);
    void _fastcall pause_mos (void);
    void _fastcall pause_os2 (void);
    unsigned getkey(void);
};

unsigned tasker::getkey(void)
{
    unsigned key;

    while(!kbhit())
        pause_mtask();
    if((key = getch() ) == 0)
        key = getch() << 8;
            return(key);

}



void _fastcall tasker::set_mtask (void) {

    if(is_dv()) mtask=1;
    else if(is_ddos()) mtask = 2;
    else if(is_mos()) mtask = 3;
    else if(is_tv()) mtask = 4;
    else if(is_os2()) mtask = 5;
}


int _fastcall tasker::is_dv (void) {

    union REGS fregs;
    unsigned char majorv;
    unsigned char minorv;
    unsigned int winno;
    if ( (getvect(0x21)) != NULL) {
             fregs.x.ax = 0x2B01;
             fregs.x.cx = 0x4445;
             fregs.x.dx = 0x5351;

             int86(0x21, &fregs, &fregs );
             majorv = fregs.h.bh;
             minorv = fregs.h.bl;

            if ((majorv) || (minorv)) {
                fregs.x.ax = 0xDE07;
                int86(0x15, &fregs, &fregs );
                winno = fregs.x.ax;
                }
    }

    DVmajor = majorv;
    DVminor = minorv;
    DVwinno = winno;

    if ((majorv) || (minorv))
        return(1);
    else
        return(0);

}


int _fastcall tasker::is_ddos (void) {

    rg.h.ah=0x0e4;
    int86(0x21,&rg,&rg);
    if(rg.h.al==1 || rg.h.al==2) return 1;
    return 0;
}


int _fastcall tasker::is_mos (void) {

    int temp;

    rg.h.ah=0x030;
    int86(0x21,&rg,&rg);
    temp=rg.x.ax;
    rg.x.ax=0x03000;
    rg.x.bx=0x03000;
    rg.x.cx=0x03000;
    rg.x.dx=0x03000;
    int86(0x21,&rg,&rg);
    if(rg.x.ax==temp) return temp;
    return 0;
}


int _fastcall tasker::is_tv (void) {

    rg.x.ax=0x01022;
    rg.x.bx=0;
    int86(0x15,&rg,&rg);
    if(!rg.x.bx) return 0;
    return rg.x.bx;
}


int _fastcall tasker::is_os2 (void) {

    rg.x.ax = 0x1680;
    int86(0x2f,&rg,&rg);
    return (rg.h.al == 0);
}

void _fastcall tasker::pause_dv (void) {

    union REGS fregs;

    fregs.x.ax = 0x1000;
    int86(0x15,&fregs,&fregs);

}


void _fastcall tasker::pause_ddos (void) {

    int86(0xf4,&rg,&rg);
}


void _fastcall tasker::pause_tv (void) {

    rg.x.ax = 0x01000;
    int86(0x15,&rg,&rg);
}


void _fastcall tasker::pause_mos (void) {

    rg.x.ax = 0x0703;
    rg.x.bx = 0x03;
    rg.x.cx = 0;
    rg.x.dx = 0;
    int86(0x38,&rg,&rg);
}


void _fastcall tasker::pause_os2 (void) {

    rg.x.ax = 0x1680;
    int86(0x2f,&rg,&rg);
}


void _fastcall tasker::pause_mtask (void) {

   switch(mtask) {
        case 0:         break;
        case 1:
            pause_dv();
            break;
        case 2:
            pause_ddos();
            break;
        case 3:
            pause_mos();
            break;
        case 4:
            pause_tv();
            break;
        case 5:
            pause_os2();
            break;

        default:        break;
    }
    int86(0x28,&rg,&rg);    /* DOS scheduler interrupt */
}



void _fastcall tasker::my_sleep (int secs) {         /* snooze a while */

    clock_t t1;


    t1 = clock() + ((clock_t)secs * (clock_t)CLOCKS_PER_SEC);
    while(clock() < t1) pause_mtask();
}



void _fastcall tasker::DosSleep (clock_t millisecs) {    /* snooze a short while */

    clock_t t1;


    t1 = clock() + millisecs;
    while(clock() < t1) pause_mtask();
}
