home *** CD-ROM | disk | FTP | other *** search
- name ERRMON ;version 1.1
-
- page 60,132
-
- comment *
- monitors INT 13 disk i/o and reports any errors encountered;
- version 1.1 also reports the offending command
- and the drive, cylinder, head, sector and number of sectors requested
-
- AT disk change error is ignored
- *
-
- .radix 16
-
- attribute equ 0f ;video attribute for error message
- line equ 24d ;line for error message, 0-24
-
- cr equ 0dh
- lf equ 0a
-
- com_org equ 100 ;ORG for com files
-
- ; error codes from IBM bios listings
- sense_fail equ 0ff ;not implemented on AT
- no_error equ 0e0 ;not implemented on PC, XT
- write_fault equ 0cc ;not implemented on PC, XT
- undef_err equ 0bbh
- not_rdy equ 0aa ;not implemented on PC, XT
- time_out equ 80
- bad_seek equ 40
- bad_cntlr equ 20
- data_corrected equ 11
- bad_eec equ 10
- bad_track equ 0bh ;not implemented on AT
- bad_sector equ 0a ;not implemented on PC, XT
- dma_boundry equ 9
- bad_dma equ 8
- init_fail equ 7
- media_change equ 6 ;ignore this AT error
- bad_reset equ 5
- record_not_fnd equ 4
- write_protect equ 3
- bad_addr_mark equ 2
- bad_cmd equ 1
-
- popff macro ;simulate POPF to avoid any '286 problems
- jmp short $+3 ;jump around IRET
- iret ;pops IP, CS, FLAGS
- push cs ;CS to stack
- call cs:$-2 ;IP to stack (cs: avoids masm error)
- endm
-
- entry struc ;map each entry in the error table
- err_nmbr db ? ;error code number for this entry
- msg_offset dw ? ;offset to message text for this error
- msg_len db ? ;length of the message text
- entry ends
-
- stack struc ;stack structure
- cur_loc dw ? ;save cursor location
- reg_bp dw ?
- reg_di dw ?
- reg_si dw ?
- reg_dx dw ? ;cx and dx hold the
- reg_cx dw ? ; drive, cylinder, head, sector info
- reg_bx dw ?
- reg_ax dw ?
- reg_f dw ? ;cy if error, code in ah
- stack ends
-
- errmon segment para public 'CODE'
- assume cs:errmon
- org com_org
-
- start: jmp init ;go install
-
- err_tbl db sense_fail
- dw msg_ff
- db len_ff
- db no_error
- dw msg_e0
- db len_e0
- db write_fault
- dw msg_cc
- db len_cc
- ude db undef_err
- dw msg_bb
- db len_bb
- db not_rdy
- dw msg_aa
- db len_aa
- db time_out
- dw msg_80
- db len_80
- db bad_seek
- dw msg_40
- db len_40
- db bad_cntlr
- dw msg_20
- db len_20
- db data_corrected
- dw msg_11
- db len_11
- db bad_eec
- dw msg_10
- db len_10
- db bad_track
- dw msg_0b
- db len_0b
- db bad_sector
- dw msg_0a
- db len_0a
- db dma_boundry
- dw msg_09
- db len_09
- db bad_dma
- dw msg_08
- db len_08
- db init_fail
- dw msg_07
- db len_07
- ; db media_change ;ignore this AT error
- ; dw msg_06
- ; db len_06
- db bad_reset
- dw msg_05
- db len_05
- db record_not_fnd
- dw msg_04
- db len_04
- db write_protect
- dw msg_03
- db len_03
- db bad_addr_mark
- dw msg_02
- db len_02
- db bad_cmd
- dw msg_01
- db len_01
- nmbr_errs equ ($-err_tbl)/size entry
-
- msg_ff db 'Sense failure'
- len_ff equ $-msg_ff
- msg_e0 db 'Status error'
- len_e0 equ $-msg_e0
- msg_cc db 'Write fault'
- len_cc equ $-msg_cc
- msg_bb db 'Undefined error'
- len_bb equ $-msg_bb
- msg_aa db 'Drive not ready'
- len_aa equ $-msg_aa
- msg_80 db 'No response'
- len_80 equ $-msg_80
- msg_40 db 'Seek failure'
- len_40 equ $-msg_40
- msg_20 db 'Controller failure'
- len_20 equ $-msg_20
- msg_11 db 'EEC error corrected'
- len_11 equ $-msg_11
- msg_10 db 'Bad CRC/EEC on read'
- len_10 equ $-msg_10
- msg_0b db 'Bad track'
- len_0b equ $-msg_0b
- msg_0a db 'Bad sector'
- len_0a equ $-msg_0a
- msg_09 db 'DMA boundry crossed'
- len_09 equ $-msg_09
- msg_08 db 'DMA overrun'
- len_08 equ $-msg_08
- msg_07 db 'Drive init failure'
- len_07 equ $-msg_07
- ;msg_06 db 'Disk changed' ;ignore this AT error
- ;len_06 equ $-msg_06
- msg_05 db 'Drive reset failure'
- len_05 equ $-msg_05
- msg_04 db 'Sector not found'
- len_04 equ $-msg_04
- msg_03 db 'Disk write protected'
- len_03 equ $-msg_03
- msg_02 db 'DAM not found'
- len_02 equ $-msg_02
- msg_01 db 'Bad drive or command'
- len_01 equ $-msg_01
-
- msg_0 db ' ' ;display location of error sector
- cmd db 2 dup (0)
- db 'D'
- drive db 2 dup (0)
- db 'C'
- cyl db 4 dup (0)
- db 'H'
- head db 2 dup (0)
- db 'S'
- sector db 2 dup (0)
- db 'N'
- number db 2 dup (0)
- len_0 equ $-msg_0
-
- int13 label dword
- sav_int13 dw 2 dup(0) ;previous INT 13 vector
- sav_ax dw 0 ;save command, number sectors requested
- sav_col db 0 ;save number of screen columns
-
- ; INT 13 enters here
- error proc far
- pushf ;real INT 13 expects flags on stack
- mov cs:[sav_ax],ax ;save command, number of sectors
- call cs:[int13] ;do the real INT 13
- jc chk_6 ;go if we have an error condition
- ret 2 ;else discard caller's flags and return
- chk_6: pushf ;save the flags from INT 13 for caller
- cmp ah,media_change ;disk change error?
- jne valid_err ;no
- jmp exit ;yes, ignore it
-
- ; have a valid error, first save registers to be used
- valid_err:
- push ax ;ah = error code
- push bx
- push cx ;cl = sector and high bits of cylinder, ch = cylinder
- push dx ;dl = drive, dh = head
- push si
- push di
- push bp
-
- ; find the error in the table
- mov di,offset err_tbl ;=> table
- mov cx,nmbr_errs ;load number of errors in table
- search: cmp ah,cs:[di].err_nmbr ;no SCAS, can't override ES register!
- je found ;got a match
- add di,size entry ;bump to next table entry
- loop search
- mov di,offset ude ;make it an undefined error
-
- ; find out where to print the report
- found: mov ah,15d
- int 10 ;get current mode, columns, page
- mov cs:[sav_col],ah ;save for end of line check
- sub ah,cs:[di].msg_len ;columns less msg_x
- sub ah,len_0 ;less msg_0
- jns len_ok ;if column >= 0
- xor ah,ah ;else set column to 0
- len_ok: mov al,ah ;starting column to al
- mov ah,line ;row to ah
- push ax ;save row, column to write to
- mov bp,sp ;=> stack
-
- ; calculate the offending sector location
- mov si,offset drive
- mov ax,[bp].reg_dx
- call cvt1 ;process drive number
- mov si,offset head
- mov al,ah
- call cvt1 ;process head number
- mov si,offset cyl
- mov ax,[bp].reg_cx
- mov bl,al ;save for later
- and al,11000000b ;mask for high cyl bits
- rol al,1
- rol al,1 ;move to low nibble
- call cvt1 ;process 1st part of cyl number
- mov al,ah
- call cvt1 ;process 2nd part of cyl number
- mov si,offset sector
- mov al,bl ;restore
- and al,00111111b ;mask for sector number bits
- call cvt1 ;process sector number
- mov si,offset number
- mov ax,cs:[sav_ax]
- call cvt1 ;process number of sectors
- mov si,offset cmd
- mov al,ah
- call cvt1 ;process command number
-
- ; write the report to the screen
- mov ah,3
- int 10 ;get current cursor position
- xchg dx,[bp].cur_loc ;swap cursor positions
- mov bl,attribute ;video attribute
- mov cx,1 ;number characters to write
- mov si,cs:[di].msg_offset ;=> msg_x
- mov di,cs:[di].word ptr msg_len ;get len msg_x
- and di,0000000011111111b ;need to clear high bits
- call write ;write it
- mov si,offset msg_0 ;=> msg_0
- mov di,len_0 ;get len msg_0
- call write ;write it
- pop dx ;old cursor position
- mov ah,2
- int 10 ;restore cursor position
-
- ; now let caller do its thing with the error
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- exit: popff
- ret 2 ;done, discard flags from caller
- error endp
-
- ; convert hex byte in al to two ascii digits, store in si, si+1
- cvt1 proc near
- mov ch,al ;will need again
- mov cl,4
- shr al,cl ;high nibble to low
- call cvt2 ;make it ascii and store
- mov al,ch ;recover byte
- and al,00001111b ;mask for low nibble
- cvt2: add al,'0' ;make an ascii digit
- cmp al,'9' ;need adjustment?
- jbe no_adj ;nope
- add al,7 ;adjust to A-F
- no_adj: mov cs:[si],al ;stuff in msg_0
- inc si ;bump pointer
- ret
- cvt1 endp
-
- ; write a defined length string to the screen
- write proc near
- cmp cs:[sav_col],dl ;end of line?
- jbe no_wrt ;yes
- mov ah,2
- int 10 ;reset cursor position
- inc dl ;bump column
- mov al,cs:[si] ;get char to write
- inc si ;bump pointer
- mov ah,9
- int 10 ;put it on screen
- dec di ;decrement counter
- jnz write ;if more to write
- no_wrt: ret
- write endp
-
- pgm_len equ $-start+com_org ;rinky dink to get an absolute constant
- remain equ pgm_len mod 10 gt 0 ;any remainder?
- prot equ (pgm_len/10)-remain ;convert bytes to paragraphs, round
-
- assume cs:errmon, ds:errmon, es:errmon, ss:errmon
-
- id db 'ERRMON Version 1.1 - Copyright (C) 1985 by Robert J. Newton',cr,lf,'$'
- dos_msg db 'ERRMON requires DOS 2.0 or greater',cr,lf,'$'
-
- init proc near
- mov ah,30
- int 21
- cmp al,2
- jb bad_dos ;dos 2.x+ required
- mov cx,es
- mov ax,3513
- int 21 ;fetch INT 13 vector
- mov [sav_int13],bx
- mov [sav_int13+2],es ;save in error proc
- mov es,cx
- mov dx,offset error ;=> new INT 13 routine
- mov ax,2513
- int 21 ;set INT 13 to error
- mov dx,offset id ;=> msg
- mov ah,9
- int 21 ;show id
- mov dx,prot ;paragraphs to protect
- mov ax,3100
- int 21 ;TSR, no error
-
- bad_dos:
- mov dx,offset dos_msg
- mov ah,9
- int 21 ;show bad news
- mov ax,4cff
- int 21 ;flag error at exit
- init endp
-
- errmon ends
-
- end start
-