   TITLE   mif

X	EQU	4

; Title   : Microsoft C language interface to the Logitech mouse driver
; Author  : Roger Armstrong
; Date    : 10-30-85
; System  : Microsoft Macro Assembler
; Version : 1.00


; Short Explanation:
;   The Microsoft C compiler can link an object module produced by the 
;  macro assembler with its own object modules. When this interface
;  module is assembled it produces an object module which exports mouse
;  driver interface functions for use by a C program.

;  When the user compiles the application to link with the interface
;  he/she should specify this model.On the Microsoft C compiler this
;  is done using the -Ml option, ' cc -c -Ml main.c '.
;

; ***********************************************
; *						*
; *		  M  A  C  R  O  S		*
; *						*
; ***********************************************

enter   MACRO
	push  bp	   ; standard C compiler call entry
	mov   bp, sp    
	push  di	
	push  si 
	ENDM

leave   MACRO
	pop   si
	pop   di
        pop   bp	
leavd	ENDM
	
	.286p

_DATA		SEGMENT  WORD PUBLIC 'DATA'
_DATA		ENDS
CONST		SEGMENT  WORD PUBLIC 'CONST'
CONST		ENDS
_BSS		SEGMENT  WORD PUBLIC 'BSS'
_BSS		ENDS
IBM_TEXT	SEGMENT  WORD PUBLIC 'CODE'
IBM_TEXT	ENDS

DGROUP	GROUP	CONST, _BSS, _DATA
;	ASSUME DS: DGROUP, SS: DGROUP

GROUP   CONST,  _BSS,   _DATA
	ASSUME  CS: IBM_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP

PUBLIC  _DriverInstalled
PUBLIC  _FlagReset
PUBLIC  _ShowCursor
PUBLIC  _HideCursor
PUBLIC  _GetPosBut
PUBLIC  _SetCursorPos
PUBLIC  _GetButPres
PUBLIC  _GetButRel
PUBLIC  _SetHorizontalLimits
PUBLIC  _SetVerticalLimits
PUBLIC  _SetGraphicCursor
PUBLIC  _ReadMotionCounters
PUBLIC	_ClearEventHandler
PUBLIC  _SetEventHandler
PUBLIC  _LightPenOn
PUBLIC  _LightPenOff
PUBLIC  _SetMickeysPerPixel
PUBLIC  _ConditionalOff
PUBLIC  _SetSpeedThreshold 


_DATA   SEGMENT
_DATA   ENDS

IBM_TEXT      SEGMENT

; *******************************************************
; *							*
; *	T H E   I N T E R F A C E   R O U T I N E S	*
; *							*
; *******************************************************


CDataSeg  dw  DGROUP

PUBLIC  _DriverInstalled
;
;    boolean DriverInstalled();
;
_DriverInstalled	PROC FAR
			enter
			; check for driver
			push  ds
			push  si
			mov   ax, 0
			mov   ds, ax
			mov   si, 0CCH   ; mouse int vector
			cmp   word ptr ds:[si], 0
			jnz vector_not_zero
			pop   si
			pop   ds
			mov   ax, 0
			leave
	vector_not_zero:
			push  es
			mov   es, ds:[si+2] ; segment
			mov   si, ds:[si]   ; offset
			cmp   byte ptr es:[si], 0CFH  ;CF = iret  
			pop   es
			pop   si
			pop   ds
			jnz driver_present
			mov   ax, 0
			leave
			jz driver_present
	driver_present:
			mov   ax, 1
			leave
_DriverInstalled	ENDP

; ****************************************
; *	F U N C T I O N  0  :  F l a g R e s e t	      *
; ****************************************

PUBLIC  _FlagReset
;
;     FlagReset( mouseStatusPtr, numberOfButtonsPtr )
;     int *mouseStatusPtr, *numberOfButtonsPtr;
;

_FlagReset      PROC FAR
;	  Output: AX --> mouse status
;		   0 (FALSE): mouse hardware and software
;			      not installed
;		  -1 (TRUE) : mouse hardware and software
;			      installed
;		  BX --> number of mouse buttons
;
			enter
			mov   ax, 0	; function 0
			int   33h	  ; call mouse driver function 
			les   di, 6[bp]    ; address of mouseStatus
			mov   es:[di], ax  ; mouseStatus = ax
			les   di, 10[bp]   ; address of numberOfButtons
			mov   es:[di], bx  ; numberOfButtons = bx
			leave

_FlagReset	ENDP


; ****************************************
; *	F U N C T I O N  1  :  
; ****************************************

PUBLIC _ShowCursor
;
; ShowCursor();
;

_ShowCursor	PROC FAR
			enter
			mov   ax, 1	; function 1
			int   33h	  ; call mouse driver function 
			leave

_ShowCursor	ENDP       

; ****************************************
; *	F U N C T I O N  2  :  
; ****************************************

PUBLIC _HideCursor
;
; HideCursor();
;

_HideCursor	PROC FAR
			enter
			mov   ax, 2	; function 2
			int   33h	  ; call mouse driver function 
			leave

_HideCursor	ENDP


; ****************************************
; *	F U N C T I O N  3  :  
; ****************************************

PUBLIC _GetPosBut
;
; GetPosBut ( buttonStatus, horizontal, vertical )
; struct {
;    unsigned leftButton   : 1;
;    unsigned rightButton  : 1;
;    unsigned middleButton : 1;
;	} *buttonStatus;
; int *horizontal, *vertical;
;

_GetPosBut	PROC FAR
			enter
			mov   ax, 3	; function 3
			int   33h	  ; call mouse driver function 
			les   di, 6[bp]    ; address of buttonStatus
			mov   es:[di], bx  ; buttonStatus = bx
			les   di, 10[bp]   ; address of horizontal
			mov   es:[di], cx  ; horizontal = cx
			les   di, 14[bp]   ; address of vertical
			mov   es:[di], dx  ; vertical = dx
			leave
_GetPosBut	ENDP


; ****************************************
; *	F U N C T I O N  4  :  
; ****************************************

PUBLIC _SetCursorPos
;
; SetCursorPos (horizontal, vertical)
; int horizontal, vertical;
;

_SetCursorPos	PROC FAR
			enter
			mov   cx, 6[bp]    ; cx = horizontal
			mov   dx, 8[bp]    ; dx = vertical
			mov   ax, 4	; function 4
			int   33h	  ; call mouse driver function 
			leave
_SetCursorPos	ENDP


; ****************************************
; *	F U N C T I O N  5  :  
; ****************************************

PUBLIC _GetButPres
;
; GetButPres (button, buttonStatus, buttonPressCount, horizontal, vertical)
; int button, *buttonStatus, *buttonPressCount, *horizontal, *vertical;
;

_GetButPres	PROC FAR
			enter
			mov   bx, 6[bp]    ; bx = button
			mov   ax, 5	; function 5
			int   33h	  ; call mouse driver function 
			les   di, 8[bp]   ; address of buttonStatus
			mov   es:[di], ax  ; buttonStatus = ax
			les   di, 12[bp]   ; address of buttonPressCount
			mov   es:[di], bx  ; buttonPressCount = bx
			les   di, 16[bp]   ; address of horizontal
			mov   es:[di], cx  ; horizontal = cx
			les   di, 20[bp]   ; address of vertical
			mov   es:[di], dx  ; vertical = dx
			leave
_GetButPres	ENDP


; ****************************************
; *	F U N C T I O N  6  :  
; ****************************************

PUBLIC _GetButRel
;
; GetButRel (button, buttonStatus, buttonReleaseCount, horizontal, vertical)
; int button, *buttonStatus, *buttonReleaseCount, *horizontal, *vertical;


_GetButRel	PROC FAR
			enter
			mov   bx, 6[bp]    ; bx = button
			mov   ax, 6	; function 6
			int   33h	  ; call mouse driver function 
			les   di, 8[bp]    ; address of buttonStatus
			mov   es:[di], ax  ; buttonStatus = ax
			les   di, 12[bp]   ; address of buttonReleaseCount
			mov   es:[di], bx  ; buttonReleaseCount = bx
			les   di, 16[bp]   ; address of horizontal
			mov   es:[di], cx  ; horizontal = cx
			les   di, 20[bp]   ; address of vertical
			mov   es:[di], dx  ; vertical = dx
			leave
_GetButRel	ENDP
	  

; ****************************************
; *	F U N C T I O N  7  :  
; ****************************************

PUBLIC _SetHorizontalLimits
;
; SetHorizontalLimits (minPos, maxPos)
; int minPos, maxPos;
;

_SetHorizontalLimits PROC FAR
			enter
			mov   cx, 6[bp]    ; cx = minPos
			mov   dx, 8[bp]    ; dx = minPos
			mov   ax, 7	; function 7
			int   33h	  ; call mouse driver function 
			leave
_SetHorizontalLimits ENDP


; ****************************************
; *	F U N C T I O N  8  :  
; ****************************************

PUBLIC _SetVerticalLimits
;
; SetHorizontalLimits (minPos, maxPos)
; int minPos, maxPos;
;

_SetVerticalLimits PROC FAR
			enter
			mov   cx, 6[bp]    ; cx = minPos
			mov   dx, 8[bp]    ; dx = minPos
			mov   ax, 8	; function 8
			int   33h	  ; call mouse driver function 
			leave
_SetVerticalLimits ENDP


; ****************************************
; *	F U N C T I O N  9  :  
; ****************************************

PUBLIC _SetGraphicCursor
;
; typedef struct {
;    unsigned int screenMask[16],
;		 cursorMask[16];
;    int	  hotX,
;		 hotY;
;		} GraphicCursor;
;  
; SetGraphicCursor (cursor)
; GraphicCursor *cursor;
;

_SetGraphicCursor PROC FAR
			enter
			les   di, 6[bp]     ; address of screenMask
			mov   dx, di	; es:dx = address of screenMask
			mov   bx, es:64[di] ; bx = hotX
			mov   cx, es:66[di] ; cx = hotY
			mov   ax, 9	 ; function 9
			int   33h	   ; call mouse driver function 
			leave
_SetGraphicCursor ENDP



; ****************************************
; *	F U N C T I O N  10  : 
; ****************************************

PUBLIC _SetTextCursor
;
; SetTextCursor (selectedCursor, screenMaskORscanStart, cursorMaskORscanStop)
; unsigned int selectedCursor, 
;	      screenMaskORscanStart, 
;	      cursorMaskORscanStop;
;

_SetTextCursor PROC FAR
			enter
			mov   bx, 6[bp]    ; bx = selectedCursor
			mov   cx, 8[bp]    ; cx = screenMaskORscanStart
			mov   dx, 10[bp]   ; dx = cursorMaskORscanStop
			mov   ax, 10       ; function 10
			int   33h	  ; call mouse driver function 
			leave
_SetTextCursor ENDP


; ****************************************
; *	F U N C T I O N  11  : 
; ****************************************

PUBLIC _ReadMotionCounters
;
; ReadMotionCounters ( horizontal, vertical )
; int *horizontal, *vertical;
;

_ReadMotionCounters PROC FAR
			enter
			mov   ax, 11       ; function 11 
			int   33h	  ; call mouse driver function 
			les   di, 6[bp]    ; address of horizontal
			mov   es:[di], cx  ; horizontal = cx
			les   di, 10[bp]   ; address of vertical
			mov   es:[di], dx  ; vertical = dx
			leave
_ReadMotionCounters ENDP


; ****************************************
; *	F U N C T I O N  12  : 
; ****************************************

PUBLIC _SetEventHandler
;
; SetEventHandler (mask, handler)
; int mask;
; int *handler();
;

PrivateHandler PROC FAR

process_event:	      cli	       ; prevent a further interrupt
					  ; which would change registers
					  ; ax, bx, cx, dx

			push	es
			push  ds	  ; save mouse driver ds
			mov   ds, cs:CDataSeg ; set up C data seg

			push  dx	  ; set up params for c function
			push  cx
			push  bx
			push  ax

			sti	       ; enable interrupts

			call cs:hand_ptr
			add  sp, 8

			pop  ds	   ; restore mouse driver ds
			pop	es
			ret
			
hand_ptr	dd	0
			 
PrivateHandler ENDP

_SetEventHandler PROC FAR
			enter
			push  es
			mov   cx, 6[bp]    ; cx = mask
			les   dx, 8[bp]    ; handler
			mov   word ptr hand_ptr[2], es
			mov   word ptr hand_ptr[0], dx
			push  cs
			pop   es
			lea   dx, cs:PrivateHandler
			mov   ax, 12       ; function 12
			int   33h	  ; call mouse driver function 
			pop   es
			leave
_SetEventHandler ENDP

_ClearEventHandler PROC FAR
			enter
			xor	ax,ax
			mov   word ptr cs:hand_ptr[0], ax
			mov   word ptr cs:hand_ptr[2], ax
			mov   dx, ax
			mov   ax, 12       ; function 12
			int   33h	  ; call mouse driver function 
			leave
_ClearEventHandler ENDP



; ****************************************
; *	F U N C T I O N  13  : 
; ****************************************

PUBLIC _LightPenOn
;
; LightPenOn ();
;

_LightPenOn PROC FAR
			enter
			mov   ax, 13       ; function 13
			int   33h	  ; call mouse driver function 
			leave
_LightPenOn ENDP


; ****************************************
; *	F U N C T I O N  14  :
; ****************************************

PUBLIC _LightPenOff
;
; LightPenOff ();
;

_LightPenOff PROC FAR
			enter
			mov   ax, 14	; function 14
			int   33h	  ; call mouse driver function 
			leave
_LightPenOff ENDP


; ****************************************
; *	F U N C T I O N  15  : 
; ****************************************

PUBLIC _SetMickeysPerPixel
;
; SetMickeysPerPixel (horPix, verPix)
; unsigned int horPix, verPix;
;

_SetMickeysPerPixel PROC FAR
			enter
			mov   cx, 6[bp]    ; cx = horPix
			mov   dx, 8[bp]    ; dx = verPix
			mov   ax, 15       ; function 15
			int   33h	  ; call mouse driver function 
			leave
_SetMickeysPerPixel ENDP


; ****************************************
; *	F U N C T I O N  16  : 
; ****************************************

PUBLIC _ConditionalOff
;
; ConditionalOff (left, top, right, bottom)
; int left, top, right, bottom;
;

_ConditionalOff PROC FAR
			enter
			mov   cx,  6[bp]   ; cx = left
			mov   dx,  8[bp]   ; dx = top
			mov   si,  10[bp]  ; si = right
			mov   di,  12[bp]  ; di = bottom
			mov   ax, 16       ; function 16
			int   33h	  ; call mouse driver function 
			leave
_ConditionalOff ENDP			


; ****************************************
; *	F U N C T I O N  19  : 
; ****************************************

PUBLIC _SetSpeedThreshold
;
; SetSpeedThreshold (threshold)
; unsigned int threshold;
;

_SetSpeedThreshold PROC FAR
			enter
			mov   dx, 6[bp]     ; dx = threshold
			mov   ax, 19	; function 19
			int   33h	   ; call mouse driver function 
			leave
_SetSpeedThreshold ENDP

; ****************************************
; *	F U N C T I O N  29  : 
; ****************************************

PUBLIC _SetCRTPage
;
; SetCRTPage(page)
; int page;
;

_SetCRTPage PROC FAR
		enter
		mov	bx,6[bp]	; bx = crt page number
		mov	ax,29		; function 29
		int	33h
		leave
_SetCRTPage ENDP

IBM_TEXT   ENDS
END
