home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c220 / 7.ddi / EXAMPLES / INTHNDLR / CTRLC.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-11-30  |  5.7 KB  |  202 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 how to call high level language code from 
  14. ; within an interrupt handler.  It installs a CTRL-C interrupt handler
  15. ; that calls the C library printf() routine to print a string.
  16. ;
  17.  
  18. ;
  19. ; Constants and data structures
  20. ;
  21. include    dosx.ah
  22.  
  23. ;
  24. ; Segment definitions and ordering.  No stack segment in this program,
  25. ; because the stack is set up by the C initializer before it calls us.
  26. ;
  27. _codeseg    segment    byte public use32 'code'
  28. _codeseg    ends
  29. _data        segment    dword public use32 'data'
  30. _data        ends
  31.  
  32. ;
  33. ; Global data
  34. ;
  35. _data    segment    
  36.  
  37.     public    pm_ccsel,pm_ccoff,rm_ccvec
  38. rm_ccvec    dd    ?    ; original real mode CTRL-C vector
  39. pm_ccoff    dd    ?    ; original protected mode CTRL-C vector
  40. pm_ccsel    dw    ?        ; 
  41.     align    4
  42.  
  43.     public    pgm_ss
  44. pgm_ss    dw    ?        ; program's SS value (including RPL bits;
  45.                 ; you can't blindly load 0014h into SS if
  46.                 ; you're running at privilege level 3
  47.     align    4
  48.  
  49.     public    cc_flag
  50. cc_flag    dd    FALSE        ; set TRUE when CTRL-C occurs
  51.  
  52.     public    cc_tos
  53.     db    1024 dup (?)    ; Temp. stack space for CTRL-C handler
  54. cc_tos    label    byte        ; Initial top of temp. stack
  55.  
  56. typecc_msg db    'Please type CTRL-C',0Dh,0Ah,'$'
  57. cc_msg    db    'CTRL-C was typed',0Ah,0    ; C-style string
  58. _data    ends
  59.  
  60. ;****************************************************************************
  61. ; main() routine called by C initializer
  62. ;****************************************************************************
  63.  
  64.     assume    cs:_codeseg,ds:_data
  65. _codeseg    segment    
  66.  
  67.     public    main
  68. main proc    near
  69.  
  70.     push    ebx            ; save non-volatile C regs we modify
  71.     push    es                ;
  72.     mov    ax,ss            ; save program's SS value (gets correct
  73.     mov    pgm_ss,ax            ; RPL bits in selector)
  74.  
  75. ;
  76. ; Save current real and protected mode CTRL-C vectors, and install our
  77. ; CTRL-C handler so it always gets control in protected mode.  We use
  78. ; the 2506h system call to do this, because the CTRL-C interrupt is
  79. ; always issued in real mode by DOS.
  80. ;
  81.     mov    cl, 23h            ; save real mode CTRL-C vector
  82.     mov    ax, 2503h            ; 
  83.     int    21h                ;
  84.     mov    rm_ccvec, ebx            ; 
  85.     mov    ax, 2502h        ; save prot mode CTRL-C vector
  86.     mov    cl,23h                ;
  87.     int    21h                ; 
  88.     mov    pm_ccsel, es            ;
  89.     mov    pm_ccoff, ebx            ; 
  90.     push    ds            ; install our CTRL-C handler to 
  91.     lea    edx, cc_hndlr            ; always get control in
  92.     mov    ax, cs                ; protected mode
  93.     mov    ds, ax                ;
  94.     mov    cl,23h                ;
  95.     mov    ax, 2506h            ; 
  96.     int    21h                ;
  97.     pop    ds                ; 
  98.  
  99. ;
  100. ; Wait for a CTRL-C to be typed
  101. ;
  102.     mov    cc_flag,FALSE        ; no CTRL-C yet
  103.     mov    ah, 09h            ; print "please type CTRL-C" message
  104.     lea    edx, typecc_msg            ;
  105.     int    21h                ;
  106. #loop:
  107.     cmp    cc_flag,TRUE        ; branch if CTRL-C has been typed
  108.     je    short #done            ;
  109.     mov    ah,0Bh            ; get input status, to allow DOS to
  110.     int    21h                ; generate CTRL-C interrupt
  111.     jmp    #loop            ; continue loop
  112.  
  113. #done:
  114. ;
  115. ; Restore the original interrupt vectors and exit
  116. ;
  117.     mov    cl, 23h            ; restore original real mode vector
  118.     mov    ebx, rm_ccvec            ; 
  119.     mov    ax, 2505h            ;
  120.     int    21h                ; 
  121.     push    ds            ; restore original prot mode vector
  122.     mov    edx, pm_ccoff            ; 
  123.     mov    ax, pm_ccsel            ;
  124.     mov    ds, ax                ; 
  125.     mov    cl,23h                ;
  126.     mov    ax, 2504h            ;
  127.     int    21h                ; 
  128.     pop    ds                ;
  129.  
  130.     pop    es            ; restore registers
  131.     pop    ebx                ;
  132.     xor    eax,eax            ; return success to caller
  133.     ret                    ;
  134.  
  135. main endp
  136.  
  137. ;****************************************************************************
  138. ; CC_HNDLR - Protected Mode CTRL-C Handler
  139. ;    This handler calls through to the C printf() routine to print 
  140. ;    a string saying that CTRL-C occurred, and sets a global flag so
  141. ;    the main loop knows that CTRL-C has occurred.
  142. ;
  143. ;    In order to call a C routine, we must first set up a stack that
  144. ;    is in segment 0014h, and also set DS and ES to segment 0014h.
  145. ;****************************************************************************
  146.  
  147.     extrn    printf:near        ; C library routine
  148.  
  149.     public    cc_hndlr
  150. cc_hndlr    proc    near
  151. ;
  152. ; This is an interrupt handler, so we must preserve all registers that
  153. ; may get modified by us or the C routine we will call.  Also re-enable
  154. ; interrupts so hardware interrupts aren't blocked.
  155. ;
  156.     sti                ; re-enable interrupts
  157.     pushad                ; save all registers
  158.     push    ds                ;
  159.     push    es                ;
  160.     push    fs                ;
  161.     push    gs                ;
  162.  
  163. ;
  164. ; Set up a C environment, including a stack in our data segment, and call
  165. ; the C printf() library routine to print a string.
  166. ;
  167. ; Note the SS selector must have its RPL bits set to the current privilege
  168. ; level (unlike DS and ES, where we can just use a hardwired RPL of zero).
  169. ;
  170.     mov    ax,SS_DATA        ; set DS and ES to our data seg
  171.     mov    ds,ax                ;
  172.     mov    es,ax                ;
  173.     mov    ecx,esp            ; get current stack pointer
  174.     mov    dx,ss                ;
  175.     mov    ax,pgm_ss        ; switch to stack in data segment
  176.     mov    ss,ax                ;
  177.     lea    esp,cc_tos            ;
  178.     push    edx            ; save old stack pointer on new stack
  179.     push    ecx                ;
  180.     lea    eax,cc_msg        ; call printf to print string
  181.     push    eax                ;
  182.     call    printf                ;
  183.     add    esp,4                ;
  184.     lss    esp,pword ptr [esp]    ; switch back to old stack
  185.  
  186. ;
  187. ; Set a flag so the main loop knows the CTRL-C occurred, restore registers,
  188. ; and return to caller
  189. ;
  190.     mov    cc_flag,TRUE        ; CTRL-C has been processed
  191.     pop    gs            ; restore regs
  192.     pop    fs                ;
  193.     pop    es                ;
  194.     pop    ds                ;
  195.     popad                    ;
  196.     iretd                ; return from interrupt
  197. cc_hndlr    endp
  198.  
  199. _codeseg    ends
  200.  
  201.     end
  202.