int24.mod 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. IMPLEMENTATION MODULE Int24 ;
  2. (* Int 24 - Critical Error handler *)
  3. IMPORT SYSTEM,AsmLib,Str,IO ;
  4. (* The pop stack inline code is required if the program should
  5. continue after an abort (returning 255 to the calling program).
  6. If ContinueProg is set to FALSE then the program will terminate
  7. on 'abort' ;
  8. *)
  9. CONST
  10. ContinueProg = FALSE ;
  11. TYPE
  12. Code = ARRAY[0..27] OF SHORTCARD ;
  13. CONST
  14. PopStackCode = Code(
  15. 58H, (* POP AX *)
  16. 58H, (* POP AX *)
  17. 58H, (* POP AX *)
  18. 5BH, (* POP BX *)
  19. 89H,0C4H, (* MOV SP,AX *)
  20. 9DH, (* POPF *)
  21. 58H, (* POP AX *)
  22. 5BH, (* POP BX *)
  23. 59H, (* POP CX *)
  24. 5AH, (* POP DX *)
  25. 5EH, (* POP SI *)
  26. 5FH, (* POP DI *)
  27. 58H, (* POP AX *)
  28. 1FH, (* POP DS *)
  29. 07H, (* POP ES *)
  30. 89H,0E5H, (* MOV BP,SP *)
  31. 80H,4EH,04H,01H, (* OR Byte Ptr [BP+04],01 ; set carry *)
  32. 89H,0C5H, (* MOV BP,AX *)
  33. 0B8H,0FFH,00H, (* MOV AX,00FF *) (* Return error *)
  34. 0CFH) ; (* IRET *)
  35. TYPE PopStackProc = PROCEDURE ( VAR CARDINAL ) ;
  36. (*$C 00,N*) PROCEDURE (*$F*) ForceSave(p : CARDINAL) : CARDINAL; FORWARD; (*$C F0,F*)
  37. (* NB! Has to be forward otherwise compiler will spot that
  38. registers are not being used
  39. *)
  40. (*$C FF,J+*)
  41. PROCEDURE Int24Handler( Dummy : CARDINAL );
  42. TYPE IntReg1 = RECORD
  43. DI,SI,ES,DS : CARDINAL;
  44. CASE : BOOLEAN OF
  45. TRUE : BX,DX,CX,AX : CARDINAL; |
  46. FALSE : BL,BH,DL,DH,CL,CH,AL,AH : SHORTCARD;
  47. END;
  48. END;
  49. VAR
  50. RegP1 : POINTER TO IntReg1;
  51. PopStack : PopStackProc ;
  52. saveipf : BOOLEAN ;
  53. s : ARRAY[0..40] OF CHAR ;
  54. k : CHAR ;
  55. BEGIN
  56. RegP1 := [SYSTEM.Seg( Dummy ):ForceSave(0)+2]; (* must be first in procedure *)
  57. saveipf := AsmLib.GetInProgramFlag() ;
  58. AsmLib.SetInProgramFlag( TRUE );
  59. WITH RegP1^ DO
  60. CASE DI OF
  61. 0 : s := 'Disk write protected' |
  62. 2 : s := 'Drive not ready' |
  63. 9 : s := 'Printer out of paper' |
  64. ELSE
  65. s := 'Disk error' ;
  66. END ;
  67. Str.Append(s,'. Abort, Retry, Ignore?');
  68. IO.WrStr(s) ; IO.WrLn ;
  69. REPEAT
  70. k := CAP(IO.RdKey()) ;
  71. UNTIL (k='R') OR (k='I') OR (k='A') ;
  72. IF k='I' THEN AL := 0 ; (* ignore *)
  73. ELSIF k='R' THEN AL := 1 ; (* retry *)
  74. ELSE (* abort *)
  75. IF ContinueProg THEN
  76. PopStack := PopStackProc(ADR(PopStackCode)) ;
  77. PopStack(Dummy);
  78. (* Remove MSDOS call frame and Return 255 to caller *)
  79. (* Does not return here *)
  80. ELSE
  81. HALT ;
  82. END ;
  83. END ;
  84. END;
  85. AsmLib.SetInProgramFlag( saveipf ); (* returning to DOS *)
  86. END Int24Handler;
  87. (*$C F0,J-*)
  88. PROCEDURE ForceSave( p : CARDINAL): CARDINAL;
  89. BEGIN
  90. RETURN SYSTEM.Ofs( p );
  91. END ForceSave;
  92. VAR
  93. Int24Vec[0:24H*4] : PROCEDURE ( CARDINAL ) ;
  94. BEGIN
  95. SYSTEM.DI ;
  96. (* Install interrupt 24 *)
  97. Int24Vec := Int24Handler ;
  98. SYSTEM.EI ;
  99. END Int24.
  100.