home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TP5FIX87.ZIP / TP5FIX87.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-06-11  |  5.7 KB  |  148 lines

  1. (*   This simple unit takes care of two lingering problems in TP5:
  2.  
  3.    1) when running a TP5 program from the DOS environment, only an error
  4.       number is displayed, rather than a text message;
  5.    2) when using a math coprocessor, the error address is not correct.
  6.  
  7.      The first problem simply requires linking to the ExitProc handler,
  8.       recovering the error message and address if one occurs, and printing
  9.       a text message.
  10.  
  11.      The second problem is caused by the curious behavior of the x87 and
  12.       Borland laziness.  On a floating point error, the 20 bit address of
  13.       the instruction causing the error is stored in the x87.  Note that
  14.       the segment and offset of the address is NOT stored.  The Borland
  15.       error handler makes no attempt to compute the address in their format
  16.       (segment and offset relative to the beginning of the main program), and
  17.       consequently does not always report the correct address.  This unit
  18.       computes and reports the 20 bit offset of the erroneous instruction
  19.       relative to the start of the main program.  This address is what is
  20.       required to find the error if the error is in the unit containing the
  21.       main program.  If the address is not in this unit, the MAP file produced
  22.       by the compiler must be used to compute the address relative to the
  23.       start of the offending unit.
  24.  
  25.       Joe Ahlgren    RBBS 703-241-7980
  26.  
  27. *)
  28.  
  29. unit TP5FIX87;
  30.  
  31.   interface
  32.  
  33.   implementation
  34.  
  35. {$F+}
  36.   var
  37.     ExitSave: pointer;
  38.   const
  39.     MaxArray = 40;
  40.   type
  41.     ErrorRecordType = record
  42.                     ErrorNumber: byte;
  43.                     ErrorTitle: string[35];
  44.                     end;
  45.     ErrorArrayType = array [1..MaxArray] of ErrorRecordType;
  46.   const
  47.     ErrorArray: ErrorArrayType =
  48.  (  (ErrorNumber: 002; ErrorTitle: 'File not found'),
  49.     (ErrorNumber: 003; ErrorTitle: 'Path not found'),
  50.     (ErrorNumber: 004; ErrorTitle: 'Too many open files'),
  51.     (ErrorNumber: 005; ErrorTitle: 'File access denied'),
  52.     (ErrorNumber: 006; ErrorTitle: 'Invalid file handle'),
  53.     (ErrorNumber: 012; ErrorTitle: 'Invalid file access code'),
  54.     (ErrorNumber: 015; ErrorTitle: 'Invalid drive number'),
  55.     (ErrorNumber: 016; ErrorTitle: 'Cannot remove current directory'),
  56.     (ErrorNumber: 017; ErrorTitle: 'Cannot rename across drives'),
  57.     (ErrorNumber: 100; ErrorTitle: 'Disk read error'),
  58.     (ErrorNumber: 101; ErrorTitle: 'Disk write error'),
  59.     (ErrorNumber: 102; ErrorTitle: 'File not assigned'),
  60.     (ErrorNumber: 103; ErrorTitle: 'File not open'),
  61.     (ErrorNumber: 104; ErrorTitle: 'File not open for input'),
  62.     (ErrorNumber: 105; ErrorTitle: 'File not open for output'),
  63.     (ErrorNumber: 106; ErrorTitle: 'Invalid numeric format'),
  64.     (ErrorNumber: 150; ErrorTitle: 'Disk is write protected'),
  65.     (ErrorNumber: 151; ErrorTitle: 'Unknown unit'),
  66.     (ErrorNumber: 152; ErrorTitle: 'Drive not ready'),
  67.     (ErrorNumber: 153; ErrorTitle: 'Unknown command'),
  68.     (ErrorNumber: 154; ErrorTitle: 'CRC error in data'),
  69.     (ErrorNumber: 155; ErrorTitle: 'Bad drive request structure length'),
  70.     (ErrorNumber: 156; ErrorTitle: 'Disk seek error'),
  71.     (ErrorNumber: 157; ErrorTitle: 'Unknown media type'),
  72.     (ErrorNumber: 158; ErrorTitle: 'Sector not found'),
  73.     (ErrorNumber: 159; ErrorTitle: 'Printer out of paper'),
  74.     (ErrorNumber: 160; ErrorTitle: 'Device write fault'),
  75.     (ErrorNumber: 161; ErrorTitle: 'Device read fault'),
  76.     (ErrorNumber: 162; ErrorTitle: 'Hardware failure'),
  77.     (ErrorNumber: 200; ErrorTitle: 'Division by zero'),
  78.     (ErrorNumber: 201; ErrorTitle: 'Range check error'),
  79.     (ErrorNumber: 202; ErrorTitle: 'Stack overflow error'),
  80.     (ErrorNumber: 203; ErrorTitle: 'Heap overflow error'),
  81.     (ErrorNumber: 204; ErrorTitle: 'Invalid pointer operation'),
  82.     (ErrorNumber: 205; ErrorTitle: 'Floating point overflow'),
  83.     (ErrorNumber: 206; ErrorTitle: 'Floating point underflow'),
  84.     (ErrorNumber: 207; ErrorTitle: 'Invalid floating point operation'),
  85.     (ErrorNumber: 208; ErrorTitle: 'Overlay manager not installed'),
  86.     (ErrorNumber: 209; ErrorTitle: 'Overlay file read error'),
  87.     (ErrorNumber: 255; ErrorTitle: 'User Break') );
  88.  
  89.   type HexType = String[4];
  90.     type
  91.       St16 = string[16];
  92.     const
  93.       HexDigits:St16 = '0123456789abcdef';
  94.   function Hex(x: word): HexType;
  95.     var
  96.       k: integer;
  97.       s: HexType;
  98.     begin
  99.       s:='';
  100.       for k:=1 to 4 do
  101.         begin
  102.         s:=HexDigits[(x and $000f)+1]+s;
  103.         x:=x shr 4;
  104.         end;
  105.       Hex:=s;
  106.     end;
  107.  
  108.   procedure FPerrorExit;
  109.     var
  110.       ec,j,k: word;
  111.       s: string[10];
  112.       msg,msg2: string[80];
  113.       ExitArray: array [1..2] of word absolute ErrorAddr;
  114.       ErrorAddr87: LongInt;
  115.       IP87: array [0..1] of word absolute ErrorAddr87;
  116.       Diagnose87: array [-5..6] of word absolute SaveInt75;
  117.     begin
  118.       ExitProc:=ExitSave;
  119.       if ExitCode > 0 then
  120.         begin
  121.         ec:=ExitCode;
  122.         Str(ec,msg);
  123.         k:=0;
  124.         for j:=1 to MaxArray do
  125.           if ErrorArray[j].ErrorNumber = ec then
  126.             k:=j;
  127.         if k <> 0 then
  128.           msg:=msg+' '+ErrorArray[k].ErrorTitle
  129.          else
  130.           msg:=msg+' ?';
  131.         msg:=' Error '+msg+' at '+Hex(ExitArray[2])+':'+Hex(exitArray[1]);
  132.         ErrorAddr87:=Diagnose87[4] and $f000;
  133.         ErrorAddr87:=ErrorAddr87*$10 + Diagnose87[3] -
  134.                         LongInt(Prefixseg+$10)*$10;
  135.         IP87[1]:=IP87[1] and $000f;
  136.         msg2:=' loaded at '+Hex(PrefixSeg+16) + ', 87 IP=' +
  137.                   HexDigits[IP87[1]+1] + Hex(IP87[0]);
  138.         WriteLn(msg);
  139.         WriteLn(msg2);
  140.         end;
  141.     end;
  142.  
  143.  
  144.     begin
  145.     ExitSave:=ExitProc;
  146.     ExitProc:=@FPerrorExit;
  147.     end.
  148.