home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / INTHNDLR / CTRLC.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-02-18  |  5.9 KB  |  213 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    4096 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. ; asm_main() routine called by C main() function
  62. ;****************************************************************************
  63.  
  64.     assume    cs:_codeseg,ds:_data
  65. _codeseg    segment    
  66.  
  67.     public    asm_main,_asm_main,asm_main_
  68. _asm_main label    near
  69. asm_main_ label    near
  70. asm_main proc    near
  71.  
  72.     push    ebx            ; save non-volatile C regs we modify
  73.     push    es                ;
  74.     mov    ax,ss            ; save program's SS value (gets correct
  75.     mov    pgm_ss,ax            ; RPL bits in selector)
  76.  
  77. ;
  78. ; Save current real and protected mode CTRL-C vectors, and install our
  79. ; CTRL-C handler so it always gets control in protected mode.  We use
  80. ; the 2506h system call to do this, because the CTRL-C interrupt is
  81. ; always issued in real mode by DOS.
  82. ;
  83.     mov    cl, 23h            ; save real mode CTRL-C vector
  84.     mov    ax, 2503h            ; 
  85.     int    21h                ;
  86.     mov    rm_ccvec, ebx            ; 
  87.     mov    ax, 2502h        ; save prot mode CTRL-C vector
  88.     mov    cl,23h                ;
  89.     int    21h                ; 
  90.     mov    pm_ccsel, es            ;
  91.     mov    pm_ccoff, ebx            ; 
  92.     push    ds            ; install our CTRL-C handler to 
  93.     lea    edx, cc_hndlr            ; always get control in
  94.     mov    ax, cs                ; protected mode
  95.     mov    ds, ax                ;
  96.     mov    cl,23h                ;
  97.     mov    ax, 2506h            ; 
  98.     int    21h                ;
  99.     pop    ds                ; 
  100.  
  101. ;
  102. ; Wait for a CTRL-C to be typed
  103. ;
  104.     mov    cc_flag,FALSE        ; no CTRL-C yet
  105.     mov    ah, 09h            ; print "please type CTRL-C" message
  106.     lea    edx, typecc_msg            ;
  107.     int    21h                ;
  108. #loop:
  109.     cmp    cc_flag,TRUE        ; branch if CTRL-C has been typed
  110.     je    short #done            ;
  111.     mov    ah,0Bh            ; get input status, to allow DOS to
  112.     int    21h                ; generate CTRL-C interrupt
  113.     jmp    #loop            ; continue loop
  114.  
  115. #done:
  116. ;
  117. ; Restore the original interrupt vectors and exit
  118. ;
  119.     mov    cl, 23h            ; restore original real mode vector
  120.     mov    ebx, rm_ccvec            ; 
  121.     mov    ax, 2505h            ;
  122.     int    21h                ; 
  123.     push    ds            ; restore original prot mode vector
  124.     mov    edx, pm_ccoff            ; 
  125.     mov    ax, pm_ccsel            ;
  126.     mov    ds, ax                ; 
  127.     mov    cl,23h                ;
  128.     mov    ax, 2504h            ;
  129.     int    21h                ; 
  130.     pop    ds                ;
  131.  
  132.     pop    es            ; restore registers
  133.     pop    ebx                ;
  134.     xor    eax,eax            ; return success to caller
  135.     ret                    ;
  136.  
  137. asm_main endp
  138.  
  139. ;****************************************************************************
  140. ; CC_HNDLR - Protected Mode CTRL-C Handler
  141. ;    This handler calls through to the C printf() routine to print 
  142. ;    a string saying that CTRL-C occurred, and sets a global flag so
  143. ;    the main loop knows that CTRL-C has occurred.
  144. ;
  145. ;    In order to call a C routine, we must first set up a stack that
  146. ;    is in segment 0014h, and also set DS and ES to segment 0014h.
  147. ;****************************************************************************
  148.  
  149. ifdef __MSC32__
  150. c_printf equ    _printf
  151. endif
  152. ifdef __HIGHC__
  153. c_printf equ    printf
  154. endif
  155. ifdef __WATCOMC__
  156. c_printf equ    printf_
  157. endif
  158.     extrn    c_printf:near        ; C library routine
  159.  
  160.     public    cc_hndlr
  161. cc_hndlr    proc    near
  162. ;
  163. ; This is an interrupt handler, so we must preserve all registers that
  164. ; may get modified by us or the C routine we will call.  Also re-enable
  165. ; interrupts so hardware interrupts aren't blocked.
  166. ;
  167.     sti                ; re-enable interrupts
  168.     pushad                ; save all registers
  169.     push    ds                ;
  170.     push    es                ;
  171.     push    fs                ;
  172.     push    gs                ;
  173.  
  174. ;
  175. ; Set up a C environment, including a stack in our data segment, and call
  176. ; the C printf() library routine to print a string.
  177. ;
  178. ; Note the SS selector must have its RPL bits set to the current privilege
  179. ; level (unlike DS and ES, where we can just use a hardwired RPL of zero).
  180. ;
  181.     mov    ax,SS_DATA        ; set DS and ES to our data seg
  182.     mov    ds,ax                ;
  183.     mov    es,ax                ;
  184.     mov    ecx,esp            ; get current stack pointer
  185.     mov    dx,ss                ;
  186.     mov    ax,pgm_ss        ; switch to stack in data segment
  187.     mov    ss,ax                ;
  188.     lea    esp,cc_tos            ;
  189.     push    edx            ; save old stack pointer on new stack
  190.     push    ecx                ;
  191.     lea    eax,cc_msg        ; call printf to print string
  192.     push    eax                ;
  193.     call    c_printf            ;
  194.     add    esp,4                ;
  195.     lss    esp,pword ptr [esp]    ; switch back to old stack
  196.  
  197. ;
  198. ; Set a flag so the main loop knows the CTRL-C occurred, restore registers,
  199. ; and return to caller
  200. ;
  201.     mov    cc_flag,TRUE        ; CTRL-C has been processed
  202.     pop    gs            ; restore regs
  203.     pop    fs                ;
  204.     pop    es                ;
  205.     pop    ds                ;
  206.     popad                    ;
  207.     iretd                ; return from interrupt
  208. cc_hndlr    endp
  209.  
  210. _codeseg    ends
  211.  
  212.     end
  213.