home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / INTHNDLR / CRITERR.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-03-21  |  7.5 KB  |  262 lines

  1.     .386p
  2. ;************************************************************************/
  3. ;*    Copyright (C) 1986-1990 Phar Lap Software, Inc.            */
  4. ;*    Unpublished - rights reserved under the Copyright Laws of the    */
  5. ;*    United States.  Use, duplication, or disclosure by the         */
  6. ;*    Government is subject to restrictions as set forth in         */
  7. ;*    subparagraph (c)(1)(ii) of the Rights in Technical Data and     */
  8. ;*    Computer Software clause at 252.227-7013.            */
  9. ;*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138    */
  10. ;************************************************************************/
  11.  
  12. ;
  13. ; This program demonstrates 
  14. ;
  15.  
  16. ;
  17. ; Constants and data structures
  18. ;
  19. include    dosx.ah
  20.  
  21. ;
  22. ; Segment definitions and ordering.  
  23. ;
  24. _codeseg    segment    byte public use32 'code'
  25. _codeseg    ends
  26. _data        segment    dword public use32 'data'
  27. _data        ends
  28. _stack        segment dword stack use32 'stack'
  29.     db    2048 dup (?)    ; 2K stack
  30. _stack        ends
  31.  
  32. ;
  33. ; Global data
  34. ;
  35. _data    segment    
  36.  
  37.     public    pm_cesel,pm_ceoff,rm_cevec
  38. rm_cevec    dd    ?    ; original real mode critical err vector
  39. pm_ceoff    dd    ?    ; original protected mode critical err vector
  40. pm_cesel    dw    ?        ; 
  41.     align    4
  42.  
  43. afile    db    'a:\foo',0
  44. status_msg db    'Causing critical err by reading from open A: floppy drive'
  45.     db    0Dh,0Ah,'$'
  46. _data    ends
  47.  
  48. ;****************************************************************************
  49. ; Program entry point
  50. ;****************************************************************************
  51.  
  52.     assume    cs:_codeseg,ds:_data
  53. _codeseg    segment    
  54.  
  55.     public    main
  56. main proc    near
  57.  
  58. ;
  59. ; Save current real and protected mode critical error vectors, and install our
  60. ; critical error handler so it always gets control in protected mode.  We use
  61. ; the 2506h system call to do this, because the critical error interrupt is
  62. ; always issued in real mode by DOS.
  63. ;
  64.     mov    cl, 24h            ; save real mode critical error vector
  65.     mov    ax, 2503h            ; 
  66.     int    21h                ;
  67.     mov    rm_cevec, ebx            ; 
  68.     mov    ax, 2502h        ; save prot mode critical error vector
  69.     mov    cl,24h                ;
  70.     int    21h                ; 
  71.     mov    pm_cesel, es            ;
  72.     mov    pm_ceoff, ebx            ; 
  73.     push    ds            ; install our critical error handler 
  74.     lea    edx, crite_hnd            ; to always get control in
  75.     mov    ax, cs                ; protected mode
  76.     mov    ds, ax                ;
  77.     mov    cl,24h                ;
  78.     mov    ax, 2506h            ; 
  79.     int    21h                ;
  80.     pop    ds                ; 
  81.  
  82. ;
  83. ; Cause a critical error by attempting to open a file on the A: floppy
  84. ; disk drive (which will cause a critical error if the floppy door is
  85. ; open).
  86. ;
  87.     mov    ah, 09h            ; tell user we're causing CTRL/C
  88.     lea    edx, status_msg            ;
  89.     int    21h                ;
  90.     lea    edx,afile        ; open file on A: drive
  91.     mov    ax,3D00h            ;
  92.     int    21h                ;
  93.  
  94. ;
  95. ; Restore the original interrupt vectors and exit
  96. ;
  97.     mov    cl, 24h            ; restore original real mode vector
  98.     mov    ebx, rm_cevec            ; 
  99.     mov    ax, 2505h            ;
  100.     int    21h                ; 
  101.     push    ds            ; restore original prot mode vector
  102.     mov    edx, pm_ceoff            ; 
  103.     mov    ax, pm_cesel            ;
  104.     mov    ds, ax                ; 
  105.     mov    cl,24h                ;
  106.     mov    ax, 2504h            ;
  107.     int    21h                ; 
  108.     pop    ds                ;
  109.  
  110.     mov    ax,4C00h        ; exit to DOS
  111.     int    21h                ;
  112. main endp
  113.  
  114. ;****************************************************************************
  115. ; CRITE_HND - Protected Mode Critical Error Handler
  116. ;    It just prints out a message saying the error occurred, and then
  117. ;    returns, instructing DOS to fail the system call that caused the error.
  118. ;
  119. ;    To demonstrate how to use the interrupt stack frame to get the
  120. ;    original stack when the interrupt occurred, we pick up the 
  121. ;    original AX value for the INT 21h call (saved on the critical error
  122. ;    stack by DOS) and print out AH to show what call it was that failed.
  123. ;****************************************************************************
  124.     public    crite_hnd
  125. crite_hnd    proc    near
  126. ;
  127. ; Interrupt handler stack frame
  128. ;
  129. #FLGS    equ    (dword ptr 52[ebp])    ; 386|DOS-Extender flags
  130. #GS    equ    (word ptr 48[ebp])    ; original GS
  131. #FS    equ    (word ptr 44[ebp])    ; original FS
  132. #DS    equ    (word ptr 40[ebp])    ; original DS
  133. #ES    equ    (word ptr 36[ebp])    ; original ES
  134. #SS    equ    (word ptr 32[ebp])    ; original SS
  135. #ESP    equ    (dword ptr 28[ebp])    ; original ESP
  136. #EFLAGS    equ    (dword ptr 24[ebp])    ; original EFLAGS
  137. #CS    equ    (dword ptr 20[ebp])    ; original CS
  138. #EIP    equ    (dword ptr 16[ebp])    ; original EIP
  139. #EBP    equ    (dword ptr [ebp])    ; original EBP
  140.  
  141. ;
  142. ; This is an interrupt handler, so we must preserve all registers we use.
  143. ; Also re-enable interrupts so hardware interrupts aren't blocked.
  144. ;
  145.     sti                ; re-enable interrupts
  146.     push    ebp            ; set up stack frame
  147.     mov    ebp,esp                ;
  148.     push    ebx            ; save regs, EXCEPT EAX which we
  149.     push    ecx                ; return a value in
  150.     push    edx                ;
  151.     push    ds                ;
  152.     push    es                ;
  153.     mov    ax,SS_DATA        ; set DS to our data segment
  154.     mov    ds,ax                ;
  155.  
  156. ;
  157. ; Get the real mode stack address in ES:EBX.  The critical error 
  158. ; interrupt should ALWAYS be issued from real mode, but check in case 
  159. ; someone coded a software INT 24h in prot mode by mistake.
  160. ;
  161.     test    #FLGS,IFL_RMODE        ; branch if didn't come from real
  162.     jz    #not_real            ; mode
  163.     movzx    ebx,#SS            ; get linear addr of real mode stack
  164.     shl    ebx,4                ; in conventional memory
  165.     add    ebx,#ESP            ;
  166.     mov    ax,SS_DOSMEM        ; set ES to DOS memory segment
  167.     mov    es,ax                ;
  168.  
  169. ;
  170. ; Print out a message, and the AH value for the INT 21h call that failed,
  171. ; so the user can see what the call was.
  172. ;
  173. ; DOS critical error stack frame
  174. ;
  175. #DOS_FLAGS equ    (word ptr es:22[ebx])    ; interrupt stack frame from real
  176. #DOS_CS    equ    (word ptr es:20[ebx])        ; mode INT 21h
  177. #DOS_IP    equ    (word ptr es:18[ebx])        ;
  178. #DOS_ES    equ    (word ptr es:16[ebx])    ; regs at time INT 21h was issued
  179. #DOS_DS    equ    (word ptr es:14[ebx])        ; in real mode
  180. #DOS_BP    equ    (word ptr es:12[ebx])        ;
  181. #DOS_DI    equ    (word ptr es:10[ebx])        ;
  182. #DOS_SI    equ    (word ptr es:8[ebx])        ;
  183. #DOS_DX    equ    (word ptr es:6[ebx])        ;
  184. #DOS_CX    equ    (word ptr es:4[ebx])        ;
  185. #DOS_BX    equ    (word ptr es:2[ebx])        ;
  186. #DOS_AX    equ    (word ptr es:[ebx])        ;
  187.  
  188. _data    segment
  189. ce_msg    db    'Critical error occurred on INT 21h function $'
  190. _data    ends
  191.     mov    ah,9            ; print critical err msg
  192.     lea    edx,ce_msg            ;
  193.     int    21h                ;
  194.     mov    ax,#DOS_AX        ; get original AX value
  195.     mov    al,ah            ; convert AH to ASCII, save in BX
  196.     call    btohex                ;
  197.     mov    bx,ax                ;
  198.     mov    ah,2            ; output function code & newline
  199.     mov    dl,bl                ;
  200.     int    21h                ;
  201.     mov    dl,bh                ;
  202.     int    21h                ;
  203.     mov    dl,0Dh                ;
  204.     int    21h                ;
  205.     mov    dl,0Ah                ;
  206.     int    21h                ;
  207.  
  208. #exit:
  209.     mov    eax,3            ; instruct DOS to fail the function
  210.                         ; (DOS 3.1 and later only)
  211.     pop    es            ; restore regs
  212.     pop    ds                ;
  213.     pop    edx                ;
  214.     pop    ecx                ;
  215.     pop    ebx                ;
  216.     pop    ebp                ;
  217.     iretd                ; return from interrupt
  218.  
  219. #not_real:
  220. ;
  221. ; Interrupt didn't originate from real mode
  222. ;
  223. _data    segment
  224. nreal_msg db    'Critical error interrupt issued in prot mode!!',0Dh,0Ah,'$'
  225. _data    ends
  226.     mov    ah,9            ; print error msg & exit
  227.     lea    edx,nreal_msg            ;
  228.     int    21h                ;
  229.     jmp    #exit                ;
  230. crite_hnd    endp
  231.  
  232. ;****************************************************************************
  233. ; BTOHEX -- convert byte in AL to ASCII hex in AX, all other regs unchanged
  234. ;****************************************************************************
  235. btohex    proc    near    ; convert byte to hex
  236.     push    bx            ; save regs
  237.     mov    ah,0            ; make sure AH is 0
  238.     mov    bx,ax            ; save value to convert
  239.     call    ntohex            ; get LS hex digit into BL
  240.     xchg    ax,bx                ;
  241.     shr    ax,4            ; get MS hex digit into AL
  242.     call    ntohex                ;
  243.     shl    bx,8            ; combine the two digits in AX
  244.     or    ax,bx                ;
  245.     pop    bx            ; restore regs & exit
  246.     ret
  247. btohex    endp
  248.  
  249. ntohex    proc    near    ; convert nibble to ascii hex
  250.     and    ax,0Fh            ; mask out all but low nibble
  251.     cmp    ax,10            ; branch if digit from 0 - 9
  252.     jb    short #digit            ;
  253.     add    ax,'A' - 10        ; digit from A-F
  254.     ret                    ;
  255. #digit:
  256.     add    ax,'0'            ; digit from 0-9
  257.     ret
  258. ntohex    endp
  259. _codeseg    ends
  260.  
  261.     end    main
  262.