home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / INTHNDLR / ICHAIN.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-11-29  |  5.5 KB  |  206 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 installing an INT 21h handler that just chains
  14. ; to the previous 386|DOS-Extender handler for most functions, but 
  15. ; processes function 09h (print string) by writing directly to the
  16. ; display with segment 001Ch (the video screen segment).
  17. ;
  18.  
  19. ;
  20. ; Constants and data structures
  21. ;
  22. include    dosx.ah
  23.  
  24. ;
  25. ; Segment definitions and ordering
  26. ;
  27. _codeseg    segment    byte public use32 'code'
  28. _codeseg    ends
  29. _data        segment    dword public use32 'data'
  30. _data        ends
  31. _stack        segment dword stack use32 'stack'
  32.     db    2048 dup (?)    ; 2K stack
  33. _stack        ends
  34.  
  35. ;
  36. ; Global data
  37. ;
  38. _data    segment    
  39.  
  40.     public    pmhnd_sel,pmhnd_off
  41. pmhnd_off    dd    ?    ; Previous protected mode handler address
  42. pmhnd_sel    dw    ?        ;
  43.  
  44. intro    db    'Demo program (take over INT 21h, for func 09h processing)'
  45.     db    0Dh, 0Ah
  46.     db    '     This string printed with standard INT 21h handler'
  47.     db    0Dh, 0Ah, 0Dh, 0Ah, '$'
  48.  
  49. hndlr_msg db    'This string printed by our INT 21h handler','$'
  50.  
  51. chain_msg db    0Dh,0Ah,0Dh,0Ah,'This string printed with INT 21h func 02h'
  52.     db    0Dh, 0Ah, '$'
  53.  
  54. _data    ends
  55.  
  56. ;****************************************************************************
  57. ; Program entry point
  58. ;****************************************************************************
  59.  
  60.     assume    cs:_codeseg,ds:_data
  61. _codeseg    segment    
  62.  
  63.     public    main
  64. main    proc    near
  65.  
  66. ;
  67. ; Print the introduction string, and install the interrupt handler
  68. ;
  69.     lea    edx, intro        ; print intro string 
  70.     mov    ah, 09h                ; 
  71.     int    21h                ;
  72.     mov    cl, 21h            ; save original INT 21h handler
  73.     mov    ax, 2502h            ; 
  74.     int    21h                ;
  75.     mov    pmhnd_sel, es            ; 
  76.     mov    pmhnd_off, ebx            ;
  77.     push    ds            ; install our INT 21h handler
  78.     lea    edx, i21_fcn9_hnd        ; 
  79.     mov    ax, cs                ;
  80.     mov    ds, ax                ;
  81.     mov    cl, 21h                ; 
  82.     mov    ax, 2504h            ;
  83.     int    21h                ; 
  84.     pop    ds                ;
  85.  
  86. ;
  87. ; Print a string with INT 21h function 09h to demonstrate our handler
  88. ; got installed.  
  89. ;
  90.     lea    edx, hndlr_msg        ; print highlighted string
  91.     mov    ah, 09h                ;
  92.     int    21h                ;
  93.  
  94. ;
  95. ; Use another INT 21h function (02h) to demonstrate that chaining works
  96. ;
  97.     lea    ebx, chain_msg        ; get addr of string
  98. #loop1:
  99.     mov    dl, byte ptr [ebx]    ; get next byte in string
  100.     inc    ebx                ;
  101.     cmp    dl, '$'            ; branch if end of string
  102.     je    short #done_str            ;
  103.     mov    ah, 02h            ; print this character
  104.     int    21h                ;
  105.     jmp    short #loop1        ; continue loop
  106. #done_str:
  107.  
  108. ;
  109. ; Restore original INT 21h handler and exit
  110. ;
  111.     push    ds            ; restore original handler
  112.     mov    edx, pmhnd_off            ;
  113.     mov    ax, pmhnd_sel            ; 
  114.     mov    ds, ax                ;
  115.     mov    cl, 21h                ;
  116.     mov    ax, 2504h            ; 
  117.     int    21h                ;
  118.     pop    ds                ;
  119.     
  120.     mov    ax, 4C00h        ; exit to DOS
  121.     int    21h                ; 
  122.  
  123. main endp
  124.  
  125. ;****************************************************************************
  126. ; I21_FCN9_HND - Replacement INT 21h Handler.  Chains to
  127. ;    original handler for any function except 09h (print string).
  128. ;
  129. ;    For function 09h, prints the string using segment 001Ch (the screen
  130. ;    segment), and also uses the high intensity attribute to show it was
  131. ;    printed by this handler and not by DOS.
  132. ;
  133. ; Note: This handler ASSUMES an 80-column text display video mode, page 0
  134. ;****************************************************************************
  135.     public    i21_fcn9_hnd
  136. i21_fcn9_hnd    proc    far
  137.  
  138.     pushfd                ; save flags in case of chain
  139.     cmp    ah, 09h            ; branch if function 09h
  140.     je    short #func_09            ;
  141.  
  142. ;
  143. ; Chain to original INT 21h handler, with all registers and flags preserved
  144. ;
  145.     sub    esp, 8            ; save space for IRETD frame
  146.     push    ds            ; save registers we use
  147.     push    eax                ;
  148.     mov    ax, SS_DATA        ; set DS to our data segment
  149.     mov    ds, ax                ; 
  150.     mov    eax, pmhnd_off        ; put original handler addr in IRETD
  151.     mov    [esp+8], eax            ; frame
  152.     movzx    eax, pmhnd_sel            ; 
  153.     mov    [esp+12], eax            ;
  154.     pop    eax            ; restore registers
  155.     pop    ds                ;
  156.     iretd                ; chain to prev handler
  157.  
  158. #func_09:
  159. ;
  160. ; Print the string at DS:EDX to the display, using segment 001Ch, and
  161. ; turning on the high intensity video attribute
  162. ;
  163.     assume    ds:nothing
  164.     sti                ; re-enable interrupts
  165.     add    esp,4            ; pop unneeded flags off stack
  166.     push    eax            ; save registers we use
  167.     push    ebx                ;
  168.     push    ecx                ;
  169.     push    edx                ;
  170.     push    es                ;
  171.     push    edx            ; save string pointer
  172.     mov    ah, 03h            ; get cursor position in page 0
  173.     mov    bh,0                ;
  174.     int    10h                ;
  175.     xor    ebx,ebx            ; convert to offset in screen seg
  176.     mov    bl,dh                ; (assume 80 cols/row, page 0)
  177.     imul    ebx,160                ;
  178.     and    edx,0FFh            ;
  179.     add    ebx,edx                ;
  180.     pop    edx            ; restore string pointer
  181.     mov    ax,SS_SCREEN        ; set ES:EBX to screen position
  182.     mov    es,ax                ;
  183.     mov    ah,0Fh            ; set high intensity video attribute
  184. #loop:
  185.     mov    al,[edx]        ; get next char
  186.     cmp    al,'$'            ; branch if no more in string
  187.     je    short #exit            ;
  188.     mov    es:[ebx],ax        ; store char in video buffer
  189.     inc    edx            ; bump ptrs & continue loop
  190.     add    ebx,2                ;
  191.     jmp    #loop                ;
  192.  
  193. #exit:
  194.     pop    es            ; restore regs
  195.     pop    edx                ;
  196.     pop    ecx                ;
  197.     pop    ebx                ;
  198.     pop    eax                ;
  199.     iretd                ; return to interrupted code
  200.  
  201. i21_fcn9_hnd    endp
  202.  
  203. _codeseg    ends
  204.  
  205.     end main
  206.