putting together a mouse driven application divide and conquer
Post on 21-Dec-2015
215 views
TRANSCRIPT
Mouse.asm from 5th edition in slide notes
• Data area
INCLUDE Irvine16.inc
.data
ESCkey = 1Bh
GreetingMsg BYTE "Press Esc to quit",0dh,0ah,0
StatusLine BYTE "Left button: "
BYTE "Mouse position: ",0
blanks BYTE " ",0
Xcoordinate WORD 0 ; current X-position
Ycoordinate WORD 0 ; current Y-position
Xclick WORD 0 ; X-pos of last button click
Yclick WORD 0 ; Y-pos of last button click
Driver: call HideCursor
mov dx,OFFSET GreetingMsg
call WriteString
call ShowMousePointer
; Display a status line on line 24.
mov dh,24
mov dl,0
call Gotoxy
mov dx,OFFSET StatusLine
call Writestring
Driver continued; Loop: show mouse coordinates, check for left mouse
; button click, or for a keypress (Esc key).
L1: call ShowMousePosition
call LeftButtonClick ; check for button click
mov ah,11h ; key pressed already?
int 16h
jz L2 ; no, continue the loop
mov ah,10h ; remove key from buffer
int 16h
cmp al,ESCkey ; yes. Is it the ESC key?
je quit ; yes, quit the program
L2: jmp L1 ; no, continue the loop
; Hide the mouse, restore the text cursor, clear
; the screen, and display "Press any key to continue."
quit:
call HideMousePointer
call ShowCursor
call Clrscr
call WaitMsg
HideCursor Show mousepointer procs
;---------------------------------------------------------
HideCursor proc
;
; Hide the text cursor by setting its top line
; value to an illegal value.
;---------------------------------------------------------
mov ah,3 ; get cursor size
int 10h
or ch,30h ; set upper row to illegal value
mov ah,1 ; set cursor size
int 10h
ret
HideCursor ENDP•;---------------------------------------------------------•ShowMousePointer PROC•;---------------------------------------------------------• push ax• mov ax,1 ; make mouse cursor visible• int 33h• pop ax• ret•ShowMousePointer ENDP
Showcursor/Hide mouse pointer procs
ShowCursor PROC
mov ah,3 ; get cursor size
int 10h
mov ah,1 ; set cursor size
mov cx,0607h ; default size
int 10h
ret
ShowCursor ENDP
HideMousePointer PROC
;---------------------------------------------------------
push ax
mov ax,2 ; hide mouse cursor
int 33h
pop ax
ret
HideMousePointer ENDP
GetMousePosition PROC
;---------------------------------------------------------
GetMousePosition PROC
;
; Return the current mouse position and button status.
; Receives: nothing
; Returns: BX = button status (0 = left button down,
; (1 = right button down, 2 = center button down)
; CX = X-coordinate
; DX = Y-coordinate
;---------------------------------------------------------
push ax
mov ax,3
int 33h
pop ax
ret
GetMousePosition ENDP
Left button click proc;---------------------------------------------------------
LeftButtonClick PROC
;
; Check for the most recent click of the left mouse
; button, and display its location.
; Receives: BX = button number (0=left, 1=right, 2=middle)
; Returns: BX = button press counter
; CX = X-coordinate
; DX = Y-coordinate
;---------------------------------------------------------
pusha
mov ah,0 ; get mouse status
mov al,5 ; (button press information)
mov bx,0 ; specify the left button
int 33h
; Exit proc if the coordinates have not changed.
cmp cx,Xclick
jne LBC1
cmp dx,Yclick
je LBC_exit
Left button click continuedLBC1:
; Save the mouse coordinates.
mov Xclick,cx
mov Yclick,dx
; Position the cursor, clear the old numbers.
mov dh,24 ; screen row
mov dl,15 ; screen column
call Gotoxy
push dx
mov dx,OFFSET blanks
call WriteString
pop dx
Left button click last slide; Show the mouse click coordinates.
call Gotoxy
mov ax,Xcoordinate
call WriteDec
mov dl,20 ; screen column
call Gotoxy
mov ax,Ycoordinate
call WriteDec
LBC_exit:
popa
ret
LeftButtonClick ENDP
Set mouse position• ;---------------------------------------------------------• SetMousePosition PROC• ;• ; Set the mouse's position on the screen.• ; Receives: CX = X-coordinate• ; DX = Y-coordinate• ; Returns: nothing• ;---------------------------------------------------------• mov ax,4• int 33h• ret• SetMousePosition ENDP
• ;---------------------------------------------------------
Showmouseposition procShowMousePosition PROC
;
; Get and show the mouse corrdinates at the
; bottom of the screen.
; Receives: nothing
; Returns: nothing
;---------------------------------------------------------
pusha
call GetMousePosition
; Exit proc if the coordinates have not changed.
cmp cx,Xcoordinate
jne SMP1
cmp dx,Ycoordinate
je SMP_exit
Showmouseposition continuedSMP1:
mov Xcoordinate,cx
mov Ycoordinate,dx
; Position the cursor, clear the old numbers.
mov dh,24 ; screen row
mov dl,60 ; screen column
call Gotoxy
push dx
mov dx,OFFSET blanks
call WriteString
pop dx
; Show the mouse coordinates.
call Gotoxy ; (24,60)
mov ax,Xcoordinate
call WriteDec
mov dl,65 ; screen column
call Gotoxy
mov ax,Ycoordinate
call WriteDec
SMP_exit:
popa
ret
ShowMousePosition ENDP
Divide and conquer
• Break the large problem into smaller parts.
• The decomposition should be rational, and facilitate final assembly of the parts, but may not be unique.
Sample decomposition: code each of the following pieces
1. Put a string at a random screen location… erase it when a key is struck and rewrite it elsewhere. Quit on escape key.
2. Cut/paste code from datetime.asm into leftbuttonclick proc in basic mouse program
3. Modify timer output to show time in seconds
4. Modify #3 to show elapsed seconds
5. Modify mouse program to check screen location of click in rows and columns
Printing a string to a random location…and erasing it
• My data area
.data
string byte 'random string',0
len=$-string
blanks byte ' ',0;use to erase string
codemov ax,@datamov ds,axcall clrscr ;;;before the loop clrscrcall randomize ;;;randomize just once
top:mov eax,80-len ;;random column..make sure string will fit on this linecall randomrangemov dl,almov eax,25 ;;random rowcall randomrangemov dh,alpush dx ;;we need to save dx for latercall gotoxymov dx, offset stringcall writestring ;;write original stringmov dl,0ffh ;;see next couple of lines dl=ffh means inputmov ah,6 ;;DOS no echo input
poll: int 21hjz poll ;;zero means no char struck yetcmp al,27 ;;escape char to terminate…does not work as well as text versionje quitpop dxcall gotoxy ;;go back and erase the stringmov dx, offset blankscall writestringjmp top
quit: ;;exit code
Mouse program plus initial timer info
• Paste timer interrupt code (plus output of it) into mouse.asm from chapt 15. Put it down in leftbuttonclick proc
• You’ll have to paste the procs from the datetime program, as well as a proto statement into your new mouse program
• Datetime.asm is in chapter14 examples
Here is datetime from chpt14 (6th ed)
TITLE Display the Date and Time (DateTime.asm)
; This Real-mode program displays the date and time.
; Last update: 06/01/2006
Include Irvine16.inc
Write PROTO char:BYTE
.data
str1 BYTE "Date: ",0
str2 BYTE ", Time: ",0
datetime from chpt14 (6th ed)
.code
main PROC
mov ax,@data
mov ds,ax
; Display the date:
mov dx,OFFSET str1
call WriteString
mov ah,2Ah ; get system date
int 21h
movzx eax,dh ; month
call WriteDec
INVOKE Write,'-'
movzx eax,dl ; day
call WriteDec
INVOKE Write,'-'
movzx eax,cx ; year
call WriteDec
datetime from chpt14 (6th ed)
; Display the time:
mov dx,OFFSET str2
call WriteString
mov ah,2Ch ; get system time
int 21h
movzx eax,ch ; hours
call WritePaddedDec
INVOKE Write,':'
movzx eax,cl ; minutes
call WritePaddedDec
INVOKE Write,':'
movzx eax,dh ; seconds
call WritePaddedDec
call Crlf
exit
main ENDP
Datetime…continued;---------------------------------------------
Write PROC char:BYTE
; Display a single character.
;---------------------------------------------
push eax
push edx
mov ah,2
mov dl,char
int 21h
pop edx
pop eax
ret
Write ENDP
Datetime…continued
;---------------------------------------------
WritePaddedDec PROC
; Display unsigned integer in EAX, padding
; to two digit positions with a leading zero.
;---------------------------------------------
.IF eax < 10
push eax
push edx
mov ah,2
mov dl,'0'
int 21h
pop edx
pop eax
.ENDIF
call WriteDec
ret
WritePaddedDec ENDP
END main
paste code from datetime.asm into left-button-click
; Position the cursor, clear the old numbers.mov dh,24 ; screen rowmov dl,15 ; screen columncall Gotoxypush dxmov dx,OFFSET blankscall WriteStringpop dx
; Show the timer info….this is what I pasted.call Gotoxymov ah,2Ch; get system timeint 21hmovzx eax,ch ; hourscall WritePaddedDecINVOKE Write,':'movzx eax,cl ; minutescall WritePaddedDecINVOKE Write,':'movzx eax,dh ; secondscall WritePaddedDeccall Crlf
;mov ax,Xcoordinate;call WriteDec;mov dl,20 ; screen column;call Gotoxy;mov ax,Ycoordinate;call WriteDec
LBC_exit:poparet
LeftButtonClick ENDP
(DateTime.asm is currently in chapter 14 of text)A gettime proc – convert (h,m,s) into seconds
gettime procmov ah,2Ch ; get system timeint 21hpush dx ;;;save seconds for later recoverymovzx ax,ch ; hoursmul sixtymovzx bx,cl ; minutesadd ax,bxmul sixtypop dxshr dx,8add ax,dx ; get seconds and add them inmov dh,24mov dl,10call gotoxycall WriteDeccall Crlfret
gettime endp
Remove output from gettime proc
gettime procmov ah,2Ch ; get system timeint 21hpush dxmovzx ax,ch ; hoursmul sixtymovzx bx,cl ; minutesadd ax,bxmul sixtypop dxshr dx,8add ax,dx ; seconds
retgettime endp
In main… get time twice and display the difference
call gotoxymov dx, offset stringcall writestringcall gettime ;;get initial timemov oldtime,ax ;;save start of stop watchmov dl,0ffhmov ah,6poll:int 21hjz pollcmp al,1bhje quitpop dxcall gotoxymov dx, offset blankscall writestringcall gettime ;;get elapsed timesub ax,oldtime ;;calculate diffmov dh,24mov dl,10call gotoxycall WriteDec ;;display itcall Crlf
Modify mouse program again
• convert pixels to r/c
• check if mousebutton click (row, col) is close to (row,col) of string
• I used row=px/8 col=py/8 where px and py are mouse coordinates in pixels.
• I simply checked if user was clicking in an arbitrary place and displayed a message for debug purposes
Modifications to leftclick proc: checking for an arbitrary poisition (row=10 col=20)
; Show the mouse click coordinates.call Gotoxymov ax,Xcoordinateshr ax,3mov bx,colsub bx,4cmp ax,bx ;;;column20?jl m2add bx,4cmp ax,bx;;;col25ja m2mov dl,20 ; call Gotoxymov ax,Ycoordinateshr ax,3mov bx,rowsub bx,2cmp ax,bx;;;row 10jl m2add bx,2cmp ax,bxja m2mov dx,offset messagecall writestringjmp lbc_exit
m2: mov dx,offset outsidemessage
call writestringLBC_exit: