;***************************************************************************** ; ; TTSUBS.ASM ; ; Copyright (C) 1990 by Aaron L. Brenner ; ; Purpose: ; Subroutines for TICTAC.C ; ; Contents: ; mouse_init() Initialize the mouse. ; mouse_on() Turns mouse processing on. ; mouse_off() Turns mouse processing off. ; mouse_bounds() Set the mouse cursor boundaries. ; mouse_cursor() Turn the mouse cursor on or off. ; mouse_buttons() Get the state of the mouse buttons. ; mouse_in_region() Determine whether or not the mouse is in a ; region. ; ; Revision history: ; 1.00 06/13/90 ALB Created. ; ;***************************************************************************** include mixed.inc clang equ 0 ifndef model model equ endif setmodel ;***************************************************************************** ; ; The mouse_info array gets set by our int handler, and is structured: ; ;***************************************************************************** mseinfo struc mi_flags db ? ; Bit flags: ; bit 0 = 1 Mouse present ; bit 1 = 1 Mouse handling ON mi_buttons db ? ; Button status mi_row db ? ; Current cursor row mi_col db ? ; Current cursor column mseinfo ends ;***************************************************************************** ; ; Structure used to define screen regions ; ;***************************************************************************** REGION struc r_ulrow db ? ; Upper left row r_ulcol db ? ; Upper left column r_lrrow db ? ; Lower right row r_lrcol db ? ; Lower right column REGION ends .data mouse_info mseinfo<0, 0, 0, 0> .code ;***************************************************************************** ; ; This is the user interrupt routine set by Fn 12. All it does is record the ; information passed by the mouse driver. ; ;***************************************************************************** mse_int proc far push ds ; Save it; it's the mouse driver's seg mov ax,DGROUP ; Get our data segment mov ds,ax ; test mouse_info.mi_flags,2 ; Should we pay attention? jz msei_exit ; No - ignore this stuff mov mouse_info.mi_buttons,bl; Save the button state mov ax,cx ; Get the column mov cl,3 ; Divide row and column by 8 shr ax,cl ; since mse driver reports pixel mov mouse_info.mi_col,al ; positions instead of text char shr dx,cl ; positions mov mouse_info.mi_row,dl ; Save the row msei_exit: pop ds ; Restore their segment ret ; Return to mouse driver mse_int endp ;***************************************************************************** ; ; int mouse_init(void) ; ; Purpose: ; Initializes the mouse, setting a user int handler. ; ; Input: ; None. ; ; Output: ; Function returns non-zero if there is a mouse. ; ;***************************************************************************** hproc mouse_init sub ax,ax ; Fn 0 - Reset mouse driver mov mouse_info.mi_flags,al ; Clear the flag int 33h ; or ax,ax ; Is there a mouse? jz hkms_exit ; Nope - just exit and al,1 ; Just use the low bit mov mouse_info.mi_flags,al ; Set the flag saying we have one push cs ; Need segment of the routine pop es ; mov dx,offset mse_int ; Address of routine to call mov cx,0000000000011110b ; Call mask (any button activity) mov ax,12 ; Fn 1 - Set user int sub int 33h ; hkms_exit: mov al,mouse_info.mi_flags ; Get the presence flag sub ah,ah ; to return hret ; Return to caller hendp ;***************************************************************************** ; ; void mouse_on(void) ; ; Purpose: ; Turn mouse processing on. This turns the mouse cursor on, and tells ; our int handler to start noticing what the mouse is doing. ; ; Input: ; None. ; ; Output: ; Mouse processing is enabled. ; ;***************************************************************************** hproc mouse_on test mouse_info.mi_flags,1 ; Do we have a mouse? jz mson_exit ; No - never mind mov ax,1 ; Turn the cursor on int 33h ; cli ; Disallow ints for a sec or mouse_info.mi_flags,2 ; Enable our processing of mouse sti ; mson_exit: hret ; Return to caller hendp ;***************************************************************************** ; ; void mouse_off(void) ; ; Purpose: ; Disables further mouse processing. ; ; Input: ; None. ; ; Output: ; Mouse processing is disabled, and the mouse cursor is turned off. ; ;***************************************************************************** hproc mouse_off test mouse_info.mi_flags,1 ; Is there a mouse? jz msof_exit ; No - never mind cli ; Disallow these for a sec and mouse_info.mi_flags,not 2; Disable mouse processing sti ; mov ax,2 ; Turn the cursor off int 33h ; msof_exit: hret ; Return to caller hendp ;***************************************************************************** ; ; void mouse_bounds(int ulrow, int ulcol, int lrrow, int lrcol) ; ; Purpose: ; Set the bounds for the mouse cursor. ; ; Input: ; ulrow, ; ulcol Row and column for the upper left corner ; lrrow, ; lrcol Row and column for the lower right corner ; ; Output: ; None. The mouse driver is notified. ; ;***************************************************************************** hproc mouse_bounds ulr:word, ulc:word, lrr:word, lrc:word test mouse_info.mi_flags,1 ; Is there a mouse? jz msbd_exit ; Nope - exit now mov ax,ulr ; Get upper row mov dx,lrr ; and lower row mov cl,3 ; Gotta multiply by 8 to come out the shl ax,cl ; way the mouse driver wants shl dx,cl ; mov cx,ax ; mov ax,8 ; Set vertical bounds int 33h ; mov ax,ulc ; Get left column mov dx,lrc ; and right column mov cl,3 ; Multiply them shl ax,cl ; shl dx,cl ; mov cx,ax ; mov ax,7 ; Set horizontal bounds int 33h ; msbd_exit: hret ; Return to caller hendp ;***************************************************************************** ; ; void mouse_cursor(int on_off) ; ; Purpose: ; Turn the mouse cursor on or off. ; ; Input: ; on_off Flag indicating whether the mouse cursor ; should be turned on or off: ; on_off = 0 Turn it off ; on_off != 0 Turn it on ; ; Output: ; The mouse cursor is on or off, as desired. ; ;***************************************************************************** hproc mouse_cursor on_off:word test mouse_info.mi_flags,1 ; Is there a mouse? jz mscr_exit ; Nope - don't bother mov bx,on_off ; Get the flag value mov ax,1 ; Start with ON cmp bx,1 ; See if BX = 0 or not adc ax,0 ; If BX = 0, then AX = 2 (OFF) int 33h ; Call the mouse driver mscr_exit: hret ; Return to caller hendp ;***************************************************************************** ; ; int mouse_buttons(void) ; ; Purpose: ; Get the state of the mouse buttons. ; ; Input: ; None. ; ; Output: ; Function returns the button state where: ; bit 0 = 1 if the left button is down ; bit 1 = 1 if the right button is down ; ;***************************************************************************** hproc mouse_buttons sub ax,ax ; Just in case it's early exit test mouse_info.mi_flags,1 ; Is there a mouse? jz msbt_exit ; Nope - exit with 0 mov al,mouse_info.mi_buttons; Get the button info and al,3 ; Just in case msbt_exit: hret ; Return to caller hendp ;***************************************************************************** ; ; int mouse_in_region(REGION *region_list, int num_regions) ; ; Purpose: ; Determine whether or not the mouse cursor is in a specific region of ; the screen. ; ; Input: ; region_list Pointer to a list of region structures ; num_regions Number of elements in that list ; ; Output: ; Function returns -1 if the mouse cursor is not in any region, or the ; index of the region structure. ; ;***************************************************************************** hproc mouse_in_region rlist:ptr, rnum:word test mouse_info.mi_flags,1 ; Is there a mouse? jz mirg_none ; Nope - return as if not in a region mov cx,rnum ; Get the number of structures sub dx,dx ; Start counter at 0 mov ax,word ptr mouse_info.mi_row ; Get the row & column (AL,AH) plds bx,rlist ; Point to the region list mirg_l1: cmp al,[bx].r_ulrow ; See if we're above it jb mirg_l2 ; Yep - not this one cmp al,[bx].r_lrrow ; See if we're below it ja mirg_l2 ; Yep - not this one cmp ah,[bx].r_ulcol ; See if we're to the left of it jb mirg_l2 ; Yep - not this one cmp ah,[bx].r_lrcol ; See if we're to the right of it ja mirg_l2 ; Yep - not this one, period mov ax,dx ; Get index of this one jmp short mirg_exit ; Exit now mirg_l2: add bx,size REGION ; Point to next one inc dx ; Count it loop mirg_l1 ; Loop for all of them mirg_none: ; ; Not in any region - return -1 ; mov ax,-1 ; Set return value mirg_exit: hret ; Return to caller hendp end