
	Comment         #

	extern void far handler(void);  /* a mouse event handler */
	------------------------------
	Version:        1.0
	Date:           1/13/90
	Author:         Michael Kelly

	Environment:

	Specific to mice compatible with the Microsoft Mouse Driver Interface

	External Variables:     _head, _tail: near pointers to links
				in a circular queue.  Each link has the
				form mirrored by the event_q struc defined
				below.

    even                    ;use word data alignment
    event_q struc           ;mirrors EVENT link defined in mouseq.h
    xc      dw      ?       ;x mouse coordinate
    yc      dw      ?       ;y mouse coordinate
    butstat dw      ?       ;mouse button status
    evmask  dw      ?       ;event mask ( active events at time of entry )
    vflag   dw      ?       ;"valid" flag
    nextptr dw      ?       ;pointer to next link
    event_q ends


				_head and _tail are defined in mouseq.h
				and iniitialized in the file mouseq.c,
				which is responsible for the creation and
				destruction of the queue.

	------------------------------

	Mouse Event Handler called as a far function from the mouse driver
	when it senses an event for which the event mask has a bit set.


	Designed to be linked to a Small Memory Model C Program

	This example uses Turbo C V. 2.0

	****************************************
	On Entry:
	    AX = bit mask for current events
		 where  a 1 in bit position:
		    0   =   mouse cursor movement
		    1   =   left button press
		    2   =   right button press
		    3   =   left button release
		    4   =   right button release
		    5 - 15: unused
	    BX = button status
	    CX = X mouse coordinate
	    DX = Y mouse coordinate
	****************************************

	#



	name    _handler


_TEXT	segment	byte public 'CODE'
DGROUP	group	_DATA,_BSS
	assume  cs:_TEXT,ds:DGROUP
_TEXT	ends
_DATA   segment word public 'DATA'
	extrn   _head:word,_tail:word

even                    ;use word data alignment
event_q struc
xc      dw      ?
yc      dw      ?
butstat dw      ?
evmask  dw      ?
vflag   dw      ?
nextptr dw      ?
event_q ends

sav_ax  dw      ?
_DATA	ends
_BSS	segment word public 'BSS'
_b@	label	byte
_BSS	ends
_TEXT   segment byte public 'CODE'

	;***********
	;Entry Point
	;***********

 _handler       proc    far
	cli                     ;disable interrupts to avoid re-entry
	push    ds              ;save registers
	push    di
	mov     di,DGROUP       ;point DS to application's data segment
	mov     ds,di
	mov     sav_ax,ax       ;we're called from inside the mouse driver
				;so keep stack pushes to a minimum

	mov     di,_tail
	mov     ax,[di].nextptr         ;get tail->next pointer
	mov     di,_head
	cmp     ax,[di]         ;if it equals head then queue is full
	jne     hndlr1
	jmp     handl_exit      ;exit if queue is full

 hndlr1:
	mov     di,_tail        ;we sacrifice one slot in queue to simplify
				;code, similar to PC BIOS keyboard buffer
				;routine

	;***********************************
	;store mouse event info in the queue
	;***********************************

	mov     [di].xc,cx              ;x mouse coordinate from CX reg
	mov     [di].yc,dx              ;y mouse coordinate from DX reg
	mov     [di].butstat,bx         ;mouse button status from BX reg
	mov     ax,sav_ax               ;event mask from AX reg
	mov     [di].evmask,ax
	mov     [di].vflag,1            ;mark queue entry "valid"
	mov     ax,[di].nextptr
	mov     _tail,ax                ;bump tail pointer

	;******************
	;Handler Exit Point
	;******************

 handl_exit:
	pop     di                      ;restore registers
	pop     ds
	sti                             ;enable interrupts
	ret                             ;far return to mouse driver
 _handler       endp
_TEXT	ends
_DATA   segment word public 'DATA'
_s@	label	byte
_DATA	ends
_TEXT	segment	byte public 'CODE'
	public   _handler
_TEXT	ends
	end
