?
Solved

interrupt question - reopen for segelebel

Posted on 1999-12-31
4
Medium Priority
?
433 Views
Last Modified: 2012-05-04
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
0
Comment
Question by:whluk
  • 2
  • 2
4 Comments
 

Author Comment

by:whluk
ID: 2316443
Edited text of question.
0
 
LVL 30

Accepted Solution

by:
SteveGTR earned 200 total points
ID: 2316789
I believe that your problem occurs because the time() or ctime() functions resolves to calls to DOS (int 21). If you call a DOS interrupt when one is already processing your code goes boom! This link provides you with information about DOS reentrancy problems (and others) and how to overcome them.

http://www.ece.uiuc.edu/ece291/books/CH18/CH18-3.html

Good Luck,
Steve
0
 

Author Comment

by:whluk
ID: 2317553
So What I am to do?
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 2317753
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
0

Featured Post

SMB Security Just Got a Layer Stronger

WatchGuard acquires Percipient Networks to extend protection to the DNS layer, further increasing the value of Total Security Suite.  Learn more about what this means for you and how you can improve your security with WatchGuard today!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
Suggested Courses

601 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question