Link to home
Start Free TrialLog in
Avatar of whluk
whluk

asked on

interrupt question - reopen for segelebel

segelebel and others,
With reference to the last question on altering timer interrupt vector , I want to know what I should do if the program is set up to involve real time calculations. I tried to add ctime and time in the interrupt handler. But the program just crashed and chucked me back to windows...

To make this clear, I just give you an example for what I've done...

/*
    Interrupt 1Ch - redirection to display        the count of interruption
    done by this ISR.
*/

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

void    interrupt       new_1C      ();
void    interrupt       (*old_1C)   ();
void    write_string    (int x, int y, char *p, int attr);
void    set_vid_mem     (void);

unsigned    paragraphs;
int         count;
char        far *vid_mem;
char        str[5];
time_t      llongtime;
char        *v2;

main() {

    set_vid_mem ();

    old_1C = getvect (0x1C);
    setvect (0x1C, new_1C);
    paragraphs = (_SS + (_SP >> 4) + 1) - _psp;
    keep(0, paragraphs);

}

/* low level functions */


/*  Get the current video mode
*/

video_mode (void)
{
    union REGS r;

    r.h.ah = 15;
    return int86 (0x10, &r, &r) & 255;
}

/*  Set pointer to video memory
*/
void    set_vid_mem (void)
{
    int vmode;

    vmode = video_mode ();
    if ((vmode != 2) && (vmode != 3) && (vmode != 7)) {
        printf ("video must be in 80 column text mode\n");
        exit (1);
    }

    if (vmode == 7)
        vid_mem = (char far *) MK_FP (0xB000, 0);
    else
        vid_mem = (char far *) MK_FP (0xB800, 0);
}

/*  Write a string to video memory
*/
void    write_string (int x, int y, char *p, int attr)
{
    char far *v;

    v = vid_mem;
    v += (y*160) + x*2;
    for (; *p; ) {
        *v++ = *p++;
        *v++ = attr;
    }
}


/*
    new Int 1C Service routine.
*/

void interrupt new_1C ()
{
    (old_1C)();
    disable ();
    itoa(++count, str, 10);
    write_string (76, 0, str, 31);
    time(&llongtime);  <---------|
    v2 = ctime(&llongtime);<-----|--added

    write_string(0,0,v2, 31);<---|
   
    enable ();
}

 






Thanks
Jacky
Avatar of whluk
whluk

ASKER

Edited text of question.
ASKER CERTIFIED SOLUTION
Avatar of SteveGTR
SteveGTR
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of whluk

ASKER

So What I am to do?
The text says:

"MS-DOS provides a special one-byte flag (InDOS) that contains a zero if DOS is currently active and a non-zero value if DOS is already processing an application request. By testing the InDOS flag your TSR can determine if it can safely make a DOS call. If this flag is zero, you can always make the DOS call. If this flag contains one, uou may not be able to make the DOS call. MS-DOS provides a function call, Get InDOS Flag Address, that returns the address of the InDOS flag. To use this function, load ah with 34h and call DOS. DOS will return the address of the InDOS flag in es:bx. If you save this address, your resident programs will be able to test the InDOS flag to see if DOS is active."

So you should perform the following steps:

1) Create a pointer for InDOS flag
2) Capture address of InDOS flag when initializing TSR
3) Test InDOS flag prior to calling DOS functions

This leads to the question, "What do I do if DOS is busy?". In your case I'd just skip the time stuff and just add to counter.

So here some code:

/* Creation of global InDOS flag */

char far *pInDOS;

/* Initialization of InDOS flag, can be in main() */

  union REGS regs;
  struct SREGS segs;

  r.h.ah = 0x34h;

  int86x(0x21, &regs, &regs, &segs);
      
  pInDOS = (char far *) MK_FP(segs.es, regs.x.bx);

/* Testing inDOS flags */

void interrupt new_1C ()
{
  (old_1C)();
  disable ();
  itoa(++count, str, 10);
  write_string (76, 0, str, 31);

  if (*pInDOS == 0)
    {
    time(&llongtime);  
    v2 = ctime(&llongtime);

    write_string(0, 0, v2, 31);
    }    

  enable ();
}

I hope this helps.

Steve