967 |
mateusz.vi |
1 |
;
|
|
|
2 |
; WORK IN PROGRESS TEMPLATE! NOT USED YET
|
|
|
3 |
;
|
|
|
4 |
; int 24h handler, part of SvarCOM. MIT license.
|
|
|
5 |
; Copyright (C) 2022 Mateusz Viste
|
|
|
6 |
;
|
|
|
7 |
; this is an executable image that can be set up as the critical error handler
|
|
|
8 |
; interrupt (int 24h). It displays the usual "Abort, retry, fail" prompt.
|
|
|
9 |
;
|
|
|
10 |
|
|
|
11 |
org 0 ; this code does not have a PSP, it is loaded as-is into a memory
|
|
|
12 |
; segment
|
|
|
13 |
|
|
|
14 |
; === CRIT HANDLER DETAILS ====================================================
|
|
|
15 |
;
|
|
|
16 |
; *** ON ENTRY ***
|
|
|
17 |
;
|
|
|
18 |
; upon entry to the INT 24h handler, the registers are as follows:
|
|
|
19 |
; BP:SI = addr of a "device header" that identifies the failing device
|
|
|
20 |
; DI = error code in lower 8 bits (only for non-disk errors)
|
|
|
21 |
; AL = drive number, but only if AH bit 7 is reset
|
|
|
22 |
; AH = error flags
|
|
|
23 |
; 0x80 = reset if device is a disk, set otherwise
|
|
|
24 |
; all the following are valid ONLY for disks (0x80 reset):
|
|
|
25 |
; 0x20 = set if "ignore" action allowed
|
|
|
26 |
; 0x10 = set if "retry" action allowed
|
|
|
27 |
; 0x08 = set if "fail" action allowed
|
|
|
28 |
; 0x06 = disk area, 0=sys files, 1=fat, 10=directory, 11=data
|
|
|
29 |
; 0x01 = set if failure is a write, reset if read
|
|
|
30 |
;
|
|
|
31 |
; within the int 24h handler, only these DOS functions are allowed:
|
|
|
32 |
; 01H-0CH (DOS character I/O)
|
|
|
33 |
; 33H (all subfns are OK, including 3306H get DOS version)
|
|
|
34 |
; 50H (set PSP address)
|
|
|
35 |
; 51H and 62H (query PSP address)
|
|
|
36 |
; 59H (get extended error information)
|
|
|
37 |
;
|
|
|
38 |
;
|
|
|
39 |
; *** ON EXIT ***
|
|
|
40 |
;
|
|
|
41 |
; After handling the error, AL should be set with an action code and get back
|
|
|
42 |
; to DOS. Available actions are defined in AH at entry (see above). Possible
|
|
|
43 |
; values on exit are:
|
|
|
44 |
; AL=0 ignore error (pretend nothing happenned)
|
|
|
45 |
; AL=1 retry operation
|
|
|
46 |
; AL=2 abort (terminates the failed program via int 23h, like ctrl+break)
|
|
|
47 |
; AL=3 return to application indicating a failure of the DOS function
|
|
|
48 |
;
|
|
|
49 |
; A very basic "always fail" handler would be as simple as this:
|
|
|
50 |
; mov al, 3
|
|
|
51 |
; iret
|
|
|
52 |
; =============================================================================
|
|
|
53 |
|
|
|
54 |
|
|
|
55 |
; save registers so I can restore them later
|
|
|
56 |
push ah
|
|
|
57 |
push bx
|
|
|
58 |
push cx
|
|
|
59 |
push dx
|
|
|
60 |
pushf
|
|
|
61 |
|
|
|
62 |
; disk errors product this message:
|
|
|
63 |
; CRITICAL ERROR - DRIVE A: - READ|WRITE FAILURE
|
|
|
64 |
; (A)bort, (R)etry, (F)ail
|
|
|
65 |
;
|
|
|
66 |
; non-disk errors produce this:
|
|
|
67 |
; CRITICAL ERROR #errno
|
|
|
68 |
|
|
|
69 |
|
|
|
70 |
; restore registers and quit the handler
|
|
|
71 |
popf
|
|
|
72 |
pop dx
|
|
|
73 |
pop cx
|
|
|
74 |
pop bx
|
|
|
75 |
pop ah
|
|
|
76 |
|
|
|
77 |
iret
|
|
|
78 |
|
|
|
79 |
|
|
|
80 |
; write DX string to stderr
|
|
|
81 |
write_dx_str_to_stderr:
|
|
|
82 |
push ax
|
|
|
83 |
push bx
|
|
|
84 |
push cx
|
|
|
85 |
|
|
|
86 |
mov ah, 0x40 ; write to file -- am I sure I can use this function safely?
|
|
|
87 |
mov bx, 2 ; stderr
|
|
|
88 |
mov cx, 1 ; one byte
|
|
|
89 |
int 0x21
|
|
|
90 |
|
|
|
91 |
pop cx
|
|
|
92 |
pop bx
|
|
|
93 |
pop ax
|