home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************/
- ;* Copyright (C) 1986-1988 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 */
- ;************************************************************************/
- ;
- ; RTAIL2.ASM - This is the real mode portion of
- ; an example program that uses
- ; the Microsoft mouse driver, and also demonstrates
- ; several techniques for mixing real and protected
- ; mode code in the same program.
- ;
- ; FUNCTIONALITY and IMPLEMENTATION - As described
- ; in PTAIL2.ASM.
- ;
-
- ;
- ; Segment ordering and attributes.
- ;
- rmcode segment byte public use16
- rmcode ends
- rmdata segment dword public use16
- rmdata ends
- stack segment dword stack use16
- stack ends
-
- ;
- ; Constants
- ;
- TRUE equ 1
- FALSE equ 0
-
- ;
- ; Give program a 4K stack
- ;
- stack segment
- db 4096 dup(?)
- stack ends
-
- ;
- ; Data structure for global data that is
- ; stored in the intermode call buffer, where
- ; both the real mode and the protected mode
- ; program can access it. This data is
- ; initialized by the protected mode program,
- ; and modified by the real mode program.
- ;
- SHARE struc
- DONEF dd ? ; flags when pgm done
- OUTP_CH db ? ; current output char
- SHARE ends
-
- ;
- ; Interrupt used to switch by prot mode pgm to
- ; transfer control to this real mode program.
- ;
- REALINT equ 0F1h
-
- ;
- ; Global data
- ;
- rmdata segment
-
- rm_cbuf dd ? ; real mode addr of
- ; call buffer
- rmi_sel dw ? ; original real mode
- rmi_offs dw ? ; interrupt vec
-
- ;
- ; Error messages
- ;
- tailmsg db 'Bad cmd tail in real mode pgm'
- db 0Dh,0Ah,'$'
- chndlrmsg db 'Output char at cursor error'
- db 0Dh,0Ah,'$'
-
- rmdata ends
-
- page
- assume cs:rmcode,ds:rmdata
- rmcode segment
-
- ;***************************************************
- ; main - Finishes setting up the interface with the
- ; prot mode program, then sets up the mouse
- ; interrupt handler, then just loops,
- ; processing mouse button hits until the left
- ; one is pressed twice.
- ;***************************************************
- main proc near ; program entry point
-
- ;
- ; Get the command tail out of the PSP, then set up DS
- ; to point to our data segment.
- ;
- mov bx,ds:80h ; get 1st word of tail
- mov ax,rmdata ; set up DS
- mov ds,ax ;
-
- ;
- ; The command tail should be 1 byte long, and that
- ; byte is the interrupt number that is used to call
- ; the protected mode program. Modify the INT
- ; instructions we use to call through to protected mode.
- ;
- cmp bl,1 ; branch if bad len
- jne short #tail_err ;
- mov cs:(byte ptr int_inst1+1),bh
- mov cs:(byte ptr int_inst2+1),bh
-
- ;
- ; Call our init routine to finish setting up the
- ; communication interface with the prot mode pgm,
- ; and to set up the mouse interrupt handler.
- ;
- call init
-
- ;
- ; Now just loop until the done flag is set by
- ; the interrupt handlers.
- ;
- les bx,rm_cbuf ; get ptr to buffer
- #wait:
- cmp dword ptr es:[bx].DONEF,FALSE
- je #wait
-
- call cleanup ; clean up for exit
- mov al,0 ; return success
-
- #exit:
- mov ah,4Ch ; exit to parent pgm
- int 21h ;
-
- #tail_err:
- lea dx,tailmsg
- #err:
- mov ah,9 ; output error msg
- int 21h ;
- mov al,1 ; return error
- jmp #exit ;
-
- main endp
-
- ;***************************************************
- ; init - This routine takes over the interrupt vector
- ; we use to call thru to real mode from the
- ; prot mode program, then calls the prot mode
- ; program to give it the vector number and to
- ; get the address of the intermode call buffer,
- ; and then calls the mouse driver to set up
- ; the character input mode routine as the
- ; mouse handler for when a mouse button gets
- ; pressed.
- ;***************************************************
- init proc near
-
- push es ; save regs
-
- ;
- ; Save the current real mode vector for the interrupt
- ; we will use to switch from prot mode to real mode,
- ; then take over the interrupt vector to point to
- ; our routine.
- ;
- mov al,REALINT ; save original
- mov ah,35h ; real mode
- int 21h ; vector
- mov ax,es ;
- mov rmi_sel,ax ;
- mov rmi_offs,bx ;
- mov al,REALINT ; set up our
- mov ah,25h ; handler
- lea dx,from_prot ;
- push ds ;
- push cs ;
- pop ds ;
- int 21h ;
- pop ds ;
-
- ;
- ; Call thru to prot mode to get the addr of the
- ; intermode call buffer, and to give the prot mode
- ; program the number of the interrupt we took over.
- ;
- mov eax,1 ; function number
- mov bl,REALINT ; interrupt number
- mov cx,cs ; code segment addr
- int_inst1:
- int 0 ; call prot mode
- mov rm_cbuf,ebx ; save addr of buf
-
- ;
- ; Call the mouse driver to set up the character mode
- ; handler as the mouse handler when a button is
- ; pressed.
- ;
- push cs ; handler addr in
- pop es ; ES:DX
- lea dx,ch_hndlr ;
- mov cx,0Ah ; interrupt mask
- mov ax,12 ; set up handler
- int 33h ;
-
- #exit:
- pop es ; restore regs &
- ret ; exit
-
- init endp
-
- ;***************************************************
- ; cleanup - All this routine does is restore the
- ; original vector for the interrupt we took
- ; over.
- ;***************************************************
- cleanup proc near
- mov al,REALINT ; restore original
- mov ah,25h ; interrupt
- mov dx,rmi_offs ; vector
- push ds ;
- push rmi_sel ;
- pop ds ;
- int 21h ;
- pop ds ;
- ret ; exit
- cleanup endp
-
- ;***************************************************
- ; from_prot - This is the routine that gets control
- ; when the prot mode program issues the software
- ; interrupt that we took over. This routine
- ; only performs one function, so there are no
- ; function codes. It sets up the toggle
- ; mode routine as the mouse handler.
- ;
- ; IN: Nothing
- ; OUT: AX-DX = destroyed
- ;***************************************************
- assume nothing,cs:rmcode
- from_prot proc near
- push es ; save regs
- push cs ; handler addr in
- pop es ; ES:DX
- lea dx,tog_hndlr ;
- mov cx,0Ah ; interrupt mask
- mov ax,12 ; set up handler
- int 33h ;
- pop es ; restore regs &
- iret ; exit
- from_prot endp
-
- ;***************************************************
- ; ch_hndlr - This routine is invoked by the mouse
- ; driver when either mouse button is pressed,
- ; and when we are in character output mode.
- ; This handler just calls a protected mode
- ; routine to process the interrupt. Since
- ; this is a hardware interrupt handler, it is
- ; obligated to preserve all 32-bit registers.
- ;
- ; This routine demonstrates passing values
- ; both on the stack and in registers to a
- ; protected mode routine invoked with a
- ; software interrupt.
- ;***************************************************
- assume nothing,cs:rmcode
- ch_hndlr proc far
- push eax ; save regs wiped
- push ebx ; out by prot
- push ecx ; mode routine
- push edx ;
-
- ;
- ; To call the prot mode routine, all we do is push
- ; any params to the routine onto the stack, then
- ; issue the software interrupt.
- ;
- push ax ; param = cond. mask
- mov eax,2 ; mouse hit function
- int_inst2:
- int 0 ; call prot mode routine
- add sp,2 ; pop parameters
- cmp eax,TRUE ; branch if error
- je short #err ;
-
- #exit:
- pop edx ; restore regs &
- pop ecx ; exit
- pop ebx ;
- pop eax ;
- ret ;
-
- #err:
- push ds ; save DS
- mov ax,rmdata ; set up data seg
- mov ds,ax ;
- assume ds:rmdata ;
- lea dx,chndlrmsg ; output error msg
- mov ah,9 ;
- int 21h ;
- pop ds ; restore DS and exit
- jmp #exit ;
- ch_hndlr endp
-
- ;***************************************************
- ; tog_hndlr - This routine is invoked by the mouse
- ; driver when either mouse button is pressed,
- ; and we are in toggle mode (the left mouse
- ; button was the last one pressed).
- ; If the left button has been pressed, we
- ; set the done flag. If the right button has
- ; been pressed, we toggle the character that
- ; gets output between '*' and ' ', and then
- ; restore ch_hndlr as the mouse interrupt
- ; handler. Since this is a hardware
- ; interrupt handler, it is obligated to
- ; preserve all 32-bit registers.
- ;***************************************************
- assume nothing,cs:rmcode
- tog_hndlr proc far
- push ds ; save regs
- push es ;
-
- push rmdata ; set up data segment
- pop ds ;
- assume ds:rmdata ;
- lds bx,rm_cbuf ; set up DS:BX to point
- assume ds:nothing ; to call buffer
-
- test ax,2 ; branch if left button
- jz short #right ; not pressed
- mov [bx].DONEF,TRUE ; set done flag & exit
- jmp short #exit ;
-
- #right:
- mov al,' ' ; assume char = ' '
- cmp [bx].OUTP_CH,'*' ; toggle output char
- je short #space ;
- mov al,'*' ;
- #space: ;
- mov [bx].OUTP_CH,al ;
- mov ax,cs ; Restore ch_hndlr
- mov es,ax ; as mouse
- lea dx,ch_hndlr ; handler
- mov cx,0Ah ;
- mov ax,12 ;
- int 33h ;
-
- #exit:
- pop es ; restore regs &
- pop ds ; exit
- ret ;
- tog_hndlr endp
-
- rmcode ends
-
- end main ; program entry point
-