[Back to INTERRUP SWAG index] [Back to Main SWAG index] [Original]
==============================================================================
BBS: -=- Edge of the Century -=-
To: DANIEL KEMPTON Date: 01-20-93 (05:13)
From: GREG VIGNEAULT Number: 3196 [140] Pascal
Subj: CRITICAL ERROR HANDLER Status: Public
------------------------------------------------------------------------------
DK> Can anyone PLEASE give me information on how to write a critical
> error handler.
Below is a quick'n-dirty critical error handler, written without
any Asm (so is usable from TP v4.0+). To test it, put a write-
protected diskette in drive A:, then run the program. It should
report error #19 (13 hex, disk write-protected).
It'll need to be modified & trimmed to your purpose. You might
code your handler to simply ignore errors, then let your main
program take appropriate action, depending on the error, etc.
DOS functions $00..$0C, $30, and $59 should be safe calls from the
handler. Function $59 will return the extended error information
code that you'll need to check (eg. #32 = share violation), as well
as other data - which you can read up on, in a Dos reference text.
I've used one byte of the DOS intra-process communication area (at
$40:$F0) to return the value needed to tell Dos what to do about
the error, rather than juggle registers. This should be okay.
This code is cramped, to fit into a single message ...
{*******************************************************************}
PROGRAM Example; { Critical Error Handler }
USES Dos, { import MsDos, GetIntVec, SetIntVec, Registers }
Crt; { import CheckBreak }
VAR OldISR : POINTER; { to save original ISR ptr }
Reg : Registers; { to access CPU registers }
errNumber : WORD; { extended error code }
errClass, { error class }
errAction, { recommended action }
errLocus : BYTE; { error locus }
FileName : String[13]; { for ASCIIZ file name }
{-------------------------------------------------------------------}
PROCEDURE cErrorISR( AX,BX,CX,DX,SI,DI,DS,ES,BP : WORD); Interrupt;
BEGIN { This is it! ... }
InLine($FB); { STI (allow interrupts) }
Reg.AX := $3000; MsDos(Reg); { fn: get Dos version }
IF (Reg.AH < 3) THEN Reg.AL := 3 { if less than Dos 3+ :FAIL }
ELSE BEGIN { else take a closer look.. }
Reg.AH := $59; Reg.BX := 0; { fn: get extended info }
MsDos( Reg ); { call Dos }
errNumber := Reg.AX; { set|clear error number }
errClass := Reg.BH; errAction := Reg.BL; errLocus := Reg.CH;
WriteLn; Write( 'Critical error (#', errNumber, ') ' );
REPEAT WriteLn; { loop for user response }
Write( 'Abort, Retry, Ignore, Fail (A|R|I|F) ? ',#7);
Reg.AH := 1; MsDos(Reg); { get user input, via Dos }
UNTIL UpCase(CHR(Reg.AL)) IN ['A','R','I','F'];
CASE CHR(Reg.AL) OF { ... depending on input }
'i','I' : Reg.AL := 0; { = ignore error }
'r','R' : Reg.AL := 1; { = retry the action }
'a','A' : Reg.AL := 2; { = abort }
'f','F' : Reg.AL := 3; { = fail }
END; {case}
END; {if Reg.AH}
Mem[$40:$F0] := Reg.AL; { to tell Dos what to think }
InLine( $8B/$E5/ { mov sp,bp }
$5D/$07/$1F/$5F/$5E/ { pop bp,es,ds,di,si }
$5A/$59/$5B/$58/ { pop dx,cx,bx,ax }
$06/ { push es }
$2B/$C0/ { sub ax,ax }
$8E/$C0/ { mov es,ax }
$26/$A0/$F0/$04/ { mov al,es:[4F0h] }
$07/ { pop es }
$CF); { iret }
END {cErrorISR};
{-------------------------------------------------------------------}
BEGIN { the main program... }
CheckBreak := FALSE; { don't allow Ctrl-Break! }
errNumber := 0; { clear the error code }
GetIntVec( $24, OldISR ); { save current ISR vector }
SetIntVec( $24, @cErrorISR ); { set our ISR }
{===========================================================}
{ insert your test code here ... }
FileName := 'A:TEST.TXT' + CHR(0); { ASCIIZ file name }
Reg.DS := SEG( FileName ); { file name segment }
Reg.DX := OFS( FileName[1] ); { file name offset }
Reg.CX := 0; { normal attribute }
Reg.AH := $3C; { fn: create file }
MsDos( Reg ); { via Dos }
{===========================================================}
IF (errNumber <> 0) THEN BEGIN
Write(#13#10#10,'For error #',errNumber,', user requested ');
CASE Mem[$40:$F0] OF
0 : WriteLn('IGNORE'); { just your imagination }
1 : WriteLn('RETRY'); { ... endless futility ? }
2 : WriteLn('ABORT'); { DOS won't come back here! }
3 : WriteLn('FAIL'); { call technical support }
END; {case}
END; {if errNumber<>0}
SetIntVec( $24, OldISR ); { must restore original ISR }
END.
{*******************************************************************}
Greg_
Jan.20.1993.Toronto.Canada. greg.vigneault@bville.gts.org
---
* Baudeville BBS Toronto CANADA 416-283-0114 2200+ confs
* PostLink(tm) v1.04 BAUDEVILLE (#1412) : RelayNet(tm)
[Back to INTERRUP SWAG index] [Back to Main SWAG index] [Original]