Technical Information Database TI599D.txt Trapping 8087 floating point exceptions in Pascal. Category :General Programming Platform :All Product :Pascal All Description: (* This unit allows you to selectively handle floating point errors - such a operations on NANs or infinity numbers - generated by the 8087 numeric coprocessor or emulation. This unit basically implements Pascal versions of C's _control87() and _stat87() functions and offers startup code for a user-defined int75h handler. For complete documentation on all of the constants in this unit, you should reference either the C documentation on _control87(), _stat87(), or signal(), or reference a 8087 programmer's guide. *) unit Except87; { NOTES: This unit is intended only for use on machines with an 80286 processor or higher. If you intend to hook interrupt 75h while using this unit, you should call Int75Startup as the first line in your interrupt handler or very, very bad things will happen. } {$IfNDef Windows} {$N+,E+} {$Else} {$N+} {$EndIf} interface const { 387 Status Word format } SW_INVALID = $0001; { Invalid operation } SW_DENORMAL = $0002; { Denormalized operand } SW_ZERODIVIDE = $0004; { Zero divide } SW_OVERFLOW = $0008; { Overflow } SW_UNDERFLOW = $0010; { Underflow } SW_INEXACT = $0020; { Precision (Inexact result) } SW_STACKFAULT = $0040; { Stack fault } { 387 Control Word format } MCW_EM = $003f; { interrupt Exception Masks} EM_INVALID = $0001; { invalid } EM_DENORMAL = $0002; { denormal } EM_ZERODIVIDE = $0004; { zero divide } EM_OVERFLOW = $0008; { overflow } EM_UNDERFLOW = $0010; { underflow } EM_INEXACT = $0020; { inexact (precision) } MCW_IC = $1000; { Infinity Control } IC_AFFINE = $1000; { affine } IC_PROJECTIVE = $0000; { projective } MCW_RC = $0c00; { Rounding Control } RC_CHOP = $0c00; { chop } RC_UP = $0800; { up } RC_DOWN = $0400; { down } RC_NEAR = $0000; { near } MCW_PC = $0300; { Precision Control } PC_24 = $0000; { 24 bits } PC_53 = $0200; { 53 bits } PC_64 = $0300; { 64 bits } function Control87(New, Mask: Word): Word; function Status87: Word; procedure Int75Startup; far; implementation procedure Int75Startup; assembler; asm { this is the entry code for your int 75 handler } xor al, al { Clear BUSY latch} out 0F0h, al mov al, 20H { End-of-interrupt} out 0A0h, al out 20h, al end; function Control87(New, Mask: Word): Word; assembler; var Control: Word; asm fstcw Control mov ax, New mov bx, Mask and ax, bx not bx fwait mov dx, Control and dx, bx mov Control, ax fldcw Control xchg ax, dx end; function Status87: Word; assembler; var Status: Word; asm fstsw Status fwait mov ax, Status and ax, SW_INVALID+SW_ZERODIVIDE+SW_OVERFLOW+SW_UNDERFLOW+SW_INEXACT end; end. (******** This is a test program for the Except87 unit *******) program TestFP; {$N+} uses Except87, DOS; var f: single; p: pointer; i: word; procedure Int75Handler; interrupt; begin Int75Startup; i := 1; end; begin i := 0; Control87(0, MCW_EM); GetIntVec($75, p); SetIntVec($75, Int75Handler); f := 99999999999.99; f := f / 0.0; writeln('Coprocessor status: ', status87); SetIntVec($75, p); writeln('Did int75 fire?: ', i); end. Reference: 7/16/98 4:33:48 PM
Last Modified: 01-SEP-99