floatexc.mod 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. (* Copyright (C) 1987 Jensen & Partners International *)
  2. IMPLEMENTATION MODULE FloatExc;
  3. FROM SYSTEM IMPORT In,Out,DI,GetFlags,SetFlags,Seg,Ofs,Registers;
  4. FROM Lib IMPORT FatalError,Terminate,Intr;
  5. FROM MATHLIB IMPORT StoreControlWord,LoadControlWord,ClearExceptions,
  6. StoreEnvironment,Environment;
  7. IMPORT Str;
  8. VAR
  9. Nmi[0:2*4], OldNmi : ADDRESS;
  10. Term : PROC;
  11. Base : CARDINAL;
  12. AT : BOOLEAN;
  13. (*$J+,C FF*)
  14. PROCEDURE NmiTrap(Dummy: CARDINAL);
  15. VAR
  16. e : Environment;
  17. s1,s2 : ARRAY [0..49] OF CHAR;
  18. Done : BOOLEAN;
  19. l : LONGCARD;
  20. CONST
  21. A = Str.Append;
  22. BEGIN
  23. IF AT THEN Out(20H,20H); END;
  24. e := StoreEnvironment();
  25. ClearExceptions;
  26. l := LONGCARD(e.IP)+LONGCARD(e.Opcode DIV 1000H)*10000H;
  27. Str.CardToStr(l,s2,16,Done);
  28. s1 := '['; s1 \A\ s2; s1 \A\ '-';
  29. l := l-LONGCARD(Base)*10H;
  30. Str.CardToStr(l,s2,16,Done);
  31. s1 \A\ s2; s1 \A\ '] Float Error : ';
  32. IF 0 IN e.StatusWord THEN s1 \A\ 'invalid operation '; FatalError( s1 );
  33. ELSIF 1 IN e.StatusWord THEN s1 \A\ 'denormalized operand'; FatalError( s1 );
  34. ELSIF 2 IN e.StatusWord THEN s1 \A\ 'divide by zero '; FatalError( s1 );
  35. ELSIF 3 IN e.StatusWord THEN s1 \A\ 'overflow'; FatalError( s1 );
  36. ELSE FatalError('RAM Parity error'); END;
  37. END NmiTrap;
  38. (*$J-,C F0*)
  39. PROCEDURE EnableExceptionHandling;
  40. BEGIN
  41. LoadControlWord(StoreControlWord()-{0,1,2,3});
  42. END EnableExceptionHandling;
  43. PROCEDURE DisableExceptionHandling;
  44. BEGIN
  45. LoadControlWord(StoreControlWord()+{0,1,2,3});
  46. END DisableExceptionHandling;
  47. PROCEDURE CloseDown;
  48. VAR
  49. f : CARDINAL;
  50. TYPE
  51. sb = SET OF [0..7];
  52. BEGIN
  53. DisableExceptionHandling;
  54. IF AT THEN
  55. (* disable interrupt 5 on secondary controler *)
  56. Out( 0A1H, SHORTCARD( sb(In(0A1H))+sb{5} ) );
  57. END;
  58. f := GetFlags(); DI; Nmi := OldNmi;
  59. SetFlags(f); Term;
  60. END CloseDown;
  61. PROCEDURE InstallTrap(d : CARDINAL);
  62. VAR
  63. f : CARDINAL;
  64. TYPE
  65. sb = SET OF [0..7];
  66. bp = POINTER TO SHORTCARD;
  67. BEGIN
  68. Base := [Seg(d):Ofs(d)+4]^; (* get program base *)
  69. f := GetFlags(); DI; OldNmi := Nmi; Nmi := ADR(NmiTrap);
  70. Terminate( CloseDown, Term );
  71. IF [0F000H:0FFFEH bp]^ = 0FCH THEN
  72. (* enable interrupt 5 on secondary controler *)
  73. Out( 0A1H, SHORTCARD( sb(In(0A1H))-sb{5} ) );
  74. AT := TRUE;
  75. ELSE
  76. AT := FALSE;
  77. END;
  78. EnableExceptionHandling; SetFlags(f);
  79. END InstallTrap;
  80. BEGIN
  81. InstallTrap(0);
  82. END FloatExc.
  83.