title tMSE-2	Basic Mouse Operations, adapted from Abel, p.392
comment+
	Elaborations of MSE-1 from Abel, p.392
	Added:	-- screen dimensions can be set
		-- save and restore old mode
end comment+
	.model small
; WOW!  This caused me days of debugging.
;	.stack 64 
; this stack (what about 64h?)
;	is just too small, and int 10h, fcn=0, mode 12h
;	causes illegal operation!
	.stack 100h
	.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
;
IF1
	include ..\mac\mymac.lib
ENDIF
	.286
	.code
main	proc far
	initdata
	; save video mode
	mov ah,0fh
	int 10h
	push ax		; al=curr mode, ah=chars/line
	push bx		; bh=curr page
	;
comment+
	display_it 'current mode, AL='
	outhex al
	newline
	display_it 'chars/line, AH='
	outhex ah
	newline
	display_it 'curr page, BH='
	outhex bh
	newline
 	pause 'press any key'
end comment+
	mov ah,0
	mov al,12h
	int 10h		; set video graphics mode 12h
	;
pause 'mode 12h done'
;  jmp _skipall
	;
	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
_skipall:
	restore <bx,ax>
	mov ah,0	; fcn=set mode (to old mode)
	int 10h
	exitdos	; macro
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
;	-----------------------
conv	proc near	; input: ax in binary
	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

