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 installing an INT 21h handler that just chains
- ; to the previous 386|DOS-Extender handler for most functions, but
- ; processes function 09h (print string) by writing directly to the
- ; display with segment 001Ch (the video screen segment).
- ;
-
- ;
- ; Constants and data structures
- ;
- include dosx.ah
-
- ;
- ; Segment definitions and ordering
- ;
- _codeseg segment byte public use32 'code'
- _codeseg ends
- _data segment dword public use32 'data'
- _data ends
- _stack segment dword stack use32 'stack'
- db 2048 dup (?) ; 2K stack
- _stack ends
-
- ;
- ; Global data
- ;
- _data segment
-
- public pmhnd_sel,pmhnd_off
- pmhnd_off dd ? ; Previous protected mode handler address
- pmhnd_sel dw ? ;
-
- intro db 'Demo program (take over INT 21h, for func 09h processing)'
- db 0Dh, 0Ah
- db ' This string printed with standard INT 21h handler'
- db 0Dh, 0Ah, 0Dh, 0Ah, '$'
-
- hndlr_msg db 'This string printed by our INT 21h handler','$'
-
- chain_msg db 0Dh,0Ah,0Dh,0Ah,'This string printed with INT 21h func 02h'
- db 0Dh, 0Ah, '$'
-
- _data ends
-
- ;****************************************************************************
- ; Program entry point
- ;****************************************************************************
-
- assume cs:_codeseg,ds:_data
- _codeseg segment
-
- public main
- main proc near
-
- ;
- ; Print the introduction string, and install the interrupt handler
- ;
- lea edx, intro ; print intro string
- mov ah, 09h ;
- int 21h ;
- mov cl, 21h ; save original INT 21h handler
- mov ax, 2502h ;
- int 21h ;
- mov pmhnd_sel, es ;
- mov pmhnd_off, ebx ;
- push ds ; install our INT 21h handler
- lea edx, i21_fcn9_hnd ;
- mov ax, cs ;
- mov ds, ax ;
- mov cl, 21h ;
- mov ax, 2504h ;
- int 21h ;
- pop ds ;
-
- ;
- ; Print a string with INT 21h function 09h to demonstrate our handler
- ; got installed.
- ;
- lea edx, hndlr_msg ; print highlighted string
- mov ah, 09h ;
- int 21h ;
-
- ;
- ; Use another INT 21h function (02h) to demonstrate that chaining works
- ;
- lea ebx, chain_msg ; get addr of string
- #loop1:
- mov dl, byte ptr [ebx] ; get next byte in string
- inc ebx ;
- cmp dl, '$' ; branch if end of string
- je short #done_str ;
- mov ah, 02h ; print this character
- int 21h ;
- jmp short #loop1 ; continue loop
- #done_str:
-
- ;
- ; Restore original INT 21h handler and exit
- ;
- push ds ; restore original handler
- mov edx, pmhnd_off ;
- mov ax, pmhnd_sel ;
- mov ds, ax ;
- mov cl, 21h ;
- mov ax, 2504h ;
- int 21h ;
- pop ds ;
-
- mov ax, 4C00h ; exit to DOS
- int 21h ;
-
- main endp
-
- ;****************************************************************************
- ; I21_FCN9_HND - Replacement INT 21h Handler. Chains to
- ; original handler for any function except 09h (print string).
- ;
- ; For function 09h, prints the string using segment 001Ch (the screen
- ; segment), and also uses the high intensity attribute to show it was
- ; printed by this handler and not by DOS.
- ;
- ; Note: This handler ASSUMES an 80-column text display video mode, page 0
- ;****************************************************************************
- public i21_fcn9_hnd
- i21_fcn9_hnd proc far
-
- pushfd ; save flags in case of chain
- cmp ah, 09h ; branch if function 09h
- je short #func_09 ;
-
- ;
- ; Chain to original INT 21h handler, with all registers and flags preserved
- ;
- sub esp, 8 ; save space for IRETD frame
- push ds ; save registers we use
- push eax ;
- mov ax, SS_DATA ; set DS to our data segment
- mov ds, ax ;
- mov eax, pmhnd_off ; put original handler addr in IRETD
- mov [esp+8], eax ; frame
- movzx eax, pmhnd_sel ;
- mov [esp+12], eax ;
- pop eax ; restore registers
- pop ds ;
- iretd ; chain to prev handler
-
- #func_09:
- ;
- ; Print the string at DS:EDX to the display, using segment 001Ch, and
- ; turning on the high intensity video attribute
- ;
- assume ds:nothing
- sti ; re-enable interrupts
- add esp,4 ; pop unneeded flags off stack
- push eax ; save registers we use
- push ebx ;
- push ecx ;
- push edx ;
- push es ;
- push edx ; save string pointer
- mov ah, 03h ; get cursor position in page 0
- mov bh,0 ;
- int 10h ;
- xor ebx,ebx ; convert to offset in screen seg
- mov bl,dh ; (assume 80 cols/row, page 0)
- imul ebx,160 ;
- and edx,0FFh ;
- add ebx,edx ;
- pop edx ; restore string pointer
- mov ax,SS_SCREEN ; set ES:EBX to screen position
- mov es,ax ;
- mov ah,0Fh ; set high intensity video attribute
- #loop:
- mov al,[edx] ; get next char
- cmp al,'$' ; branch if no more in string
- je short #exit ;
- mov es:[ebx],ax ; store char in video buffer
- inc edx ; bump ptrs & continue loop
- add ebx,2 ;
- jmp #loop ;
-
- #exit:
- pop es ; restore regs
- pop edx ;
- pop ecx ;
- pop ebx ;
- pop eax ;
- iretd ; return to interrupted code
-
- i21_fcn9_hnd endp
-
- _codeseg ends
-
- end main
-