| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- (* Copyright (C) 1987 Jensen & Partners International *)
- IMPLEMENTATION MODULE FloatExc;
- FROM SYSTEM IMPORT In,Out,DI,GetFlags,SetFlags,Seg,Ofs,Registers;
- FROM Lib IMPORT FatalError,Terminate,Intr;
- FROM MATHLIB IMPORT StoreControlWord,LoadControlWord,ClearExceptions,
- StoreEnvironment,Environment;
- IMPORT Str;
- VAR
- Nmi[0:2*4], OldNmi : ADDRESS;
- Term : PROC;
- Base : CARDINAL;
- AT : BOOLEAN;
- (*$J+,C FF*)
- PROCEDURE NmiTrap(Dummy: CARDINAL);
- VAR
- e : Environment;
- s1,s2 : ARRAY [0..49] OF CHAR;
- Done : BOOLEAN;
- l : LONGCARD;
- CONST
- A = Str.Append;
- BEGIN
- IF AT THEN Out(20H,20H); END;
- e := StoreEnvironment();
- ClearExceptions;
- l := LONGCARD(e.IP)+LONGCARD(e.Opcode DIV 1000H)*10000H;
- Str.CardToStr(l,s2,16,Done);
- s1 := '['; s1 \A\ s2; s1 \A\ '-';
- l := l-LONGCARD(Base)*10H;
- Str.CardToStr(l,s2,16,Done);
- s1 \A\ s2; s1 \A\ '] Float Error : ';
- IF 0 IN e.StatusWord THEN s1 \A\ 'invalid operation '; FatalError( s1 );
- ELSIF 1 IN e.StatusWord THEN s1 \A\ 'denormalized operand'; FatalError( s1 );
- ELSIF 2 IN e.StatusWord THEN s1 \A\ 'divide by zero '; FatalError( s1 );
- ELSIF 3 IN e.StatusWord THEN s1 \A\ 'overflow'; FatalError( s1 );
- ELSE FatalError('RAM Parity error'); END;
- END NmiTrap;
- (*$J-,C F0*)
- PROCEDURE EnableExceptionHandling;
- BEGIN
- LoadControlWord(StoreControlWord()-{0,1,2,3});
- END EnableExceptionHandling;
- PROCEDURE DisableExceptionHandling;
- BEGIN
- LoadControlWord(StoreControlWord()+{0,1,2,3});
- END DisableExceptionHandling;
- PROCEDURE CloseDown;
- VAR
- f : CARDINAL;
- TYPE
- sb = SET OF [0..7];
- BEGIN
- DisableExceptionHandling;
- IF AT THEN
- (* disable interrupt 5 on secondary controler *)
- Out( 0A1H, SHORTCARD( sb(In(0A1H))+sb{5} ) );
- END;
- f := GetFlags(); DI; Nmi := OldNmi;
- SetFlags(f); Term;
- END CloseDown;
- PROCEDURE InstallTrap(d : CARDINAL);
- VAR
- f : CARDINAL;
- TYPE
- sb = SET OF [0..7];
- bp = POINTER TO SHORTCARD;
- BEGIN
- Base := [Seg(d):Ofs(d)+4]^; (* get program base *)
- f := GetFlags(); DI; OldNmi := Nmi; Nmi := ADR(NmiTrap);
- Terminate( CloseDown, Term );
- IF [0F000H:0FFFEH bp]^ = 0FCH THEN
- (* enable interrupt 5 on secondary controler *)
- Out( 0A1H, SHORTCARD( sb(In(0A1H))-sb{5} ) );
- AT := TRUE;
- ELSE
- AT := FALSE;
- END;
- EnableExceptionHandling; SetFlags(f);
- END InstallTrap;
- BEGIN
- InstallTrap(0);
- END FloatExc.
|