home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
c_all592.arj
/
TI722.ASC
< prev
next >
Wrap
Text File
|
1992-02-25
|
3KB
|
133 lines
PRODUCT : Borland C++ NUMBER : 722
VERSION : 2.0
OS : DOS
DATE : February 25, 1992 PAGE : 1/2
TITLE : Using Floating Points in ISR's
QUESTION:
How do I use floating point within an interrupt service
routine?
ANSWER:
The floating point emulator in Turbo C is NOT re-entrant.
8087 instructions can only be used in interrupt routines
if the chip is present, and all programs with 8087
interrupt handlers should be compiled without emulation.
Within the interrupt handler, the FNSAVE instruction
should be used to save the state of the 8087 chip into a
94 byte state record. After saving the state, an
implicit FINIT is executed to bring the chip into its
default state. In this state, exceptions are masked, so
divide-by-zeros, overflows, etc. will produce NANs and
INFs, not run-time errors. It so happens that this is
exactly what we want (a run-time error during an
interrupt would completely crash the system), so no FLDCW
is required to load a different control word. The FNSAVE
must be executed before the STI that re-enables
interrupts. Furthermore, an FWAIT must precede STI to
make sure that the state has been completely saved. The
FRSTOR must be followed by an FWAIT to ensure that the
state has been completely reloaded before the state
variable is removed from the stack.
EXAMPLE:
#include <stdio.h>
#include <conio.h>
#include <dos.h>
double x = 0;
void interrupt (*save)(void);
void interrupt func(void)
{
unsigned char state87[94];
__emit__(
0xDD,0x76,state87, /* FNSAVE [BP+<state87] */
0x9B, /* FWAIT */
0xFB); /* STI */
PRODUCT : Borland C++ NUMBER : 722
VERSION : 2.0
OS : DOS
DATE : February 25, 1992 PAGE : 2/2
TITLE : Using Floating Points in ISR's
x += 1;
__emit__(
0x9B,0xDD,0x66,state87, /* FRSTOR [BP+<state87] */
0x9B); /* FWAIT */
}
main()
{
char ch = 0;
save = getvect(5); /* the <Shift-PrtScr> interrupt. */
setvect(5, func);
while (ch != 'q')
{
cprintf("%f\r\n", x); /* Each time you hit <Shift-PrtScr> */
if (kbhit()) /* x will get incremented. */
ch = getch();
}
setvect(5, save); /* restore original vector for INT 5 */
return(0);
}