home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / sysutl / fatal14.arc / FATAL.ASM next >
Encoding:
Assembly Source File  |  1989-12-25  |  37.0 KB  |  1,453 lines

  1. page 66,132
  2. ;
  3. ; Resident Critical Error Handler
  4. ;
  5. ; This program is a TSR that traps critical errors and attempts
  6. ; to handle them in an intelligent way.
  7. ;
  8. ; It draws on all available information to present a complete error
  9. ; description to the user, and to provide sensible default actions
  10. ; when the operator is not present.
  11. ;
  12. ; Copyright 1989 Samuel H. Smith; All rights reserved.
  13. ;
  14. ;------------------------------------------------
  15. ;
  16. ;                                  LICENSE
  17. ;                                  =======
  18. ;  SourceWare: What is it?
  19. ;  -----------------------
  20. ;
  21. ;  SourceWare is my name for a unique concept in user supported
  22. ;  software.
  23. ;
  24. ;  Programs distributed under the SourceWare concept always offer source
  25. ;  code.
  26. ;
  27. ;  This package can be freely distributed so long as it is not modified
  28. ;  or sold for profit.  If you find that this program is valuable, you
  29. ;  can send me a donation for what you think it is worth.  I suggest
  30. ;  about $10.
  31. ;
  32. ;  Send your contributions to:
  33. ;     Samuel H. Smith                 The Tool Shop BBS
  34. ;     5119 N. 11th Ave., #332         (602) 264-3969 (2400) - Free node
  35. ;     Phoenix AZ 85013                (602) 279-0230 (HAYES 9600)
  36. ;                                     (602) 279-2673 (HST 9600)
  37. ;
  38. ;  Why SourceWare?
  39. ;  ---------------
  40. ;  Why do I offer source code?  Why isn't the donation manditory?  The
  41. ;  value of good software should be self-evident.  The source code is
  42. ;  the key to complete understanding of a program.  You can read it to
  43. ;  find out how things are done.  You can also change it to suit your
  44. ;  needs, so long as you do not distribute the modified version without
  45. ;  my consent.
  46. ;
  47. ;
  48. ;  Copyright
  49. ;  ---------
  50. ;  If you modify this program,  I would appreciate a copy of the new
  51. ;  source code.  I am holding the copyright on the source code,  so
  52. ;  please don't delete my name from the program files or from the
  53. ;  documentation.
  54. ;
  55. ;                               DISCLAIMER
  56. ;                               ==========
  57. ;  I make no warranty of any kind, express or implied, including without
  58. ;  limitation, any warranties of merchantability and/or fitness for a
  59. ;  particular purpose.  I shall not be liable for any damages, whether
  60. ;  direct, indirect, special or consequential arising from a failure of
  61. ;  this program to operate in the manner desired by the user.  I shall
  62. ;  not be liable for any damage to data or property which may be caused
  63. ;  directly or indirectly by the use of this program.
  64. ;
  65. ;  IN NO EVENT WILL I BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY
  66. ;  LOST PROFITS,  LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL
  67. ;  DAMAGES ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR
  68. ;  FOR ANY CLAIM BY ANY OTHER PARTY.
  69. ;
  70.  
  71. %newpage
  72. ;------------------------------------------------
  73. ; macro- push all registers
  74. ;
  75. pushall macro
  76.         push ax
  77.         push bx
  78.         push cx
  79.         push dx
  80.         push ds
  81.         push es
  82.         push si
  83.         push di
  84.         push bp
  85. endm
  86.  
  87. ;------------------------------------------------
  88. ; macro- pop all registers
  89. ;
  90. popall macro
  91.         pop bp
  92.         pop di
  93.         pop si
  94.         pop es
  95.         pop ds
  96.         pop dx
  97.         pop cx
  98.         pop bx
  99.         pop ax
  100. endm
  101.  
  102. ;------------------------------------------------
  103. ; macro- clear register
  104. ;
  105. clr macro reg
  106.         xor reg,reg
  107. endm
  108.  
  109.  
  110. ;------------------------------------------------
  111. ; macro- dos function call
  112. ;
  113. dosDisplay     = 9h
  114. dosSetvec      = 25h
  115. dosGetvers     = 30h
  116. dosGetvec      = 35h
  117. dosFreemem     = 49h
  118. dosExit        = 4ch
  119. dosErrinfo     = 59h
  120.  
  121. msdos   macro funct,param
  122.         ifb <param>
  123.            mov ah,funct
  124.         else
  125.            mov ax,(funct*100h)+param
  126.         endif
  127.         int 21h
  128. endm
  129.  
  130. ;------------------------------------------------
  131. ; macro- get vector
  132. ; exit: vector stored in 'dword ptr ds:dest'
  133. ;
  134. getvect macro vectnum,dest
  135.         msdos dosGetvec,vectnum
  136.         mov word ptr dest,bx
  137.         mov word ptr dest+2,es
  138. endm
  139.  
  140. ;------------------------------------------------
  141. ; macro- set vector
  142. ;
  143. setvect macro vectnum,handler
  144.         lea dx,handler
  145.         msdos dosSetvec,vectnum
  146. endm
  147.  
  148.  
  149. ;------------------------------------------------
  150. ; macro- restore original vector
  151. ;
  152. revect macro vectnum,ohandler
  153.         lds dx,es:ohandler
  154.         msdos dosSetvec,vectnum
  155. endm
  156.  
  157.  
  158. ;------------------------------------------------
  159. ; macro- video function call
  160. ;
  161. vidSetcu       = 02h
  162. vidGetcu       = 03h
  163. vidGetch       = 08h
  164. vidPutch       = 09h
  165. vidTty         = 0eh
  166.  
  167. video   macro funct
  168.         mov ah,funct
  169.         int 10h
  170. endm
  171.  
  172. ;------------------------------------------------
  173. ; macro- keyboard function call
  174. ;
  175. kbdGetch       = 0
  176. kbdStatus      = 1
  177.  
  178. keybd   macro funct
  179.         mov ah,funct
  180.         int 16h
  181. endm
  182.  
  183. %newpage
  184. ;------------------------------------------------
  185. ; program segment prefix
  186. ;
  187. code segment
  188.         assume cs:code, ds:nothing, es:nothing, ss:nothing
  189.  
  190.         org 012h
  191. int24p  dd      ?       ;pointer to current int24 handler
  192.  
  193.         org 02ch
  194. envseg  dw      ?       ;environment segment number
  195.  
  196.         org 80h
  197. tailLen db      ?       ;command tail length
  198. tail    db      ?
  199.  
  200.         org 100h
  201. entry:
  202.         jmp entryPoint
  203.  
  204.  
  205.  
  206. ;------------------------------------------------
  207.  
  208. signature       db 13,10,'Resident Critical Error Handler v1.4 ',??DATE
  209.                 db 13,10,'Copyright 1989 Samuel H. Smith; ALL RIGHTS RESERVED'
  210.                 db 13,10
  211. crlfs           db 13,10,'$'
  212.  
  213.  
  214. %newpage
  215. ;------------------------------------------------
  216. ; table format:
  217. ;       db 'initial message....$'
  218. ;       db 80h+code,0,'message....$'
  219. ;       db 80h+code,0,'message....$'
  220. ;       db 0,0,'last message$'
  221. ;
  222. ; table of extended error messages
  223. ;
  224. errorNames     db 'Error: $'
  225. ;               db 80h+01h,0,'Function number invalid!$'
  226. ;               db 80h+02h,0,'File not found!$'
  227. ;               db 80h+03h,0,'Path not found!$'
  228. ;               db 80h+04h,0,'Too many open files (no handles available)!$'
  229.                 db 80h+05h,0,'Access denied!$'
  230. ;               db 80h+06h,0,'Invalid handle!$'
  231. ;               db 80h+07h,0,'Memory control block destroyed!$'
  232. ;               db 80h+08h,0,'Insufficient memory!$'
  233. ;               db 80h+09h,0,'Memory block address invalid!$'
  234. ;               db 80h+0Ah,0,'Environment invalid!$'
  235. ;               db 80h+0Bh,0,'Format invalid!$'
  236. ;               db 80h+0Ch,0,'Access code invalid!$'
  237. ;               db 80h+0Dh,0,'Data invalid!$'
  238. ;               db 80h+0Fh,0,'Invalid drive!$'
  239. ;               db 80h+10h,0,'Attempted to remove current directory!$'
  240. ;               db 80h+11h,0,'Not same device!$'
  241. ;               db 80h+12h,0,'No more matching files!$'
  242.  
  243.                 db 80h+13h,0,'Disk write-protected!$'
  244.                 db 80h+14h,0,'Unknown unit!$'
  245.                 db 80h+15h,0,'Drive not ready!$'
  246. ;               db 80h+16h,0,'Unknown command!$'
  247.                 db 80h+17h,0,'Data error (CRC)!$'
  248. ;               db 80h+18h,0,'Bad request structure length!$'
  249.                 db 80h+19h,0,'Seek error!$'
  250.                 db 80h+1Ah,0,'Unknwon media type (non-DOS disk)!$'
  251.                 db 80h+1Bh,0,'Sector not found!$'
  252.                 db 80h+1Ch,0,'Printer out of paper!$'
  253.                 db 80h+1Dh,0,'Write fault!$'
  254.                 db 80h+1Eh,0,'Read fault!$'
  255.                 db 80h+1Fh,0,'General failure!$'
  256.  
  257.                 db 80h+20h,0,'Sharing violation!$'
  258.                 db 80h+21h,0,'Lock violation!$'
  259.                 db 80h+22h,0,'Invalid disk change!$'
  260. ;               db 80h+23h,0,'No FCB available!$'
  261.                 db 80h+24h,0,'Sharing buffer overflow!$'
  262.  
  263. ;               db 80h+32h,0,'Network request not supported!$'
  264.                 db 80h+33h,0,'Remote computer not listening!$'
  265. ;               db 80h+34h,0,'Duplicate name on network!$'
  266.                 db 80h+35h,0,'Network name not found!$'
  267.                 db 80h+36h,0,'Network busy!$'
  268.                 db 80h+37h,0,'Network device no longer exists!$'
  269. ;               db 80h+38h,0,'Network BIOS command limit exceeded!$'
  270.                 db 80h+39h,0,'Network adapter hardware error!$'
  271.                 db 80h+3Ah,0,'Incorrect response from network!$'
  272.                 db 80h+3Bh,0,'Unexpected network error!$'
  273. ;               db 80h+3Ch,0,'Incompatible remote adapter!$'
  274.                 db 80h+3Dh,0,'Print queue full!$'
  275. ;               db 80h+3Eh,0,'Queue not full!$'
  276. ;               db 80h+3Fh,0,'Not enough space to print file!$'
  277.                 db 80h+40h,0,'Network name was deleted!$'
  278.                 db 80h+41h,0,'Access denied by network!$'
  279. ;               db 80h+42h,0,'Network device type incorrect!$'
  280.                 db 80h+43h,0,'Network name not found!$'
  281. ;               db 80h+44h,0,'Network name limit exceeded!$'
  282. ;               db 80h+45h,0,'Network BIOS session limit exceeded!$'
  283. ;               db 80h+46h,0,'Temporarily paused!$'
  284.                 db 80h+47h,0,'Network request not accepted!$'
  285. ;               db 80h+48h,0,'Print/disk redirection paused!$'
  286.                 db 80h+50h,0,'File already exists!$'
  287. ;               db 80h+52h,0,'Cannot make directory!$'
  288. ;               db 80h+53h,0,'Fail on INT 24h!$'
  289. ;               db 80h+54h,0,'Too many redirections!$'
  290. ;               db 80h+55h,0,'Duplicate redirection!$'
  291. ;               db 80h+56h,0,'Invalid password!$'
  292. ;               db 80h+57h,0,'Invalid parameter!$'
  293.                 db 80h+58h,0,'Network write fault!$'
  294.                 db 0,0,'Undefined!$'
  295.  
  296.  
  297. ;------------------------------------------------
  298. ; table of error areas
  299. ;
  300. driveNames      db 'drive $'
  301.                 db 80h+'A',0,'A:$'
  302.                 db 80h+'B',0,'B:$'
  303.                 db 80h+'C',0,'C:$'
  304.                 db 80h+'D',0,'D:$'
  305.                 db 80h+'E',0,'E:$'
  306.                 db 80h+'F',0,'F:$'
  307.                 db 80h+'G',0,'G:$'
  308.                 db 80h+'G',0,'G:$'
  309.                 db 80h+'I',0,'I:$'
  310.                 db 80h+'J',0,'J:$'
  311.                 db 80h+'K',0,'K:$'
  312.                 db 80h+'L',0,'L:$'
  313.                 db 80h+'M',0,'M:$'
  314.                 db 80h+'N',0,'N:$'
  315.                 db 80h+'O',0,'O:$'
  316.                 db 80h+'P',0,'P:$'
  317.                 db 80h+'Q',0,'Q:$'
  318.                 db 80h+'R',0,'R:$'
  319.                 db 80h+'S',0,'S:$'
  320.                 db 80h+'T',0,'T:$'
  321.                 db 80h+'U',0,'U:$'
  322.                 db 80h+'V',0,'V:$'
  323.                 db 80h+'W',0,'W:$'
  324.                 db 80h+'X',0,'X:$'
  325.                 db 80h+'Y',0,'Y:$'
  326.                 db 80h+'Z',0,'Z:$'
  327.                 db 0,0,'?:$'
  328.  
  329. areaPrefix      db 'Area:  $'
  330. readMsg         db 'Reading from $'
  331. writeMsg        db 'Writing to $'
  332.  
  333. areaNames       db ' $'
  334.                 db 80h+00h,0,'DOS reserved area.$'
  335.                 db 80h+01h,0,'File allocation table.$'
  336.                 db 80h+02h,0,'Directory area.$'
  337.                 db 80h+03h,0,'Data area.$'
  338.                 db 0,0,'Undefined.$'
  339.  
  340. charMsg         db 'device '
  341. deviceName      db 'DEV.$'
  342. deviceDriver   dd      0
  343.  
  344.  
  345. ;------------------------------------------------
  346. ; table of error classes
  347. ;
  348. classNames      db 'Class: $'
  349.                 db 80h+01h,0,'Out of space or I/O channels$'
  350.                 db 80h+02h,0,'Temporary situation (file or record lock)$'
  351.                 db 80h+03h,0,'Authorization (denied access)$'
  352.                 db 80h+04h,0,'Internal error$'
  353.                 db 80h+05h,0,'Hardware failure$'
  354.                 db 80h+06h,0,'System failure$'
  355.                 db 80h+07h,0,'Application program error$'
  356.                 db 80h+08h,0,'Item not found$'
  357.                 db 80h+09h,0,'Bad format$'
  358.                 db 80h+0Ah,0,'Resource locked$'
  359.                 db 80h+0Bh,0,'Media error$'
  360.                 db 80h+0Ch,0,'Item already exists$'
  361.                 db 80h+0Dh,0,'Unknown$'
  362.                 db 80h+0Eh,0,'[E]$'
  363.                 db 80h+0Fh,0,'[F]$'
  364.                 db 0,0,'Undefined$'
  365.  
  366.  
  367. ;------------------------------------------------
  368. ; table of error locus codes
  369. ;
  370. locusNames      db ' in $'
  371.                 db 80h+01h,0,'Unknown.$'
  372.                 db 80h+02h,0,'Block(disk) device.$'
  373.                 db 80h+03h,0,'Network.$'
  374.                 db 80h+04h,0,'Character device.$'
  375.                 db 80h+05h,0,'System memory.$'
  376.                 db 80h+06h,0,'[6]$'     
  377.                 db 80h+07h,0,'[7]$'     ;what do these represent?
  378.                 db 80h+08h,0,'[8]$'     ;I can't find them in any reference.
  379.                 db 0,0,'Undefined.$'
  380.  
  381.  
  382. ;------------------------------------------------
  383. ; table of suggested actions
  384. ;
  385. suggestNames    db 'Suggested action: $'
  386.                 db 80h+01h,0,'Retry the operation.$'
  387.                 db 80h+02h,0,'Delay and then retry.$'
  388.                 db 80h+03h,0,'Re-enter input.$'
  389.                 db 80h+04h,0,'Abort after cleanup.$'
  390.                 db 80h+05h,0,'Immediately abort.$'
  391.                 db 80h+06h,0,'Ignore the error.$'
  392.                 db 80h+07h,0,'Retry after correcting the error.$'
  393.                 db 0,0,'Undefined.$'
  394.  
  395.  
  396. ;------------------------------------------------
  397. ; default actions
  398. ;       01h retry
  399. ;       02h delayed retry
  400. ;       03h prompt user to reenter input
  401. ;       04h abort after cleanup
  402. ;       05h immediate abort
  403. ;       06h ignore
  404. ;       07h retry after user intervention
  405. ;                  ?RRRAAIR
  406. defaultActions db '?RRRRAIR'
  407.  
  408. actionPrefix    db '    Action: (A)bort, (R)etry, (I)gnore, (F)ail? <'
  409. defaultAction   db ?,'> '
  410.                 db 12 dup (' ')
  411.                 db 12 dup (8)
  412.  
  413. SelectedAction  db ?
  414.  
  415. beep            db 7,'$'
  416.  
  417.  
  418. ;------------------------------------------------
  419. ;
  420. box_top         db '  ╔═══════════════════╡ CRITICAL ERROR! ╞════════════════════╗  '
  421. box_side        db 13,10
  422.                 db '                                                             ║  ',13
  423.                 db '  ║  $'
  424. box_bottom      db 13,10
  425.                 db '  ╚══════════════════════════════════════════════════════════╝  '
  426.                 db 13,10,'$'
  427.  
  428. timeoutCount    dw      182     ;18.2 * 10 = 10 second delay
  429. tickCount       dw      0
  430.  
  431. messageColor    = 70h           ;reverse black on white
  432.  
  433. ;------------------------------------------------
  434.  
  435. saveLines       = 7
  436. saveCols        = 66
  437. saveSize        = (saveCols*saveLines)
  438. screenSave      dw      saveSize dup ('SH')
  439.  
  440. cursorSave      dw      0
  441.  
  442.  
  443. errorCount      dw      0       ;count of errors intercepted
  444. autoCount       dw      0       ;count of automatic retries
  445.  
  446. old_int08       dd      0
  447. old_int1c       dd      0
  448. old_int21       dd      0
  449.  
  450. old_int24       dd      0
  451.  
  452. compare_length  = 100           ;bytes to compare of old and
  453.                                 ;new int24 handler code
  454.  
  455. %newpage
  456. ;=============================================
  457. ; INT 24 - FATAL ERROR HANDLER
  458. ;
  459. int24_handler proc near
  460.         pushall
  461.  
  462.         push cs
  463.         pop ds
  464.         assume ds:code
  465.  
  466. ;       mov allowed_actions,ah
  467.         mov word ptr deviceDriver,si
  468.         mov word ptr deviceDriver+2,bp
  469.  
  470.         inc errorCount
  471.         call save_screen
  472.         call report_error_details
  473.         call determine_action
  474.         call restore_screen
  475.  
  476.         popall
  477.         assume ds:nothing
  478.         mov al,selectedAction
  479.         iret
  480. int24_handler endp
  481.  
  482.  
  483.  
  484. ;---------------------------------------------
  485. ;  AH: bit 7 = 0 disk I/O error
  486. ;            = 1 other error -- if block device, bad FAT
  487. ;                            -- if char device, code in DI
  488. ;      bit 6  unused
  489. ;      bit 5 = 1 if Ignore allowed, 0 if not (DOS 3+)
  490. ;      bit 4 = 1 if Retry allowed, 0 if not (DOS 3+)
  491. ;      bit 3 = 1 if Fail allowed, 0 if not (DOS 3+)
  492. ;      bit 2 \ disk area of error  00 = DOS area  01 = FAT
  493. ;      bit 1 /                     10 = root dir  11 = data area
  494. ;      bit 0 = 1 if write, 0 if read
  495. ;
  496. ;  AL = drive number if AH bit 7 = 1, otherwise undefined
  497. ;
  498. ;  BP:SI -> header of device driver for which error occurred
  499. ;           block device if high bit of BP:[SI+4] set
  500. ;
  501. report_error_area proc near
  502.         assume ds:code
  503.         push ax
  504.  
  505.         lea si,box_side
  506.         call display_string
  507.  
  508.         lea si,areaPrefix
  509.         call display_string
  510.  
  511.         lea si,readMsg                 ;display "read" or "write"
  512.         test ah,1
  513.         jz not_write
  514.         lea si,writeMsg
  515.  
  516. not_write:
  517.         call display_string
  518.  
  519.         test ah,80h
  520.         jz is_disk
  521.  
  522.         push ds
  523.         assume ds:nothing
  524.  
  525.         lds si,deviceDriver
  526.         add si,0ah                      ;start of device name
  527.  
  528.         lea di,deviceName
  529.         push cs
  530.         pop es
  531.  
  532.         movsb                           ;copy 3 bytes
  533.         movsb
  534.         movsb
  535.  
  536.         pop ds
  537.         assume ds:code
  538.  
  539.         lea si,charMsg                 ;display "in serial device"
  540.         call display_string
  541.         jmp short report_end
  542.  
  543. is_disk:
  544.         push ax
  545.         add al,'A'                      
  546.         mov ah,al
  547.         lea si,driveNames
  548.         call table_lookup               
  549.         pop ax
  550.  
  551.         shr ah,1                        ;display area code
  552.         and ah,3
  553.         lea si,areaNames
  554.         call table_lookup               
  555.  
  556. report_end:
  557.         pop ax
  558.         ret
  559. report_error_area endp
  560.  
  561.  
  562. ; ---------------------------------------------
  563. ;
  564. report_error_details proc near
  565.         assume ds:code
  566.         push ax
  567.  
  568.         lea si,box_top
  569.         call display_string
  570.  
  571.         clr bx
  572.         msdos dosErrinfo
  573.  
  574.         lea si,errorNames               ;error [what]
  575.         mov ah,al
  576.         call table_lookup
  577.  
  578.         pop ax
  579.         call report_error_area          ;while read/write disk area
  580.  
  581.         lea si,box_side
  582.         call display_string
  583.  
  584.         mov ah,bh
  585.         lea si,classNames               ;class: out of storage, etc.
  586.         call table_lookup
  587.  
  588.         mov ah,ch
  589.         lea si,locusNames               ;in block device/network/serial
  590.         call table_lookup
  591.  
  592.         lea si,box_side
  593.         call display_string
  594.  
  595.         clr bh                          
  596.         mov al,defaultActions[bx]      ;lookup default action from table
  597.         mov defaultAction,al
  598.  
  599.         mov ah,bl
  600.         lea si,suggestNames
  601.         call table_lookup
  602.         ret
  603. report_error_details endp
  604.  
  605.  
  606.  
  607. ; ---------------------------------------------
  608. ; Handler must return:
  609. ;
  610. ; suggested action codes
  611. ;       01h retry
  612. ;       02h delayed retry
  613. ;       03h prompt user to reenter input
  614. ;       04h abort after cleanup
  615. ;       05h immediate abort
  616. ;       06h ignore
  617. ;       07h retry after user intervention
  618. ;
  619. ; exit: selectedAction
  620. ;       AL = 00 ignore error
  621. ;          = 01 retry operation
  622. ;          = 02 terminate program through INT 22h
  623. ;          = 03 fail system call in progress (DOS 3+)
  624. ;
  625. ; allowed_actions
  626. ;       bit 5 = 1 if Ignore allowed, 0 if not (DOS 3+)
  627. ;       bit 4 = 1 if Retry allowed,  0 if not (DOS 3+)
  628. ;       bit 3 = 1 if Fail allowed,   0 if not (DOS 3+)
  629. ;
  630.  
  631. determine_action proc near
  632.         assume ds:code
  633.         lea si,box_bottom
  634.         call display_string
  635.  
  636.         lea si,actionPrefix
  637.         call display_string
  638.  
  639.         call flush_key
  640.  
  641. get_action:
  642.         call get_key
  643.  
  644.         mov al,0
  645.         cmp ah,'I'
  646.         jz action_ok
  647.  
  648.         inc al
  649.         cmp ah,'R'
  650.         jz action_ok
  651.  
  652.         inc al
  653.         cmp ah,'A'
  654.         jz action_ok
  655.  
  656.         inc al
  657.         cmp ah,'F'
  658.         jz action_ok
  659.  
  660.         lea si,beep
  661.         call display_string
  662.  
  663.         jmp short get_action
  664.  
  665. action_ok:
  666.         mov selectedAction,al
  667.         ret
  668. determine_action endp
  669.  
  670. %newpage
  671. ; =============================================
  672. ; get keyboard input.  provide default after delay
  673. ;
  674. get_key proc near
  675.         assume ds:code
  676.         mov tickCount,0
  677.  
  678. get_wait:
  679.         mov ax,tickCount
  680.         cmp ax,timeoutCount
  681.         jge automatic_default
  682.  
  683.         keybd kbdStatus
  684.         jz get_wait
  685.  
  686.         keybd kbdGetch
  687.  
  688.         cmp al,13       ;convert <enter> to default action
  689.         jz  use_default
  690.  
  691.         and al,5fh      ;map to upper case
  692.         mov ah,al
  693.         ret
  694.  
  695. automatic_default:
  696.         inc autoCount
  697.  
  698. use_default:
  699.         mov ah,defaultAction
  700.         ret
  701. get_key endp
  702.  
  703.  
  704. ; =============================================
  705. ; flush keyboard buffer - discard type ahead
  706. ;
  707. flush_key proc near
  708.         assume ds:code
  709. flush_next:
  710.         keybd kbdStatus
  711.         jz flush_exit
  712.  
  713.         keybd kbdGetch
  714.         jmp short flush_next
  715.  
  716. flush_exit:
  717.         ret
  718. flush_key endp
  719.  
  720.  
  721. ;------------------------------------------------
  722. ; display buffer using messageColor
  723. ; entry: ds:si -> message
  724. ;
  725. display_string proc near
  726.         assume ds:code
  727.         push ax
  728.         push bx
  729.         push cx
  730.  
  731. disp_next:
  732.         lodsb
  733.         cmp al,'$'
  734.         jz disp_exit
  735.  
  736.         cmp al,7        ;bell
  737.         jz nocolor
  738.         cmp al,8        ;backspace
  739.         jz nocolor
  740.         cmp al,10       ;linefeed
  741.         jz nocolor
  742.         cmp al,13       ;return
  743.         jz nocolor
  744.  
  745.         clr bh
  746.         mov bl,messageColor
  747.         mov cx,1
  748.         video vidPutch
  749.  
  750. nocolor:
  751.         mov bl,messageColor
  752.         video vidTty
  753.         jmp short disp_next
  754.  
  755. disp_exit:
  756.         pop cx
  757.         pop bx
  758.         pop ax
  759.         ret
  760. display_string endp
  761.  
  762.  
  763. ;-------------------------------------------------------------
  764. ; table_lookup
  765. ;
  766. ; entry:        ds:si = table head
  767. ;               ah    = entry code
  768. ;
  769. table_lookup proc near
  770.         assume ds:code
  771.         push si
  772.         call display_string     ;display initial message from table
  773.         pop si
  774.  
  775.         add ah,80h              ;adjust for 80h+ in table codes
  776.  
  777. next:
  778.         lodsb                   ;skip to the end of the message
  779.         cmp al,'$'
  780.         jnz next
  781.  
  782.         lodsb                   ;get entry code
  783.         cmp al,0
  784.         jz Found
  785.  
  786.         cmp al,ah
  787.         jnz next
  788.  
  789. found:
  790.         inc byte ptr [si]       ;count this message
  791.         inc si                  ;and skip the counter
  792.         call display_string     ;display what was found
  793.         ret
  794. table_lookup endp
  795.  
  796.  
  797.  
  798. ; ---------------------------------------------
  799. ; save user screen
  800. ;
  801. save_screen proc near
  802.         assume ds:code
  803.         pushall
  804.  
  805.         clr bx
  806.         video vidGetcu
  807.         mov cursorSave,dx
  808.  
  809.         push cs
  810.         pop es
  811.         lea di,screenSave
  812.         clr dx
  813.  
  814. next_line:
  815.         call save_line
  816.         inc dh
  817.         cmp dh,saveLines
  818.         jnz next_line
  819.  
  820.         clr bx
  821.         clr dx
  822.         video vidSetcu
  823.  
  824.         popall
  825.         ret
  826. save_screen endp
  827.  
  828.  
  829. ; ---------------------------------------------
  830. ; save line
  831. ;
  832. ; entry:        es:di   buffer
  833. ;               dx      starting cursor
  834. ; exit:         saves dh,si
  835. ;
  836. save_line proc near
  837.         assume ds:code
  838.         clr dl
  839.  
  840. next_col:
  841.         push dx
  842.         clr bx
  843.         video vidSetcu
  844.  
  845.         video vidGetch
  846.         stosw
  847.  
  848.         pop dx
  849.         inc dl
  850.         cmp dl,saveCols
  851.         jnz next_col
  852.  
  853.         ret
  854. save_line endp
  855.  
  856.  
  857. ; ---------------------------------------------
  858. ; restore user screen
  859. ;
  860. restore_screen proc near
  861.         assume ds:code
  862.  
  863.         lea si,screenSave
  864.         clr dx
  865.  
  866. rnext_line:
  867.         call restore_line
  868.         inc dh
  869.         cmp dh,saveLines
  870.         jnz rnext_line
  871.  
  872.         mov dx,cursorSave
  873.         clr bx
  874.         video vidSetcu
  875.         ret
  876. restore_screen endp
  877.  
  878.  
  879. ; ---------------------------------------------
  880. ; restore line
  881. ;
  882. ; entry:        ds:si   buffer
  883. ;               dx      starting cursor
  884. ; exit:         saves dh,si
  885. ;
  886. restore_line proc near
  887.         assume ds:code
  888.         clr dl
  889.  
  890. rnext_col:
  891.         push dx
  892.         clr bx
  893.         video vidSetcu
  894.  
  895.         lodsw
  896.         mov bl,ah
  897.         mov cx,1
  898.         video vidPutch
  899.  
  900.         pop dx
  901.         inc dl
  902.         cmp dl,saveCols
  903.         jnz rnext_col
  904.  
  905.         ret
  906. restore_line endp
  907.  
  908.  
  909. %newpage
  910. ; ---------------------------------------------
  911. ; INT 08H - HARDWARE CLOCK TICK HANDLER
  912. ;
  913. ; Count passing clock ticks while attempting to re-install fatal
  914. ; error handler.  
  915. ;
  916. int08_handler proc far
  917.         assume ds:nothing
  918.         inc tickCount          ;count clock ticks-- used to detect timeout
  919.         call install_handler
  920.         jmp old_int08
  921. int08_handler endp
  922.  
  923.  
  924. ; ---------------------------------------------
  925. ; INT 1cH - USER CLOCK TICK HANDLER
  926. ;
  927. ; Count passing clock ticks while attempting to re-install fatal
  928. ; error handler.  
  929. ;
  930. ;int1c_handler proc far
  931. ;        assume ds:nothing
  932. ;        inc tickCount          ;count clock ticks-- used to detect timeout
  933. ;       call install_handler
  934. ;        jmp old_int1c
  935. ;int1c_handler endp
  936.  
  937.  
  938. ; ---------------------------------------------
  939. ; INT 21H - DOS FUNCTION HANDLER
  940. ;
  941. ; Attempt to re-install fatal error handler.
  942. ;
  943. int21_handler proc far
  944.         assume ds:nothing
  945.         call install_handler
  946.         jmp old_int21
  947. int21_handler endp
  948.  
  949.  
  950. ; ---------------------------------------------
  951. ; Attempt to re-install fatal error handler.  This is required
  952. ; because command.com tends to over-ride any resident error handlers.
  953. ;
  954. install_handler proc near
  955.         assume ds:nothing
  956.         pushall
  957.  
  958.         clr ax                  ;find current fatal handler
  959.         mov es,ax
  960.         les di,es:[24h*4]
  961.  
  962. ; replace current handler if it is below us (probably command.com)
  963.  
  964.         mov ax,es
  965.         mov dx,cs
  966.         cmp ax,dx
  967.         jbe replace
  968.  
  969. ; if current handler is AFTER us, look at the handler code to see if it
  970. ; is another copy of command.com.  this allows us to handle nested
  971. ; command.com's while still preserving application handlers.
  972.  
  973.         lds si,cs:old_int24
  974.         mov cx,compare_length
  975.         rep cmpsw
  976.         jcxz replace
  977.  
  978.         jmp short keep
  979.  
  980. ; if dos or command.com stole the handler, we now take it back.
  981. ; this also performs the initial installation upon startup
  982.  
  983. replace:
  984.         clr ax
  985.         mov es,ax
  986.         mov word ptr es:[24h*4],offset int24_handler
  987.         mov word ptr es:[24h*4+2],cs
  988.  
  989. keep:
  990.         popall
  991.         ret
  992. install_handler endp
  993.  
  994.  
  995. %newpage
  996. ; =============================================
  997. ; end of resident portion of code
  998. ;
  999. resident:
  1000.  
  1001. ; calculate size of resident portion in bytes and segments
  1002.  
  1003. fatal_size = (offset(resident)-offset(entry))
  1004. fatal_segs = (fatal_size / 16) + 32
  1005.  
  1006.  
  1007. ; initialization messages
  1008.  
  1009. license         db 'This program can be freely distributed so long as it is not modified',13,10
  1010.                 db 'or sold for profit.  If you find that this program is valuable, you',13,10
  1011.                 db 'can send me a donation for what you think it is worth.  I suggest',13,10
  1012.                 db 'about 10 dollars.',13,10
  1013.                 db 13,10
  1014.                 db 'Send your registrations to:        The Tool Shop BBS',13,10
  1015.                 db '   Samuel H. Smith                 (602) 264-3969 (2400) - Free node',13,10
  1016.                 db '   5119 N. 11th Ave., #332         (602) 279-2673 (HST 9600)',13,10
  1017.                 db '   Phoenix AZ 85013                (602) 279-0230 (HAYES 9600)',13,10
  1018.                 db 13,10
  1019.                 db 'IN NO EVENT WILL I BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY',13,10
  1020.                 db 'LOST PROFITS,  LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL',13,10
  1021.                 db 'DAMAGES ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR',13,10
  1022.                 db 'FOR ANY CLAIM BY ANY OTHER PARTY.',13,10
  1023.                 db 13,10
  1024.  
  1025. usages          db 'Usage:  FATAL/I     ;install in memory.',13,10
  1026.                 db '        FATAL/U     ;un-install.',13,10
  1027.                 db '        FATAL/C     ;display critical error count.',13,10
  1028.                 db '        FATAL/Z     ;zero critical error count.',13,10
  1029.                 db '$'
  1030.  
  1031. needDos30       db 'DOS 3.0 or later required!',13,10,'$'
  1032.  
  1033. fatalLoaded     db 'FATAL v1.4 installed.',13,10,'$'
  1034. fatalRemoved    db 'FATAL unInstalled.',13,10,'$'
  1035. tableZeroed     db 'Error tables zeroed.',13,10,'$'
  1036. othersLoaded    db 'Other programs loaded after FATAL -- cannot unInstall.',13,10,'$'
  1037. alreadyLoaded   db 'Already loaded!',13,10,'$'
  1038. notLoaded       db 'Fatal is not resident.  Use FATAL/I first.',13,10,'$'
  1039.  
  1040. reportPrefix    db 13,10,'FATAL v1.4 status:',13,10,'$'
  1041. errorCounts     db 'Critical errors.',13,10,'$'
  1042. autoCounts      db 'Automatic retries.','$'
  1043. drivePrefix     db 'Drive: $'
  1044. locusPrefix     db 'Locus:$'
  1045.  
  1046.  
  1047. ; ---------------------------------------------
  1048. ; program entry point
  1049. ;
  1050. entryPoint proc near
  1051.         push cs
  1052.         pop ds
  1053.         assume ds:code
  1054.  
  1055.         lea si,tail
  1056. checkTail:
  1057.         lodsb
  1058.         cmp al,13
  1059.         jz usage
  1060.  
  1061.         cmp al,'/'
  1062.         jz checkOption
  1063.         cmp al,'-'
  1064.         jz checkOption
  1065.         jmp short checkTail
  1066.  
  1067. checkOption:
  1068.         lodsb
  1069.         and al,0ffh-20h         ;map to upper case
  1070.  
  1071.         cmp al,'Z'
  1072.         jnz checkC
  1073.  
  1074.         call zeroStats
  1075.         jmp short exitProgram
  1076.  
  1077. checkC:
  1078.         cmp al,'C'
  1079.         jnz checkU
  1080.  
  1081.         call reportStats
  1082.         jmp short exitProgram
  1083.  
  1084. checkU:
  1085.         cmp al,'U'
  1086.         jnz checkI
  1087.  
  1088.         call unInstall
  1089.         jmp short exitProgram
  1090.  
  1091. checkI:
  1092.         cmp al,'I'
  1093.         jnz usage
  1094.         jmp short newInstall
  1095.  
  1096.  
  1097. ; ---------------------------------------------
  1098. ; fatal/? - display license and usage messages
  1099. ;
  1100. usage:
  1101.         lea dx,signature
  1102.         call disps
  1103.  
  1104.         mov al,tailLen
  1105.         cmp al,0
  1106.         lea dx,usages
  1107.         jnz exitWithMessage
  1108.  
  1109.         lea dx,license
  1110. ;       jmp short exitWithMessage
  1111.  
  1112.  
  1113. ; ---------------------------------------------
  1114. exitWithMessage:
  1115.         call disps
  1116.  
  1117. exitProgram:
  1118.         msdos dosExit,0
  1119.  
  1120.  
  1121. ; ---------------------------------------------
  1122. ; fatal/I - new installation - hook vectors and go resident
  1123. ;
  1124. newInstall:
  1125.         lea dx,signature
  1126.         call disps
  1127.  
  1128.         msdos dosGetvers                ;verify dos 3 or later
  1129.         lea dx,needDos30
  1130.         cmp al,2
  1131.         jle installExit
  1132.  
  1133.         call checkPresent
  1134.         lea dx,alreadyLoaded
  1135.         jz installExit
  1136.  
  1137.         getvect 08h,old_int08           ;save original handler vectors
  1138.         getvect 21h,old_int21
  1139. ;       getvect 1ch,old_int1c
  1140.         getvect 24h,old_int24
  1141.  
  1142.         setvect 08h,int08_handler       ;install new handlers
  1143. ;       setvect 1ch,int1c_handler
  1144.         setvect 21h,int21_handler
  1145.  
  1146.         lea dx,fatalLoaded
  1147.         call disps
  1148.  
  1149.         lea dx,resident                 ;terminate and stay resident
  1150.         int 27h
  1151.  
  1152. installExit:
  1153.         jmp short exitWithMessage
  1154. entryPoint endp
  1155.  
  1156.  
  1157. ; =============================================
  1158. ; check if fatal is already present
  1159. ;
  1160. ; exit: Z       fatal is present,
  1161. ;               es-> resident code segment
  1162. ;
  1163. ;       NZ      not present
  1164. ;
  1165. checkPresent proc near
  1166.         msdos dosGetvec,24h     ;es:xx -> current int24 handler
  1167.  
  1168.         lea bx,signature        ;cs:bx -> local signature
  1169. checkNext:
  1170.         mov al,ds:[bx]          ;get next byte from local message
  1171.         cmp al,'$'              ;end of message?
  1172.         jz checkExit            ;already present if so
  1173.  
  1174.         cmp al,es:[bx]          ;compare next byte to int24 handler
  1175.         jnz checkExit           ;new installation if mismatch
  1176.  
  1177.         inc bx                  ;got a match, try the next char
  1178.         jmp short checkNext
  1179.  
  1180. checkExit:
  1181.         ret
  1182. checkPresent endp
  1183.  
  1184.  
  1185. ; ---------------------------------------------
  1186. ; display message in code segment
  1187. ;
  1188. disps proc near
  1189.         push ds
  1190.         push cs
  1191.         pop ds
  1192.         msdos dosDisplay
  1193.         pop ds
  1194.         ret
  1195. disps endp
  1196.  
  1197.  
  1198. ; ---------------------------------------------
  1199. ; fatal/u - uninstall and exit
  1200. ;
  1201. unInstall proc near
  1202.         call checkPresent
  1203.         lea dx,notLoaded
  1204.         jnz unExit
  1205.  
  1206.         mov bx,es               ;bx->tsr code segment
  1207.         mov ax,ds
  1208.         sub ax,bx               ;calculate memory usage after fatal tsr
  1209.  
  1210.         lea dx,othersLoaded
  1211.         cmp ax,fatal_segs       ;amount of allowed overhead for DOS/PSP, etc.
  1212.         jge unExit              ;insure that others are not loaded after
  1213.  
  1214.         assume ds:nothing
  1215.         revect 21h,old_int21    ;unhook dos interrupt
  1216. ;       revect 1ch,old_int1c    ;unhook timer interrupt
  1217.         revect 08h,old_int08    ;unhook timer interrupt
  1218.         revect 24h,old_int24    ;unhook critical error interrupt
  1219.  
  1220.         push es
  1221.         mov es,es:envseg
  1222.         msdos dosFreemem       ;dealloc the tsr's environment segment
  1223.  
  1224.         pop es              
  1225.         msdos dosFreemem       ;dealloc the tsr's code segment
  1226.  
  1227.         push cs
  1228.         pop ds
  1229.         assume ds:code
  1230.  
  1231.         lea dx,fatalRemoved
  1232. unExit:
  1233.         call disps
  1234.         ret
  1235. unInstall endp
  1236.  
  1237.  
  1238. ; ---------------------------------------------
  1239. ; fatal/C - report critical error counts
  1240. ;
  1241. reportStats proc near
  1242.         call checkPresent
  1243.         lea dx,notLoaded
  1244.         jnz reportExit
  1245.  
  1246.         push es
  1247.         pop ds
  1248.         lea dx,reportPrefix
  1249.         mov ax,errorCount
  1250.         call decimal
  1251.  
  1252.         lea dx,errorCounts
  1253.         mov ax,autoCount
  1254.         call decimal
  1255.  
  1256.         lea dx,autoCounts
  1257.         call disps
  1258.  
  1259.         mov ax,errorCount
  1260.         cmp ax,0
  1261.         jz reportFinish         ;finish now if no errors to report
  1262.  
  1263.         lea si,errorNames
  1264.         mov dx,si
  1265.         call dumpTable
  1266.  
  1267.         lea si,classNames
  1268.         mov dx,si
  1269.         call dumpTable
  1270.  
  1271.         lea si,locusNames
  1272.         lea dx,locusPrefix
  1273.         call dumpTable
  1274.  
  1275.         lea si,driveNames
  1276.         lea dx,drivePrefix
  1277.         call dumpTable
  1278.  
  1279.         lea si,areaNames
  1280.         lea dx,areaPrefix
  1281.         call dumpTable
  1282.  
  1283.         lea si,suggestNames
  1284.         mov dx,si
  1285.         call dumpTable
  1286.  
  1287. reportFinish:
  1288.         lea dx,crlfs
  1289. reportExit:
  1290.         call disps
  1291.         ret
  1292. reportStats endp
  1293.  
  1294.  
  1295. ;-------------------------------------------------------------
  1296. ; dumpTable - display usage counts for a code table
  1297. ; entry:  ds:si = table head
  1298. ;            dx = table name
  1299. ;
  1300. dumpTable proc near
  1301.         push dx
  1302.         lea dx,crlfs
  1303.         call disps
  1304.         pop dx
  1305.         call disps
  1306.  
  1307. dumpNext:
  1308.         lodsb                   ;skip to the end of the message
  1309.         cmp al,'$'
  1310.         jnz dumpNext
  1311.  
  1312.         lodsw                   ;get entry code+activity count
  1313.         cmp ah,0                ;skip entries with count=0
  1314.         jnz dumpEntry
  1315.         jmp short dumpAgain
  1316.  
  1317. dumpEntry:
  1318.         push ax
  1319.         mov al,ah
  1320.         clr ah
  1321.         lea dx,crlfs
  1322.         call decimal
  1323.  
  1324.         mov dx,si
  1325.         call disps
  1326.         pop ax
  1327.  
  1328. dumpAgain:
  1329.         cmp al,0
  1330.         jnz dumpNext
  1331.  
  1332.         ret
  1333. dumpTable endp
  1334.  
  1335.  
  1336. ; ---------------------------------------------
  1337. ; convert number to decimal
  1338. ;       dx  initial message
  1339. ;       ax  number to convert
  1340. ;
  1341. decBuf db '00000'
  1342. decEnd db ' $'
  1343.  
  1344. decimal proc near
  1345.         assume ds:nothing
  1346.         push si
  1347.  
  1348.         push ax
  1349.         call disps
  1350.         pop ax
  1351.  
  1352.         lea bx,decBuf
  1353.         mov cx,5
  1354.         mov dl,' '
  1355. decClear:
  1356.         mov cs:[bx],dl
  1357.         inc bx
  1358.         loop decClear
  1359.  
  1360.         mov cx,5                ;convert 5 digits
  1361.         mov si,10               ;divisor
  1362.  
  1363. decNext:
  1364.         clr dx                  ;convert AX -> DX:AX
  1365.  
  1366.         div si                  ;divide number by 10. Remainder is in
  1367.                                 ; DX--this is a one-digit decimal
  1368.                                 ; number.  Number/10 is in AX
  1369.  
  1370.         add dl,'0'              ;convert remainder to a text character
  1371.         dec bx                  ;put this digit in the string and
  1372.         mov cs:[bx],dl          ;point to the location for the
  1373.                                 ; next most-significant digit
  1374.         cmp ax,0
  1375.         jz decLast              ;stop when 0 is reached
  1376.  
  1377.         loop decNext
  1378.  
  1379. decLast:
  1380.         lea dx,decBuf
  1381.         call disps
  1382.  
  1383.         pop si
  1384.         ret
  1385. decimal endp
  1386.  
  1387.  
  1388. ; ---------------------------------------------
  1389. ; fatal/Z - zero critical error counts
  1390. ;
  1391. zeroStats proc near
  1392.         call checkPresent
  1393.         lea dx,notLoaded
  1394.         jnz zeroExit
  1395.  
  1396.         push es
  1397.         pop ds
  1398.         assume ds:code  ;ds->resident code segment
  1399.  
  1400.         clr ax
  1401.         mov errorCount,ax
  1402.         mov autoCount,ax
  1403.         mov errorCount,ax
  1404.  
  1405.         lea si,errorNames
  1406.         call zeroTable
  1407.  
  1408.         lea si,classNames
  1409.         call zeroTable
  1410.  
  1411.         lea si,locusNames
  1412.         call zeroTable
  1413.  
  1414.         lea si,driveNames
  1415.         call zeroTable
  1416.  
  1417.         lea si,areaNames
  1418.         call zeroTable
  1419.  
  1420.         lea si,suggestNames
  1421.         call zeroTable
  1422.  
  1423.         lea dx,tableZeroed
  1424. zeroExit:
  1425.         call disps
  1426.         ret
  1427. zeroStats endp
  1428.  
  1429.  
  1430. ;-------------------------------------------------------------
  1431. ; zeroTable - zero usage counts for a code table
  1432. ; entry:  ds:si = table head
  1433. ;
  1434. zeroTable proc near
  1435.  
  1436. zeroNext:
  1437.         lodsb                           ;skip to the end of the message
  1438.         cmp al,'$'
  1439.         jnz zeroNext
  1440.  
  1441.         lodsw                           ;get entry code+activity count
  1442.         mov byte ptr ds:[si-1],0        ;zero error count
  1443.  
  1444.         cmp al,0
  1445.         jnz zeroNext
  1446.  
  1447.         ret
  1448. zeroTable endp
  1449.  
  1450. code ends
  1451.         end entry
  1452.  
  1453.