home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / editors / tde150.arj / INT24.ASM < prev    next >
Assembly Source File  |  1992-04-01  |  11KB  |  255 lines

  1. ; Do a simple critical error handler (CEH).  It is designed to be memory model
  2. ; independent.  When we first install this CEH, pass in the FAR address of
  3. ; a CEH structure.  Save the address of CEH structure in the code segment of
  4. ; our assembly CEH replacement.  When a critical error occurs, load in the
  5. ; address of our CEH structure and save the return codes in the structure.
  6. ; Call the prompt functions in criterr.c, then return from interrupt.
  7. ;
  8. ; Let's set the error flag only if a Fail or Ignore condition is input by
  9. ; the user.  The Ignore option is not explicity supported by this algorithm,
  10. ; but it is returned for DOS versions less than 3.0.  The Fail option is
  11. ; not available for DOS versions less than 3.0.  If the user selects the
  12. ; Retry option, set the ceh.flag to OK, because there is no error.  By
  13. ; selecting Retry, the user just wants to retry the DOS operation, which is
  14. ; not necessarily an error condition.
  15. ;
  16. ; See DOS technical reference manuals for more info on critical error handlers.
  17. ; Also see "Advanced MSDOS" by Ray Duncan for a discussion and a skeleton
  18. ; example of a critical error handler.  For further reference, see
  19. ; the "MS-DOS Encyclopedia."
  20. ;
  21. ; Assembler flags:
  22. ;
  23. ;      QuickAssembler:   qcl /c int24.asm
  24. ;            MASM 6.0:   ml /c /Cp /Zm int24.asm
  25. ;
  26. ; Editor name:   tde, the Thomson-Davis Editor.
  27. ; Author:        Frank Davis
  28. ; Date:          April 1, 1992
  29. ;
  30. ; This code is released into the public domain, Frank Davis.  You may
  31. ; distribute it freely.
  32.  
  33. ;typedef struct {         typedef from tdestr.h
  34. ;   int  flag;
  35. ;   int  ecode;
  36. ;   int  rw;
  37. ;   int  drive;
  38. ;   int  extended;
  39. ;   int  class;
  40. ;   int  action;
  41. ;   int  locus;
  42. ;   int  dattr;
  43. ;   char dname[10];
  44. ;} CEH;
  45.  
  46. flag            EQU     0
  47. ecode           EQU     2
  48. rw              EQU     4
  49. drive           EQU     6
  50. extended        EQU     8
  51. class           EQU     10
  52. action          EQU     12
  53. locus           EQU     14
  54. dattr           EQU     16
  55. dname           EQU     18
  56.  
  57. ; see any DOS tech ref manaul for the format of device headers.
  58. ;
  59. dev_attr_word   EQU     4
  60. char_dev_name   EQU     10
  61.  
  62. ;
  63. ; external C routine in criterr.c
  64. ;
  65.         EXTRN   _crit_err_handler:FAR
  66.  
  67.  
  68. _TEXT   SEGMENT WORD PUBLIC 'CODE'
  69.         ASSUME  cs:_TEXT, ds:NOTHING, es:NOTHING
  70.         public  _install_ceh
  71.  
  72.  
  73. ;
  74. ; Prototype this function as far in the C header file so it may be used easily
  75. ; with any memory model.  See the last section in tdefunc.h for more info.
  76. ;
  77. _install_ceh    PROC    FAR
  78.         jmp     initialize
  79.  
  80. ceh_pointer     DW      ?,?     ; pointer to critical error handler structure
  81. dos_version     DW      ?       ; what version of DOS are we working with?
  82.  
  83. start:
  84. ;
  85. ;  the first thing we need to do is turn interrupts back on.  interrupts
  86. ;  are disabled when the handler receives control.
  87. ;
  88. ;  segment register strategy:
  89. ;      use ds to access variables in the code segment and the device header
  90. ;      use es to access the ceh structure.
  91. ;
  92.         sti                     ; turn interrupts back on
  93.         push    bx              ; push required registers
  94.         push    cx
  95.         push    dx
  96.         push    ds
  97.         push    es
  98.  
  99.         ASSUME  ds:_TEXT, es:NOTHING    ; put cs in ds and tell assembler
  100.                                         ; ds references code, _TEXT seg
  101.         mov     dx, cs
  102.         mov     ds, dx
  103.  
  104.         mov     dx, di                          ; put error code in dx
  105.         xor     dh, dh                          ; high part of di is undef'ed
  106.         mov     bx, WORD PTR ceh_pointer+2      ; get SEGMENT of ceh struc
  107.         mov     es, bx                          ; put it in es
  108.         mov     di, WORD PTR ceh_pointer        ; get OFFSET of ceh struc
  109.         mov     WORD PTR es:[di].ecode, dx      ; save error code
  110.         mov     dl, ah                          ; move error stuff to dl
  111.         and     dl, 1                           ; 1 == write error
  112.         mov     WORD PTR es:[di].rw, dx         ; save read/write error code
  113.  
  114.         mov     dl, al                          ; put drive letter in dl
  115.         mov     WORD PTR es:[di].drive, dx      ; save drive number
  116.         test    ah, 80h                 ; was this a character or block dev
  117.         jz      drive_err               ; if fail, then block error
  118.         mov     ds, bp                  ; put SEGMENT of device header in ds
  119.         mov     dx, WORD PTR [si].dev_attr_word ; see DOS tech ref, get dev attr
  120.         test    dx, 8000h               ; was there a prob w/ FAT
  121.         jz      drive_err               ; if bit 15 == 0, drive error - FAT prob
  122.         mov     WORD PTR es:[di].dattr, 1       ; 1 == character device
  123.         mov     bx, di                  ; save OFFSET of CEH struct in bx
  124.         add     di, dname               ; load destination of char dev name
  125.         add     si, char_dev_name       ; char dev
  126.         mov     cx, 8                   ; char name is 8 bytes
  127.         rep     movsb                   ; move 8 bytes of driver name
  128.         xor     al, al                  ; zero out al
  129.         stosb                           ; store a terminating NULL
  130.         mov     di, bx                  ; get back the OFFSET of CEH struct
  131.         jmp     SHORT get_extended_error
  132.         ALIGN   2
  133. drive_err:
  134.         mov     WORD PTR es:[di].dattr, 0       ; 0 == disk drive
  135. get_extended_error:
  136.         mov     dx, cs                  ; put cs back into ds
  137.         mov     ds, dx
  138.         mov     ax, WORD PTR ds:dos_version     ; get DOS version
  139.         or      ax, ax                  ; is it 0?
  140.         jz      no_ext_avail            ; skip extended error
  141.  
  142. ;
  143. ; page 1-216, Programmer's Ref Man, 1986, function 59h pretty much wipes
  144. ; out all registers that don't return info.  function 59h is available
  145. ; for DOS >= 3.
  146. ;
  147.         push    di
  148.         push    ds
  149.         push    es
  150.         xor     bx, bx                  ; version indicator, 0 = current
  151.         mov     ah, 59h                 ; function 59h == get extended err
  152.         int     21h                     ; Standard DOS interrupt
  153.         pop     es
  154.         pop     ds
  155.         pop     di
  156.         cmp     ax, 88                          ; check for return code > 88
  157.         ja      no_ext_avail                    ; if ax <= 88, we have info
  158.         mov     WORD PTR es:[di].extended, ax   ; save ext err code
  159.         xor     ax, ax                          ; zero out ax
  160.         mov     al, bh                          ; get error class
  161.         mov     WORD PTR es:[di].class, ax      ; save error class
  162.         mov     al, bl                          ; get suggested action
  163.         mov     WORD PTR es:[di].action, ax     ; save suggested action
  164.         mov     al, ch                          ; get locus
  165.         mov     WORD PTR es:[di].locus, ax      ; save locus
  166.         jmp     SHORT prompt_user               ; now, ask user what to do
  167.         ALIGN   2
  168.  
  169. no_ext_avail:
  170.         xor     ax, ax                          ; zero out ax
  171.         mov     WORD PTR es:[di].extended, ax   ; not avail
  172.         mov     WORD PTR es:[di].class, ax      ; not avail
  173.         mov     WORD PTR es:[di].action, ax     ; not avail
  174.         mov     WORD PTR es:[di].locus, ax      ; not avail
  175.  
  176. prompt_user:
  177.         push    di                      ; save OFFSET of CEH struct
  178.         push    es                      ; save SEGMENT OF CEH struct
  179.         push    ds                      ; save code segment in ds
  180.         mov     ax, ss                  ; put stack segment in ds
  181.         mov     ds, ax                  ; C routine expects stack seg in ds
  182.         call    FAR PTR _crit_err_handler       ; return code is in ax
  183.         pop     ds                      ; get back our registers
  184.         pop     es
  185.         pop     di
  186.  
  187.         mov     bx, WORD PTR ds:dos_version     ; get the DOS version
  188.         or      bx, bx                          ; is bx == 0?
  189.         jne     retry_or_fail                   ; DOS version is >= 3
  190.         cmp     ax, 3                           ; did user try fail?
  191.         jne     retry_or_fail                   ; cannot fail with DOS < 3
  192.         mov     ax, 0                           ; change it to Ignore
  193.         ALIGN   2
  194.  
  195. retry_or_fail:
  196.         mov     dx, -1                          ; if we fail, store a -1
  197.         cmp     ax, 1                           ; did user do a retry?
  198.         jne     end_int_24                      ; if retry, change error code
  199.         xor     dx, dx                          ;   reset error flag on retry
  200.  
  201. end_int_24:
  202.         mov     WORD PTR es:[di].flag, dx       ; save ceh flag
  203.         pop     es
  204.         pop     ds
  205.         pop     dx
  206.         pop     cx
  207.         pop     bx              ; pop registers
  208.         iret                    ; return from interrupt
  209.  
  210. ; ***********************************************************************
  211. ; prototype for _install_ceh in the C header file, tdefunc.h, is
  212. ;
  213. ;               void far install_ceh( void far * )
  214. ;
  215. ; The formal parameters are available on the stack.  Use bp register to
  216. ; access them.
  217. ;
  218. ; ***********************************************************************
  219.  
  220. initialize:
  221.         push    bp              ; setup bp to access formal parameter
  222.         mov     bp, sp
  223.  
  224.         push    ds              ; save ds
  225.  
  226.         ASSUME  ds:_TEXT        ; tell assembler ds references code, _TEXT seg
  227.         mov     ax, cs
  228.         mov     ds, ax          ; put cs in ds - required by function 25h, below
  229.  
  230.         mov     ah, 30h         ; function 30h == get DOS version
  231.         int     21h             ; DOS interrupt
  232.         xor     bx, bx          ; start out with zero for DOS version
  233.         cmp     al, 3           ; compare major version
  234.         jl      store_dos       ; if less than version 3, store 0
  235.         mov     bx, 3           ; else store 3 for DOS >= 3
  236. store_dos:
  237.         mov     WORD PTR dos_version, bx        ; save DOS info for my int 24
  238.  
  239.         mov     ax, WORD PTR [bp+6]             ; load OFFSET of void FAR *
  240.         mov     WORD PTR ceh_pointer, ax        ; save OFFSET of void FAR *
  241.         mov     ax, WORD PTR [bp+8]             ; load SEGMENT of void FAR *
  242.         mov     WORD PTR ceh_pointer+2, ax      ; save SEGMENT of void FAR *
  243.  
  244.         mov     dx, OFFSET start        ; get new offset of int 24
  245.                                         ; we have already set ds above
  246.         mov     ax, 2524h               ; use function 25 so int 24 points
  247.         int     21h                     ;  to my critical error routine
  248.  
  249.         pop     ds              ; clean up
  250.         pop     bp
  251.         retf
  252. _install_ceh            endp
  253. _TEXT   ends
  254.         end
  255.