home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------
- * filename - ctrl87.cas
- *
- * function(s)
- * _control87 - access floating-point control word
- *-----------------------------------------------------------------------*/
-
- /*[]------------------------------------------------------------[]*/
- /*| |*/
- /*| Turbo C Run Time Library - Version 3.0 |*/
- /*| |*/
- /*| |*/
- /*| Copyright (c) 1987, 1990 by Borland International |*/
- /*| All Rights Reserved. |*/
- /*| |*/
- /*[]------------------------------------------------------------[]*/
-
- #pragma inline
-
- #include <float.h>
- #include <dos.h>
- #include "emuvars.h"
-
- /*---------------------------------------------------------------------*
-
- Name _control87 - access floating-point control word
-
- Usage unsigned int _control87(unsigned int new, unsigned int mask);
-
- Prototype in float.h
-
- Description This function is used to retrieve or change the floating-
- point control word.
-
- For every bit that is on in mask, the corresponding bit
- in the floating-point control word is set to the value
- of that bit in new.
-
- Return value The new floating-point control word value is returned.
-
- Notes:
- The Denormal exception is always trapped on the 8087 and 80287, but
- never on the 80387. The emulator never generates it.
-
- The Invalid exception is always trapped, as FPU stack overflows and
- underflows can sometimes be repaired transparently, but sometimes
- also cause nonrecoverable fatal errors.
-
- The return value should be what the user expects, as the processing
- of the Denormal and Invalid bits is done surreptitiously.
-
- Caution:
- The control word should not be changed directly, unless you wish
- to bypass the RTL trap handling.
-
- It is dangerous to unmask an exception unless the status bit is already
- clear. To be safe, call _clear87() first.
-
- *---------------------------------------------------------------------*/
-
- unsigned int _control87(unsigned int new, unsigned int mask)
- {
- volatile unsigned int Control;
-
- #pragma warn -asm
- asm emul
- #pragma warn .asm
-
- asm fstcw Control
- _AX = new;
- _BX = mask;
- asm and ax, bx
- asm not bx
- asm fwait
- _DX = Control;
- asm and dx, bx
- asm or dx, ax
-
- /* DX has what the user thinks he wants, but we don't give it to him */
- /* we store it in memory as a shadow mask instead */
-
- asm mov cl, dl
- asm and cl, 3Fh /* remove reserved bits */
- asm mov byte ptr SS: _emu.control [0], cl
-
- #if DeepStack
- _AX = _DX & ~(EM_DENORMAL | EM_INVALID);
- #else
- _AX = _DX & ~EM_DENORMAL;
- #endif
-
- /* if using a 80387, mask denormal exceptions */
- asm cmp byte ptr SS: _emu._8087, 3
- asm jl control
- asm or al, EM_DENORMAL
-
- control:
- Control = _AX;
- asm fldcw Control
-
- /* tell the user we did what he asked */
- /* what he doesn't know won't hurt him */
- asm xchg ax, dx
- return _AX;
- }
-