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
|