| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- IMPLEMENTATION MODULE Int24 ;
- (* Int 24 - Critical Error handler *)
- IMPORT SYSTEM,AsmLib,Str,IO ;
- (* The pop stack inline code is required if the program should
- continue after an abort (returning 255 to the calling program).
- If ContinueProg is set to FALSE then the program will terminate
- on 'abort' ;
- *)
- CONST
- ContinueProg = FALSE ;
- TYPE
- Code = ARRAY[0..27] OF SHORTCARD ;
- CONST
- PopStackCode = Code(
- 58H, (* POP AX *)
- 58H, (* POP AX *)
- 58H, (* POP AX *)
- 5BH, (* POP BX *)
- 89H,0C4H, (* MOV SP,AX *)
- 9DH, (* POPF *)
- 58H, (* POP AX *)
- 5BH, (* POP BX *)
- 59H, (* POP CX *)
- 5AH, (* POP DX *)
- 5EH, (* POP SI *)
- 5FH, (* POP DI *)
- 58H, (* POP AX *)
- 1FH, (* POP DS *)
- 07H, (* POP ES *)
- 89H,0E5H, (* MOV BP,SP *)
- 80H,4EH,04H,01H, (* OR Byte Ptr [BP+04],01 ; set carry *)
- 89H,0C5H, (* MOV BP,AX *)
- 0B8H,0FFH,00H, (* MOV AX,00FF *) (* Return error *)
- 0CFH) ; (* IRET *)
- TYPE PopStackProc = PROCEDURE ( VAR CARDINAL ) ;
- (*$C 00,N*) PROCEDURE (*$F*) ForceSave(p : CARDINAL) : CARDINAL; FORWARD; (*$C F0,F*)
- (* NB! Has to be forward otherwise compiler will spot that
- registers are not being used
- *)
- (*$C FF,J+*)
- PROCEDURE Int24Handler( Dummy : CARDINAL );
- TYPE IntReg1 = RECORD
- DI,SI,ES,DS : CARDINAL;
- CASE : BOOLEAN OF
- TRUE : BX,DX,CX,AX : CARDINAL; |
- FALSE : BL,BH,DL,DH,CL,CH,AL,AH : SHORTCARD;
- END;
- END;
- VAR
- RegP1 : POINTER TO IntReg1;
- PopStack : PopStackProc ;
- saveipf : BOOLEAN ;
- s : ARRAY[0..40] OF CHAR ;
- k : CHAR ;
- BEGIN
- RegP1 := [SYSTEM.Seg( Dummy ):ForceSave(0)+2]; (* must be first in procedure *)
- saveipf := AsmLib.GetInProgramFlag() ;
- AsmLib.SetInProgramFlag( TRUE );
- WITH RegP1^ DO
- CASE DI OF
- 0 : s := 'Disk write protected' |
- 2 : s := 'Drive not ready' |
- 9 : s := 'Printer out of paper' |
- ELSE
- s := 'Disk error' ;
- END ;
- Str.Append(s,'. Abort, Retry, Ignore?');
- IO.WrStr(s) ; IO.WrLn ;
- REPEAT
- k := CAP(IO.RdKey()) ;
- UNTIL (k='R') OR (k='I') OR (k='A') ;
- IF k='I' THEN AL := 0 ; (* ignore *)
- ELSIF k='R' THEN AL := 1 ; (* retry *)
- ELSE (* abort *)
- IF ContinueProg THEN
- PopStack := PopStackProc(ADR(PopStackCode)) ;
- PopStack(Dummy);
- (* Remove MSDOS call frame and Return 255 to caller *)
- (* Does not return here *)
- ELSE
- HALT ;
- END ;
- END ;
- END;
- AsmLib.SetInProgramFlag( saveipf ); (* returning to DOS *)
- END Int24Handler;
- (*$C F0,J-*)
- PROCEDURE ForceSave( p : CARDINAL): CARDINAL;
- BEGIN
- RETURN SYSTEM.Ofs( p );
- END ForceSave;
- VAR
- Int24Vec[0:24H*4] : PROCEDURE ( CARDINAL ) ;
- BEGIN
- SYSTEM.DI ;
- (* Install interrupt 24 *)
- Int24Vec := Int24Handler ;
- SYSTEM.EI ;
- END Int24.
|