[alt.msdos.programmer] Trapping Floating Point Errors in Turbo C

resnicks@netcom.UUCP (Steve Resnick) (01/23/91)

I have a problem - I need to trap floating point errors from the floating
point hardware. Currently, I am using signal() to do this, but signal doesn't
give me some of the information I need. I assume that the 80n87 and the
emulator (EMU.LIB) both generate an interrupt in the event of a floating
point exception. My question is, what interrupt is generated, and if the
ISR for that interrupt is shared, what do I need to check on the PIC to
determine the source of the interupt?  One of the things I want, which
I can't get out of signal, is the CS:IP at the time of the exception, 
so that I can point the finger at a specific routine.
 
Thanx, in advance,

Steve

teittinen@cc.helsinki.fi (01/24/91)

In article <21650@netcom.UUCP>, resnicks@netcom.UUCP (Steve Resnick) writes:
> 
> I have a problem - I need to trap floating point errors from the floating
> point hardware. Currently, I am using signal() to do this, but signal doesn't
> give me some of the information I need.

Have you tried writing your own matherr()-function. It is another "clean"
way to handle floating point errors and it gets some information that is
not included in signal (if my memory serves me right).

-- 
E-Mail: teittinen@finuh.bitnet               ! "Studying is the only way
        teittinen@cc.helsinki.fi             !  to do nothing without
Marko Teittinen, student of computer science !  anyone blaming you" -me

karlson@eucalyptus.Berkeley.EDU (Eric Karlson) (01/25/91)

I am not completely sure of this, but some time back when I was searching
for just this sort of info, I seem to recall finding a reference that
implied that the 8087 interrupt came in on INT 2 (the same as the memory
parity error, I believe). Again, take this with a grain of salt, it was some
time ago and I never did find an explicit statement on this matter.

My primary comment is about the CS:IP at the time of interrupt.  Even if
you do find a way of getting that, it won't give you what you want.  The
reason is that the 8087 runs in parrallel to the 80X86, so when the 8087
signals an interrupt, the main processor could be doing something entirely
unrelated to what caused the 8087 to get an error (if your math routines
are written so that they will never return until the 8087 has finished the
work for that procedure, then this is a lie, but said routine do not HAVE
to be written this way).

							Eric Karlson

resnicks@netcom.UUCP (Steve Resnick) (01/26/91)

In article <1991Jan24.125150.4631@cc.helsinki.fi> teittinen@cc.helsinki.fi writes:
>In article <21650@netcom.UUCP>, resnicks@netcom.UUCP (Steve Resnick) writes:
>> 
>> I have a problem - I need to trap floating point errors from the floating
>> point hardware. Currently, I am using signal() to do this, but signal doesn't
>> give me some of the information I need.
>
>Have you tried writing your own matherr()-function. It is another "clean"
>way to handle floating point errors and it gets some information that is
>not included in signal (if my memory serves me right).

I have a matherr function - and this does give me detailed information about
who, what, when and where. Problem is, matherr is called by functions in
MATH[insert memory model here].LIB. In the event I do something silly like
double Foo = HUGE_VAL * 10; I will get a floating point overflow, but, since
this is inline in my code, matherr() doesn't get called. Sigh. 

As was pointed out earlier, the NPX (using Intel nomenclature) uses INT 2 on 
an XT. On an AT class machine, the NPX uses int 75H. I don't know yet, the 
state of the PIC, if any, when these interrupts occur, but it sounds as
though I may be spitting in the wind, if the coprocessor does in fact execute
in paralell to the CPU .

Thanx for the info., guys! :)

Cheers!
Steve


-- 
-------------------------------------------------------------------------------
resnicks@netcom.com, stever@octopus.com, steve.resnick@f105.n143.z1.FIDONET.ORG
apple!camphq!105!steve.resnick, {apple|pyramid|vsi1}!octopus!stever
- In real life: Steve Resnick. Flames, grammar and spelling errors >/dev/null
0x2b |~ 0x2b, THAT is the question.
-------------------------------------------------------------------------------

mwizard@eecs.cs.pdx.edu (Craig Nelson) (02/12/91)

resnicks@netcom.UUCP (Steve Resnick) writes:


>I have a problem - I need to trap floating point errors from the floating
>point hardware. Currently, I am using signal() to do this, but signal doesn't
>give me some of the information I need. I assume that the 80n87 and the
>emulator (EMU.LIB) both generate an interrupt in the event of a floating
>point exception. My question is, what interrupt is generated, and if the
>ISR for that interrupt is shared, what do I need to check on the PIC to
>determine the source of the interupt?  One of the things I want, which
>I can't get out of signal, is the CS:IP at the time of the exception, 
>so that I can point the finger at a specific routine.
> 
>Thanx, in advance,

>Steve


	If you check the interrupt table (we all have one lieing around) you
 will see a floating point error generates an interrupt 75h.  Dealing with
 this problem strictly from Turbo C might present problems unless you have the
 new IDE that came with Turbo C++.  If you have the new or old Turbo Debugger
 then you should have Turbo Assembler as well and the answer is simple. With
 what you are asking for you should solve the problem by writing a new ISR
 and storing its location in the vector table at the proper position.  In case
 you're wondering, on an 80x86 based machine its 0000:01D4h.  Write a small
 routine (using assembly language is advised) and make sure the stack is not
 modified during execution. This routine is going to be used simpley as a place
 to stash a breakpoint during debugging.  You can use the interrupt function
 type if you really want to, but I like making things as hard as possible.
	After installing the interrupt function in the vector location (please
 remember to save where the old one is in some global variables) You should
 be able to set a breakpoint in the new interrupt handler and run the program.
 To install the new handler refer to the Turbo C reference guide for the
 syntax and semantics on the getvect() and setvect() routines.  
	After all that work the last of your questions (what routine is causing
 this to happen) should be on the stack (hopefully by this time you are well
 familiar with Turbo Debugger).  The order of items on the stack when you enter
 the ISR will be as follows: flags at time of interrupt, then cs:ip.
	One more chunk of advice.  If you are using the EMU.LIB for all this
 then checking cs:ip won't do you any good.  It will contain the emulation
 code for whatever Borland created in their little black room to emulate a
 coprocessor.

		Craig  (mwizard@eecs.ee.pdx.edu)