home *** CD-ROM | disk | FTP | other *** search
- .386p
- ;************************************************************************/
- ;* Copyright (C) 1986-1990 Phar Lap Software, Inc. */
- ;* Unpublished - rights reserved under the Copyright Laws of the */
- ;* United States. Use, duplication, or disclosure by the */
- ;* Government is subject to restrictions as set forth in */
- ;* subparagraph (c)(1)(ii) of the Rights in Technical Data and */
- ;* Computer Software clause at 252.227-7013. */
- ;* Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138 */
- ;************************************************************************/
-
- ;
- ; This program demonstrates how to call high level language code from
- ; within an interrupt handler. It installs a CTRL-C interrupt handler
- ; that calls the C library printf() routine to print a string.
- ;
-
- ;
- ; Constants and data structures
- ;
- include dosx.ah
-
- ;
- ; Segment definitions and ordering. No stack segment in this program,
- ; because the stack is set up by the C initializer before it calls us.
- ;
- _codeseg segment byte public use32 'code'
- _codeseg ends
- _data segment dword public use32 'data'
- _data ends
-
- ;
- ; Global data
- ;
- _data segment
-
- public pm_ccsel,pm_ccoff,rm_ccvec
- rm_ccvec dd ? ; original real mode CTRL-C vector
- pm_ccoff dd ? ; original protected mode CTRL-C vector
- pm_ccsel dw ? ;
- align 4
-
- public pgm_ss
- pgm_ss dw ? ; program's SS value (including RPL bits;
- ; you can't blindly load 0014h into SS if
- ; you're running at privilege level 3
- align 4
-
- public cc_flag
- cc_flag dd FALSE ; set TRUE when CTRL-C occurs
-
- public cc_tos
- db 1024 dup (?) ; Temp. stack space for CTRL-C handler
- cc_tos label byte ; Initial top of temp. stack
-
- typecc_msg db 'Please type CTRL-C',0Dh,0Ah,'$'
- cc_msg db 'CTRL-C was typed',0Ah,0 ; C-style string
- _data ends
-
- ;****************************************************************************
- ; main() routine called by C initializer
- ;****************************************************************************
-
- assume cs:_codeseg,ds:_data
- _codeseg segment
-
- public main
- main proc near
-
- push ebx ; save non-volatile C regs we modify
- push es ;
- mov ax,ss ; save program's SS value (gets correct
- mov pgm_ss,ax ; RPL bits in selector)
-
- ;
- ; Save current real and protected mode CTRL-C vectors, and install our
- ; CTRL-C handler so it always gets control in protected mode. We use
- ; the 2506h system call to do this, because the CTRL-C interrupt is
- ; always issued in real mode by DOS.
- ;
- mov cl, 23h ; save real mode CTRL-C vector
- mov ax, 2503h ;
- int 21h ;
- mov rm_ccvec, ebx ;
- mov ax, 2502h ; save prot mode CTRL-C vector
- mov cl,23h ;
- int 21h ;
- mov pm_ccsel, es ;
- mov pm_ccoff, ebx ;
- push ds ; install our CTRL-C handler to
- lea edx, cc_hndlr ; always get control in
- mov ax, cs ; protected mode
- mov ds, ax ;
- mov cl,23h ;
- mov ax, 2506h ;
- int 21h ;
- pop ds ;
-
- ;
- ; Wait for a CTRL-C to be typed
- ;
- mov cc_flag,FALSE ; no CTRL-C yet
- mov ah, 09h ; print "please type CTRL-C" message
- lea edx, typecc_msg ;
- int 21h ;
- #loop:
- cmp cc_flag,TRUE ; branch if CTRL-C has been typed
- je short #done ;
- mov ah,0Bh ; get input status, to allow DOS to
- int 21h ; generate CTRL-C interrupt
- jmp #loop ; continue loop
-
- #done:
- ;
- ; Restore the original interrupt vectors and exit
- ;
- mov cl, 23h ; restore original real mode vector
- mov ebx, rm_ccvec ;
- mov ax, 2505h ;
- int 21h ;
- push ds ; restore original prot mode vector
- mov edx, pm_ccoff ;
- mov ax, pm_ccsel ;
- mov ds, ax ;
- mov cl,23h ;
- mov ax, 2504h ;
- int 21h ;
- pop ds ;
-
- pop es ; restore registers
- pop ebx ;
- xor eax,eax ; return success to caller
- ret ;
-
- main endp
-
- ;****************************************************************************
- ; CC_HNDLR - Protected Mode CTRL-C Handler
- ; This handler calls through to the C printf() routine to print
- ; a string saying that CTRL-C occurred, and sets a global flag so
- ; the main loop knows that CTRL-C has occurred.
- ;
- ; In order to call a C routine, we must first set up a stack that
- ; is in segment 0014h, and also set DS and ES to segment 0014h.
- ;****************************************************************************
-
- extrn printf:near ; C library routine
-
- public cc_hndlr
- cc_hndlr proc near
- ;
- ; This is an interrupt handler, so we must preserve all registers that
- ; may get modified by us or the C routine we will call. Also re-enable
- ; interrupts so hardware interrupts aren't blocked.
- ;
- sti ; re-enable interrupts
- pushad ; save all registers
- push ds ;
- push es ;
- push fs ;
- push gs ;
-
- ;
- ; Set up a C environment, including a stack in our data segment, and call
- ; the C printf() library routine to print a string.
- ;
- ; Note the SS selector must have its RPL bits set to the current privilege
- ; level (unlike DS and ES, where we can just use a hardwired RPL of zero).
- ;
- mov ax,SS_DATA ; set DS and ES to our data seg
- mov ds,ax ;
- mov es,ax ;
- mov ecx,esp ; get current stack pointer
- mov dx,ss ;
- mov ax,pgm_ss ; switch to stack in data segment
- mov ss,ax ;
- lea esp,cc_tos ;
- push edx ; save old stack pointer on new stack
- push ecx ;
- lea eax,cc_msg ; call printf to print string
- push eax ;
- call printf ;
- add esp,4 ;
- lss esp,pword ptr [esp] ; switch back to old stack
-
- ;
- ; Set a flag so the main loop knows the CTRL-C occurred, restore registers,
- ; and return to caller
- ;
- mov cc_flag,TRUE ; CTRL-C has been processed
- pop gs ; restore regs
- pop fs ;
- pop es ;
- pop ds ;
- popad ;
- iretd ; return from interrupt
- cc_hndlr endp
-
- _codeseg ends
-
- end
-