title MSE-2	Basic Mouse Operations
comment+
	This program restricts the mouse pointer to within a display
		rectangle (greenish blue area), and it
		displays continuously the current coordinates
		of the mouse in the top row of the screen.
		You quit the pressing the left mouse button.
	SOURCE:  Adapted by Chee Yap (10/97) from Abel, p.392.
		Modifications:
			-- screen dimensions can be easily changed
			-- save and restore old mode
	HINTS/BUGS:
		-- this program does not clear the screen outside
			the mouse area
		-- in windows NT, the mouse limits does not quite
			work if you remain a window within NT.
			Hence you need to take over the whole screen
			(type ALT-ENTER in the ms-dos window)
		-- in windows 95, there is another way to get the
			mouse limits to work: go to properties menu
			of the MSDOS Prompt Window, choose the
			``misc'' tab, and set the mouse to
			be ``exclusive'' for this window. 
		
end comment+
	.model small
	.stack 100h	; .stack 64 causes me 2 days of debugging!
	.data
xbin	dw	0	; binary x-coord
ybin	dw	0	; binary y-coord
ascval	dw	?	; ascii field
;	screen display fields
dispdata label byte
xmsg	db	'x = '	
xascii	dw	?	; x in ascii
	db	' '
ymsg	db	'y = '
yascii	dw	?	; y in ascii
	db	'$'
;	screen size
nwcorner label word	; north west corner of screen
colmin	db	9	; column 9
rowmin	db	3	; row 3
secorner label word	; south east corner of screen
colmax	db	69d	; column 19
rowmax	db	19d	; row 19
norows	db	17	; number of rows, 19-3+1
;
	.286		
	.code
main	proc far
	mov ax,@data
	mov ds,ax
	; save video mode
	mov ah,0fh
	int 10h
	push ax		; al=curr mode, ah=chars/line
	push bx		; bh=curr page
	;
	call clear	; clear screen
	call init	; init mouse
	cmp ax,00	; mouse installed?
	je exit		; no, exit
again:
	call mseptr	; get mouse ptr location
	cmp bx,01	; button pressed?
	je done		; yes, get out of this loop
	call cursor	; set cursor
	mov ax,xbin
	call conv	; x to ascii
	mov ax,ascval
	mov xascii,ax	; save converted value in xascii
	mov ax,ybin
	call conv	; y to ascii
	mov ax,ascval
	mov yascii,ax	; save converted value in yascii
	call disp	; display x,y values
	jmp again
done:
	call hide	; hide mouse pointer
exit:	call clear	; clear screen
	; restore old mode
	pop bx
	pop ax
	mov ah,0	; fcn=set mode (to old mode)
	int 10h
	mov ax,4c00h
	int 21h
main	endp

;	INIT MOUSE POINTER
;	------------------
init	proc near
	mov ax,00h	; initialize mse function
	int 33h
	cmp ax,00	; mse installed?
	je nomse	; no, exit
	; set mouse x-limits
	mov ax,07h	; fcn=set mouse x-limits (in pixels)
	mov cl,colmin	;
	xor ch,ch	; set cx=8*colmin
	sal cx,3	; multiply by 8 (convert from char-width pixels)
	mov dl,colmax	;
	xor dh,dh	; set dx=8*colmax
	sal dx,3	; multiply by 8
	int 33h
	; set mouse y-limits
	mov ax,08h	; fcn=set mouse 8-limits (in pixels)
	mov cl,rowmin	;
	xor ch,ch	; set cx=8*rowmin
	sal cx,3	; multiply by 8 (convert from chars to pixels)
	mov dl,rowmax	;
	xor dh,dh	; set dx=8*rowmax
	sal dx,3	; multiply by 8
	int 33h
	mov ax,01h	; show mse pointer
	int 33h
nomse:	ret
init	endp

;	GET MOUSE POINTER LOCATION
;	--------------------------
mseptr	proc near
more:	mov ax,03h	; get mse ptr location function
	int 33h
	cmp bx,01	; right button pressed?
	je return	; yes, means return
	shr cx,03	; divide pixel value
	shr dx,03	;    by 8
	cmp cx,xbin	; has ptr location
	jne changed	;    changed?
	cmp dx,ybin
	je more		; if not, repeat
changed: mov xbin,cx	; if yes, save new location
	mov ybin,dx
return: ret
mseptr	endp

;	CONVERT BINARY TO ASCII
;	-----------------------
;	INPUT: ax (in binary), OUTPUT: ascval (in ascii)
conv	proc near	
	mov ascval,2020h ; clear ascii field
	mov cx,10	; set divide factor
	lea si,ascval+1	; load ascval address
	cmp ax,cx	; compare location to 10
	jb lower	; if lower, bypass
	div cl		; if higher, divide by 10
	or ah,30h	; insert ASCII 3s
	mov [si],ah	; store in rightmost byte
	dec si	
lower:	or al,30h	; insert ASCII 3s
	mov [si],al	; store in leftmost byte
	ret
conv	endp

;	HIDE MOUSE POINTER (before ending)
;	----------------------------------
hide	proc near
	mov ax,02h	; hide function
	int 33h
	ret
hide	endp

;	CLEAR SCREEN
;	------------
clear	proc near
	mov ah,06h	; request clear screen 
	mov bh,30h	; colors
	mov cx,nwcorner	; nw corner (3,9)
	mov dx,secorner	; se corner (19,69)
	mov al,norows	; (al=17 rows, which clears screen)
	int 10h
	ret
clear 	endp

;	SET TEXT CURSOR
;	---------------
cursor	proc near
	mov ah,02h	; set cursor position function
	mov bh,0	; page 0
	mov dh,0	; row
	mov dl,25	; col
	int 10h
	ret
cursor	endp

;	DISPLAY MOUSE POSITION
;	----------------------
disp	proc near
	mov ah,40h	; display function
	mov bx,01	; screen handle 01 = Output (normally display)
	mov cx,14	; number of characters
	lea dx,dispdata	; display data
	int 21h
	ret
disp	endp
	end main

