1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
PAGE ,132
; A sample Interrupt 24 (DOS critical error exception) handler
;
; Public domain by Bob Stout
;
; Requires MASM 5.1 or later or equivalent
;
; Assemble with: MASM /Mx /z ...
; TASM /jMASM /mx /z ...
% .MODEL memodel,C ;Add model support via command
;line macros, e.g.
;MASM /Dmemodel=LARGE
EXTRN cedevdvr:dword, cetype:word, ceerror:word, cereturn:byte
EXTRN read_err:far, write_err:far, term_err:far
EXTRN no_paper:far, fixup_ret:far, FAT_err:far
;NOTE: All the above routines MUST set cereturn to:
; 0 - Ignore
; 1 - Retry
; 2 - Abort
; 3 - Fail (DOS 3.3 and later)
.DATA?
PUBLIC osver, rmvbl, exerr, locus, class, suggest
osver db ?
rmvbl db ?
exerr dw ?
locus db ?
class db ?
suggest db ?
.CODE
;
; This is called by myint24
;
; extern int (*read_err)(),
; (*write_err)(),
; (*term_err)(),
; (*no_paper)(),
; (*fixup_ret)(),
; (*FAT_err)();
;
; Each returns: 0 - Ignore
; 1 - Retry
; 2 - Abort
; 3 - Fail (DOS 3.3 and later)
;
mynew24 PROC USES BX
mov ah,030h ;get DOS version number
int 21
or al,al ;zero means DOS 1.x
jnz NotDOS1
mov al,1
NotDOS1:
mov osver,al ;save DOS version
mov ax,cetype ;get type of exception...
mov bx,ax ; & save it for later
and ax,80h ;disk error?
jnz NotDiskErr ;no, continue
cmp al,1 ;yes, DOS 1.x?
jz wrong_DOS ;yes, can't check for removable media
mov ah,-1 ;no, assume removable media
test word PTR cedevdvr,0800h ;is the media removable?
jz removable
xor ah,ah ;no, flag fixed media
removable:
mov rmvbl,ah ;save media type
cmp al,3 ;DOS 3.0 or greater?
jb wrong_DOS ;no, skip it
push bx ;yes, save cetype info...
push ds ; & other regs
push es
push dx
push si
push di
push bp
mov ah,59h ;get extended error info
int 21
pop bp ;restore regs
pop di
pop si
pop dx
pop es
pop ds
mov exerr,ax ;save extended error code...
mov locus,ch ; locus...
mov class,bh ; class...
mov suggest,bl ; & suggested action
pop bx ;restore cetype info
wrong_DOS:
mov ax,bx ;get exception type
and ax,06h ;FAT problems?
cmp ax,02h
jnz ok_fat ;no, continue
jmp far PTR FAT_err ;yes, handle it
ok_fat:
mov ax,bx ;get exception type
and ax,01h ;handle read and write separately
jz rd_err
jmp far PTR write_err
rd_err:
jmp far PTR read_err
NotDiskErr:
test ceerror,0009h ;printer out of paper?
jnz not_eop ;no, continue
jmp far PTR no_paper ;yes, handle it
not_eop:
test word PTR cedevdvr,8000h ;character device?
jnz unknown ;no, continue
jmp far PTR term_err ;yes, assume bad terminal I/O
;
; If we get here, we haven't identified the error. We now call fixup_ret()
; to resolve which action to take. This will usually involve the information
; in exerr qualified by the version of DOS in use and is best left to coding
; in a higher level language like C.
;
; NOTE: It is IMPERATIVE that the return value of fixup_ret() default to 2
; to insure that if all else fails, the critcal error handler aborts!
;
unknown:
call far PTR fixup_ret ;unknown error - handle loose ends...
xor ah,ah ; & return
mov cereturn,al
ret
mynew24 ENDP
end
|