ebergman@isis.cs.du.edu (Eric Bergman-Terrell) (06/03/91)
I'm working on a Windows program that does a lot of floating point calculations. I'm using BC++ 2.0 on my 386SX which does have a 387SX math coprocessor. The Problem: If I leave the program running and shell out to DOS and then come back, the Windows program usually crashes, sometimes with a UAE, and sometimes with a message like "coprocessor stack underflow". What's even stranger is that I didn't do any floating point while in DOS-land. So I tried the following: in my main event loop (switch statement from HELL) I call a routine to reset the 8x87 upon receipt of WM_KILLFOCUS and WM_SETFOCUS messages. The routine is just: asm fwait asm finit asm fwait Result: I haven't been able to make the problem recur. Even if I shell out to DOS in the middle of a computation, the program doesn't crash when I get back. SO: is Windows forgetting to save/restore the coprocessor state when the DOS shell is started? Or is this the responsibility of the programmer? Furthermore, is it safe to simply call the finit instruction? I'm assuming that on a machine lacking a math chip the instruction will cause the corresponding emulation routine to be called. I'll find out tomorrow when I try the prog. on a coprocessorless machine... Furthermore, is the Windows floating point emulation library documented ANYWHERE? I have Petzold, Prog. Ref., Guide to Programming, and the DOCS for BC++ 2.0. Haven't found any coverage of the emul library anywhere ... Terrell
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (06/03/91)
In article <1991Jun3.045252.5431@mnemosyne.cs.du.edu> ebergman@isis.cs.du.edu (Eric Bergman-Terrell) writes: >The Problem: If I leave the program running and shell out to DOS and then >come back, the Windows program usually crashes, sometimes with a UAE, and >sometimes with a message like "coprocessor stack underflow". > >What's even stranger is that I didn't do any floating point while in DOS-land. > >So I tried the following: in my main event loop (switch statement from HELL) >I call a routine to reset the 8x87 upon receipt of WM_KILLFOCUS and >WM_SETFOCUS messages. The routine is just: > >asm fwait >asm finit >asm fwait > >Result: I haven't been able to make the problem recur. Even if I shell out >to DOS in the middle of a computation, the program doesn't crash when I get >back. This fix is a little dangerous. After the FINIT, the 387 will be configured to mask all errors: it won't report problems like stack underflow, it'll just return NaN as a result. You should take frequent looks at the status word to see if any exceptions have occurred if you do this, but watch out: at least in Turbo Pascal, the sticky bits in the status word aren't sticky. The floating point string conversion routines reset them. BC++ may have the same bug. Duncan Murdoch