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
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);<-----|-
write_string(0,0,v2, 31);<---|
enable ();
}
Thanks
Jacky
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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, ®s, ®s, &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
"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, ®s, ®s, &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
ASKER