Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;===*===*===*===*===*===*===
- ; Assembly 8086 project
- ; 10th grade, Gvahim project
- ; Author: Daniel Monastirski
- ;===*===*===*===*===*===*===
- .model small
- .stack 100h
- .386
- ;Note: the functions multiply and divide can only work on integers.
- ; -12.2+3.5 DOES NOT WORK
- ;The function divide does show the result including the fraction.
- _resetScreen MACRO
- mov [calcColor], 30
- lea si, RectCoords
- add si, 8
- push si
- call drawRect
- ENDM
- _callAnsPrint MACRO n, position
- push n ;bp+8
- push offset ans ;bp+6
- push offset position ;bp+4
- call printAns
- ENDM
- _drawDigitRect MACRO n
- add si, n
- push si
- call drawRect
- ENDM
- _callCalculatingFunc MACRO func
- lea si, ansFloat
- inc si
- push si
- push offset oprnd2float
- push offset oprnd1float
- call func
- push offset ansInt
- push offset oprnd2intgr
- push offset oprnd1intgr
- call func
- jmp printResult
- ENDM
- _compareTwoArrays MACRO arr1, arr2
- push offset arr2
- push offset arr1
- call compare
- ENDM
- _callDrawRectangle MACRO LocationArray
- push locationArray
- call drawRect
- ENDM
- .data
- oprndInput1 db 10 dup (10) ;raw input from user
- oprndInput2 db 10 dup (10) ;raw input from user
- oprnd1intgr db 10 dup (0) ;Before the dot of oprnd1
- oprnd1float db 10 dup (0) ;After the dot of oprnd1. Recives '0' if oprnd1 is an integer.
- oprnd2intgr db 10 dup (0) ;Before the dot of oprnd2
- oprnd2float db 10 dup (0) ;After the dot of oprnd2. Recives '0' if oprnd2 is an integer.
- ans db 10 dup (0)
- ansInt db 10 dup (0)
- ansFloat db 2Eh,0,0,0,0,0,0,0,0,0
- temp db 10 dup (0)
- operator db 0
- sign db 0
- calcX dw 60
- calcY dw 10
- calcColor db 7
- counter db 0
- ;rectangles array:minX, minY, maxX,maxY.contains the values of 26 rectangles: gray background, screen, 24 buttons.
- RectCoords dw 10,10,310,190, 15,15,305,45 ;Gray background and the calculator screen.
- dw 15,50,60,80, 64,50,109,80, 113,50,158,80, 162,50,256,80, 260,50,305,80
- dw 15,85,60,115, 64,85,109,115, 113,85,158,115, 162,85,207,115, 211,85,256,115, 260,85,305,115
- dw 15,120,60,150, 64,120,109,150, 113,120,158,150, 162,120,207,150, 211,120,256,150, 260,120,305,150
- dw 15,155,60,185, 64,155,109,185, 113,155,158,185, 162,155,207,185, 211,155,256,185, 260,155,305,185
- button9 dw 128,55,143,59, 139,59,143,75, 128,55,133,67, 128,63,143,67, 128,71,143,75
- button8 dw 79,55,94,59, 91,58,94,75, 79,63,94,67, 79,71,94,75, 79,58,83,75
- button7 dw 30,55,45,59, 41,59,45,75
- button6 dw 128,90,143,94, 128,90,132,110, 128,98,143,102, 128,106,143,110, 139,98,143,110
- button5 dw 79,90,94,94, 79,98,94,102, 79,106,94,110, 79,90,84,98, 90,102,94,110
- button4 dw 41,90,45,110, 30,98,45,102, 30,90,34,98
- button3 dw 128,125,143,129, 139,125,143,145, 128,133,143,137, 128,141,143,145
- button2 dw 79,125,94,129, 79,133,94,137, 79,141,94,145, 90,125,94,137, 79,133,83,145
- button1 dw 41,125,45,145
- button0 dw 41,160,45,180, 30,160,34,180, 30,160,45,164, 30,176,45,180
- buttonDot dw 90,176,94,180
- buttonSqr dw 134,160,139,165, 128,165,133,170, 140,165,145,170
- buttonPlu dw 174,132,195,138, 182,125,187,145
- buttonMin dw 223,132,244,138
- buttonMul dw 172,90,177,94, 177,94,182,98, 182,98,187,102, 187,102,192,106, 192,106,197,110, 172,106,177,110, 177,102,182,106, 187,94,192,98, 192,90,197,94
- buttonDiv dw 223,97,244,103, 231,90,236,94, 231,107,236,111
- buttonEqu dw 223,162,244,167, 223,173,244,178
- buttonFac dw 182,160,187,172, 182,175,187,180
- buttonDel dw 165,55,168,75, 165,55,173,58, 165,72,173,75, 173,58,176,72 ;D
- dw 180,55,183,75, 180,55,191,58, 180,63,191,67, 180,72,191,75 ;E
- dw 195,55,198,75, 195,72,206,75 ;L
- dw 210,55,213,75, 210,55,221,58, 210,63,221,67, 210,72,221,75 ;E
- dw 225,55,238,58, 230,55,233,75 ;T
- dw 242,55,245,75, 242,55,253,58, 242,63,253,67, 242,72,253,75 ;E
- buttonCos dw 263,58,266,72, 266,55,274,58, 266,72,274,75 ;C
- dw 277,58,280,72, 277,55,288,58, 277,72,288,75, 285,58,288,72 ;O
- dw 291,55,302,59, 291,55,294,63, 291,63,302,67, 299,63,302,75, 291,71,302,75 ;S
- buttonSin dw 263,90,274,94, 263,90,266,99, 263,98,274,102, 271,98,274,110, 263,106,274,110 ;S
- dw 278,90,282,94, 278,98,282,110 ;I
- dw 286,90,289,110, 289,93,292,96, 292,90,299,93, 299,93,302,110 ;N
- buttonTan dw 263,130,274,133, 267,125,270,142, 269,142,274,145 ;T
- dw 280,125,286,128, 285,128,288,145, 280,132,286,135, 277,134,280,142, 279,142,288,145 ;A
- dw 291,125,294,145, 291,127,296,129, 296,125,300,127, 299,127,302,145 ;N
- buttonCot dw 263,163,266,177, 266,160,274,163, 266,177,274,180 ;C
- dw 277,163,280,177, 277,160,288,163, 277,177,288,180, 285,163,288,177 ;O
- dw 291,165,302,168, 295,160,298,177, 297,177,302,180 ;T
- ;Screen display positions. order: up-mid-down-topleft-topright-bottomleft-bottomright-dot. Every row = 32 words = 64 bytes.
- pos0 dw 23,20,45,24, 23,28,45,32, 23,36,45,40, 23,20,26,30, 42,20,45,30, 23,30,26,40, 42,30,45,40, 42,37,45,40
- pos1 dw 51,20,73,24, 51,28,73,32, 51,36,73,40, 51,20,54,30, 70,20,73,30, 51,30,54,40, 70,30,73,40, 70,37,73,40
- pos2 dw 79,20,101,24, 79,28,101,32, 79,36,101,40, 79,20,82,30, 98,20,101,30, 79,30,82,40, 98,30,101,40, 98,37,101,40
- pos3 dw 107,20,129,24, 107,28,129,32, 107,36,129,40, 107,20,110,30, 126,20,129,30, 107,30,110,40, 126,30,129,40, 126,37,129,40
- pos4 dw 135,20,157,24, 135,28,157,32, 135,36,157,40, 135,20,138,30, 154,20,157,30, 135,30,138,40, 154,30,157,40, 154,37,157,40
- pos5 dw 163,20,185,24, 163,28,185,32, 163,36,185,40, 163,20,166,30, 182,20,185,30, 163,30,166,40, 182,30,185,40, 182,37,185,40
- pos6 dw 191,20,213,24, 191,28,213,32, 191,36,213,40, 191,20,194,30, 210,20,213,30, 191,30,194,40, 210,30,213,40, 210,37,213,40
- pos7 dw 219,20,241,24, 219,28,241,32, 219,36,241,40, 219,20,222,30, 238,20,241,30, 219,30,222,40, 238,30,241,40, 238,37,241,40
- pos8 dw 247,20,269,24, 247,28,269,32, 247,36,269,40, 247,20,250,30, 266,20,269,30, 247,30,250,40, 266,30,269,40, 266,37,269,40
- pos9 dw 275,20,297,24, 275,28,297,32, 275,36,297,40, 275,20,278,30, 294,20,297,30, 275,30,278,40, 294,30,297,40, 294,37,297,40
- diagonal1 dw 69,38,73,40, 67,35,71,37, 65,32,69,34
- diagonal2 dw 97,38,101,40, 95,35,99,37, 93,32,97,34
- diagonal3 dw 153,38,157,40, 151,35,155,37, 149,32,153,34
- ;Flags:
- swappedArrays db 0 ;If oprndInput2 is bigger than oprndInput1, value changes
- usedClick db 0 ;If the mouse click was on a button, value changes
- operatorFlag db 0 ;If the first operand is less than 10 digits long, value changes
- equalsFlag db 0 ;If the second operand is less than 10 digits long, value changes
- shortNumFlag db 0 ;If the int part of ans has filler 0's to be 10 digits long, value changes.
- oprnd1NegFlag db 0 ;If Operand1 is negative, value changes
- .code
- START:
- mov ax,@data
- mov ds, ax
- ;Setting to graphic mode
- mov ax, 13h
- int 10h
- begin:
- mov [usedClick], 0
- mov [operator], 0
- call drawCalc
- mov ax,0h ;Resetting mouse port
- int 33h
- mov ax,1h ;Showing the mouse on the screen
- int 33h
- lea di, oprndInput1
- mov [operator], 0
- click1:
- lea si, pos0
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0 ;checking if the user clicked on an area that is not a button.
- je click1
- mov [usedClick], 0
- inc di
- click2:
- lea si, pos1
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click3:lea si, pos2
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click4:
- lea si, pos3
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click5:
- lea si, pos4
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click6:
- lea si, pos5
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click7:
- lea si, pos6
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click8:
- lea si, pos7
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click9:
- lea si, pos8
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- click10:
- lea si, pos9
- push di
- push si
- call clickHandler1
- cmp [usedClick], 0
- je click2
- cmp [operator], 'R'
- je begin
- cmp [operator], 'P'
- je equationReady
- cmp [operator], 0
- jne operandII
- mov [usedClick], 0
- inc di
- operatorHere:
- call CheckLeftClick
- shr cx,1
- mov [calcColor], 19
- call pressPlus
- call pressMinus
- call pressMultiply
- call pressDivide
- call pressDELETE
- call pressPow
- call CheckReleaseClick
- cmp [operator], 0
- je operatorHere
- operandII:lea di, oprndInput2
- click11:
- lea si, pos0
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click11
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click12:
- lea si, pos1
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click12
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click13:
- lea si, pos2
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click13
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click14:
- lea si, pos3
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click14
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click15:
- lea si, pos4
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click15
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click16:
- lea si, pos5
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click16
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click17:
- lea si, pos6
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click17
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click18:
- lea si, pos7
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click18
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click19:
- lea si, pos8
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click19
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- click20:
- lea si, pos9
- push di
- push si
- call clickHandler2
- cmp [usedClick], 0
- je click20
- cmp [operator], 'R'
- je begin
- cmp [equalsFlag], 1
- je equationReady
- mov [usedClick], 0
- inc di
- equationReady:
- xor bx, bx
- push offset RectCoords
- call drawCalc
- ;Seperating the input operands into an integer part and a float part, for easier calculation
- push offset oprndInput1
- push offset oprnd1float
- push offset oprnd1intgr
- call dotCheck
- push offset oprndInput2
- push offset oprnd2float
- push offset oprnd2intgr
- call dotCheck
- ;Checking what operator was chosen and calling the correct function.
- PLUSCHECK: cmp [operator], '+'
- jne MINUSCHECK
- cmp [oprnd1NegFlag], 1
- jne prepareForPlus
- ;If the first operand is negative and |num1| < num2, call minus to calculate oprnd2 -oprnd1
- _compareTwoArrays oprnd1intgr, oprnd2intgr
- cmp [swappedArrays], 1
- je resultNeg1
- _compareTwoArrays oprnd1float, oprnd2float
- cmp [swappedArrays], 1
- je resultNeg1
- ;If the first num is negative but |num1| > num2
- mov [sign], 1
- _callCalculatingFunc minus
- resultNeg1:
- lea si, ansFloat
- inc si
- push si
- push offset oprnd1float
- push offset oprnd2float
- call minus
- push offset ansInt
- push offset oprnd1intgr
- push offset oprnd2intgr
- call minus
- jmp printResult
- prepareForPlus: _callCalculatingFunc plus
- MINUSCHECK: cmp [operator], '-'
- jne MULTICHECK
- ;Checking if the first num is negative.
- cmp [oprnd1NegFlag], 1
- jne CheckAbiggerThanB
- mov [oprnd1NegFlag], 0
- mov [sign], 1
- _callCalculatingFunc plus
- ;Checking if the first num is smaller than the 2nd num.
- CheckAbiggerThanB:
- _compareTwoArrays oprnd1intgr, oprnd2intgr
- cmp [swappedArrays], 1
- je resultNeg
- _callCalculatingFunc minus
- resultNeg:
- mov [sign], 1
- lea si, ansFloat
- inc si
- push si
- push offset oprnd1float
- push offset oprnd2float
- call minus
- push offset ansInt
- push offset oprnd1intgr
- push offset oprnd2intgr
- call minus
- MULTICHECK: cmp [operator], '*'
- jne DIVCHECK
- mov al, [oprnd1NegFlag]
- mov [sign], al
- xor ax,ax
- xor cx,cx
- push offset ansInt
- push offset oprnd2intgr
- push offset oprnd1intgr
- call multiply
- jmp printResult
- DIVCHECK: cmp [operator], '/'
- jne FACTCHECK
- mov al, [oprnd1NegFlag]
- mov [sign], al
- push offset temp
- call resetArray
- _compareTwoArrays oprnd2intgr, temp ;If the user tried to divide by 0, display error message.
- cmp [swappedArrays], 0
- jne divisionOk
- call errorsHandler
- jmp programFinished
- divisionOk:
- push offset oprnd2intgr
- push offset oprnd1intgr
- call divide
- jmp printResult
- FACTCHECK: cmp [operator], '!'
- jne COSCHECK
- COSCHECK: cmp [operator], 'C'
- jne SINCHECK
- SINCHECK: cmp [operator], 'S'
- jne TANCHECK
- TANCHECK: cmp [operator], 'T'
- jne COTCHECK
- COTCHECK: cmp [operator], 't' ; Or - Do we need cot?
- jne SQRCHECK
- SQRCHECK: cmp [operator], 'P'
- jne printResult
- push offset ansInt
- push offset oprnd1intgr
- call square
- ;Printing the answer, digit by digit, using a macro
- printResult:
- mov [calcColor], 0
- call createAnswerArray
- _callAnsPrint 0, pos0
- _callAnsPrint 1, pos1
- _callAnsPrint 2, pos2
- _callAnsPrint 3, pos3
- _callAnsPrint 4, pos4
- _callAnsPrint 5, pos5
- _callAnsPrint 6, pos6
- _callAnsPrint 7, pos7
- _callAnsPrint 8, pos8
- _callAnsPrint 9, pos9
- programFinished:
- mov ah,00h ;wait for input
- int 16h
- mov ah, 0 ;Return to text mode
- mov al, 2
- int 10h
- .exit
- clickHandler1 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- mov di, [bp+6]
- call CheckLeftClick
- shr cx,1
- mov [calcColor], 0
- push di
- push si
- call checkPressedNumButton
- call pressDELETE
- ;Checking for operators
- call pressMinus
- mov [calcColor], 19
- call pressPlus
- call pressMultiply
- call pressDivide
- call pressPow
- call CheckReleaseClick
- pop bp
- ret
- clickHandler1 endp
- clickHandler2 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- mov di, [bp+6]
- call CheckLeftClick
- shr cx,1
- mov [calcColor], 0
- push di
- push si
- call checkPressedNumButton ;After entering the first number and operator, the only legal available buttons are the numbers, the reset, and the equals buttons.
- call pressDELETE
- call pressEquals
- call CheckReleaseClick
- pop bp
- ret
- clickHandler2 endp
- ;Function waits for the mouse to be clicked. Allows user input.
- CheckLeftClick proc
- MouseLP:
- mov ax,3h
- int 33h
- cmp bx, 00000001b ; check left mouse click
- jne MouseLP
- ret
- CheckLeftClick endp
- ;Function waits for the mouse to be released. Allows user input.
- CheckReleaseClick proc
- ReleaseLP:
- mov ax, 3h
- int 33h
- cmp bx, 00000000b
- jne ReleaseLP
- ret
- CheckReleaseClick endp
- ;Function handling operator +
- ;Input: the offsets of the arrays oprndInput1,oprndInput2,ansInt
- plus proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- mov di, [bp+6]
- mov bx, [bp+8]
- add si, 9
- add di, 9
- add bx, 9
- digitSum:
- mov al,[si]
- add al,[di]
- add al,ah
- xor ah,ah
- overflow:
- cmp al,10
- jl okayP
- inc ah
- sub al,10
- jmp overflow
- okayP:
- mov [bx],al
- dec si ;every iteration, the registers will point toward the arrays offsets
- dec di
- dec bx
- cmp bx, [bp+8]
- jge digitSum
- AdditionDone:
- pop bp
- ret 6
- plus endp
- ;function handling si - di => bx
- ;Input: the offsets of the arrays oprndInput1,oprndInput2,ansInt
- minus proc
- push bp
- mov bp,sp
- mov si, [bp+4]
- mov di, [bp+6]
- mov bx, [bp+8]
- add si, 9
- add di, 9
- add bx, 9
- mov cx, 10
- digitSub:
- mov al,[si]
- sub al,[di]
- sub al,ah
- xor ah,ah
- overflowMin:
- cmp al,0
- jge okMin
- inc ah
- add al,10
- jmp overflowMin
- okMin:
- mov [bx],al
- dec si
- dec di
- dec bx
- loop digitSub
- minusComplete:
- pop bp
- ret 6
- minus endp
- ;function handling operator *
- ;Input: the offsets of 3 arrays.
- ;Output: Result of multiplication of the first 2 arrays, saved in the 3rd array
- multiply proc
- push bp
- mov bp,sp
- mov di, [bp+4] ;oprnd1
- mov si, [bp+6] ;oprnd2
- mov bx, [bp+8]
- add di, 9
- xor cx,cx
- xor ax,ax
- multi:
- mov cl, byte ptr[di]
- cmp cx, 0
- je prepareTemp
- oprndDigitLoop: ;representing multiplication by adding n to itself m times, and saving the result in temp
- ;adding [si] to temp cx times
- push bx
- push si
- push di
- push offset temp
- push si
- push offset temp
- call plus
- pop di
- pop si
- pop bx
- loop oprndDigitLoop
- prepareTemp:
- push si
- mov si, offset counter
- mov cl, [si]
- cmp cx, 0
- je copyTmp
- xor ax,ax
- shiftTemp:
- mov si, offset temp
- add si, 9
- mov al, [si]
- mov [si], byte ptr 0
- dec si
- shiftLeft:
- mov ah, [si] ;Saving the value in ah
- mov [si], al ;[si] will recieve the value of [si-1]
- dec si
- mov al, ah
- cmp si, offset temp
- jge shiftLeft
- loop shiftTemp
- ;copying the result from temp and adding it to the answer array
- copyTmp:
- pop si
- push bx
- push si
- push di
- push bx
- push bx
- push offset temp
- call plus
- ;Resetting temp for future use.
- push offset temp
- call resetArray
- pop di
- pop si
- pop bx
- nothingToMul:
- dec di
- inc [counter]
- cmp [counter], 10
- jle multi
- pop bp
- ret 6
- multiply endp
- ;Function handling operator /
- ;Input: The offsets of the arrays oprndInput1,oprndInput2,ansInt. [remainder is in dx]
- divide proc
- push bp
- mov bp,sp
- push offset temp
- call resetArray
- mov bx, offset temp
- add bx, 9
- mov [bx], byte ptr 1
- mov [counter], 0
- findIntDiv: ;Checking how many times oprnd2 can fit inside oprnd1.
- mov si, [bp+4]
- mov di, [bp+6]
- push di
- push si
- call compare
- cmp [swappedArrays], 1
- je continueDiv
- push offset ansInt
- push offset temp
- push offset ansInt
- call plus ;Adding 1 to the result
- mov si, [bp+4]
- mov di, [bp+6]
- push si
- push di
- push si
- call minus ;calculating SI-DI => SI
- jmp findIntDiv
- continueDiv:
- push offset temp
- call resetArray
- inc [counter]
- mov bx, offset temp
- mov [bx], byte ptr 1
- lea bx, ansFloat
- add bl, [counter]
- mov si, [bp+4]
- add si, 9
- mov al, [si]
- mov [si], byte ptr 0
- dec si
- mov cx, 9
- shiftRemainder:
- mov ah, [si] ;Saving the value in ah
- mov [si], al ;[si] will recieve the value of [si-1]
- dec si
- mov al, ah
- loop shiftRemainder
- findRemainder: ;Checking how many times oprnd2 can fit inside oprnd1.
- mov si, [bp+4]
- mov di, [bp+6]
- push di
- push si
- call compare
- cmp [swappedArrays], 1
- je divDone
- push bx
- mov si, bx
- push bx
- push offset temp
- push si
- call plus ;Adding 1 to the result
- mov si, [bp+4]
- mov di, [bp+6]
- push si
- push di
- push si
- call minus
- pop bx
- jmp findRemainder
- divDone:
- cmp [counter],9
- jle continueDiv
- pop bp
- ret 4
- divide endp
- ;Function calculates oprndInput1 to the power of 2.
- square proc
- push bp
- mov bp,sp
- mov di,[bp+4]
- mov bx, [bp+6]
- push bx
- push di
- push di
- call multiply
- pop bp
- ret 4
- square endp
- ;Function resets all program variables that have changed during run time.
- programReset proc
- lea di, oprndInput1
- mov cx, 10
- oprndInput1Loop:
- mov byte ptr[di], 10
- inc di
- loop oprndInput1Loop
- lea di, oprndInput2
- mov cx, 10
- oprndInput2Loop:
- mov byte ptr[di], 10
- inc di
- loop oprndInput2Loop
- push offset oprnd1intgr
- call resetArray
- push offset oprnd1float
- call resetArray
- push offset oprnd2intgr
- call resetArray
- push offset oprnd2float
- call resetArray
- push offset ansInt
- call resetArray
- lea si, ansFloat
- mov byte ptr [si], 2Eh
- inc si
- push si
- call resetArray
- push offset temp
- call resetArray
- ;Resetting flag values
- mov [usedClick], 1
- mov [operatorFlag], 0
- mov [equalsFlag], 0
- mov [operator], 'R' ;Using the operator variable to notify the program the restart function was called.
- mov [sign], 0
- ret
- programReset endp
- ;Function checks if an array has a decimal point and breaks it to 2 different arrays.
- ;Input: The offsets of the original operand array, an array for the integer part, and an array for the float part.
- ;Output: An integer part and a float part, in 2 different arrays.
- dotCheck proc
- push bp
- mov bp, sp
- mov si, [bp+4] ;integer array
- mov di, [bp+6] ;float array
- mov bx, [bp+8] ;original input array
- add si, 9
- mov cx, 10 ;counter
- checkForDot: ;Searching the array to find if the number is an integer or not.
- mov al, [byte ptr bx]
- cmp al, 2Eh
- je numIsFloat ;If one of the values in the array is 2Eh, the number is not an integer.
- inc bx
- loop checkForDot
- jmp numIsInt ;If the loop ended and did not jump to numIsFloat, the number is an int.
- numIsFloat: ;Starting from the dot, copying the rest of the array to the float array.
- inc bx
- mov al, [bx]
- push cx
- dec cx
- floatLoop:
- cmp al, 10
- je prepareForInt
- numStartsHere: mov [di], al
- inc bx
- inc di
- inc dx ;counter
- mov al, [bx] ;checking if the array is a number that's not 10 digits long.
- loop floatLoop
- prepareForInt:
- mov bx, [bp+8]
- pop cx
- inc cx
- mov dx, 10
- sub dx, cx
- add bx, dx
- xor dx, dx
- jmp intLoop
- numIsInt:
- mov bx, [bp+8]
- add bx, 9
- intLoop:
- mov al, [bx]
- cmp al, 10
- je notGoodDigit
- mov [si], al
- dec si
- notGoodDigit:
- dec bx
- cmp bx, [bp+8]
- jge intLoop
- pop bp
- ret 6
- dotCheck endp
- ;Function compares the values of 2 arrays and puts into si the offset bigger array and into di the other
- ;Input: the offsets of the two arrays
- ;Output: SI pointing to the array representing the bigger number, and DI to the other.
- ; the variable swappedArrays will contain 0 if the arrays are equal, -1 if the first one is bigger, and 1 if the second array is bigger.
- compare proc
- push bp
- mov bp,sp
- mov si, [bp+4]
- mov di, [bp+6]
- mov [swappedArrays], 0
- mov cx,10
- chk:
- mov al, [si]
- cmp al,[di] ;if si and di are equal
- je contChk
- cmp al,[di]
- jg bigger
- smaller:
- mov [swappedArrays], 1
- jmp checkCompleted
- bigger:
- mov [swappedArrays], -1
- contChk:
- inc si
- inc di
- cmp [swappedArrays], 0
- jne checkCompleted
- loop chk
- checkCompleted:
- cmp [swappedArrays],0
- jle nochange
- mov si, [bp+6]
- mov di, [bp+4]
- jmp cont
- nochange:
- mov si, [bp+4]
- mov di, [bp+6]
- cont:
- pop bp
- ret 4
- compare endp
- ;Function changes the values of an array to the same value
- ;Input: the offset of the array and the value
- resetArray proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- mov cx, 10
- reset:
- mov byte ptr[si], 0
- inc si
- loop reset
- pop bp
- ret 2
- resetArray endp
- ;Function handles the setting of the rectangle coloring.
- ;Input: none.
- drawCalc proc
- lea si, RectCoords
- mov [calcColor], 29h
- xor bx,bx
- buttonsLoop:
- cmp bx, 0
- jne screenCheck
- mov [calcColor], 20 ;gray background
- jmp print
- screenCheck:
- cmp bx, 1
- jne delCheck
- mov [calcColor], 30 ;screen
- jmp print
- delCheck:
- cmp bx, 5
- jne normal
- mov [calcColor], 43 ;DEL button
- jmp print
- normal:
- mov [calcColor], 29h ;all other buttons.
- print:
- _callDrawRectangle si
- add si, 8
- inc bx
- cmp bx, 25
- jl buttonsLoop
- mov [calcColor], 0
- lea si, button9
- mov bx, 0
- symbolLoop: ;button symbols.
- _callDrawRectangle si
- add si, 8
- inc bx
- cmp bx, 127
- jl symbolLoop
- ret
- drawCalc endp
- ;Function draws a rectangle.
- ;input: an array containing the values minX,minY,maxX,maxY. color is set outside of the function.
- drawRect proc
- push bp
- mov bp, sp
- push ax
- push cx
- mov si, [bp+4]
- mov ax, [si]
- mov [calcX],ax
- button:
- mov si, [bp+4]
- add si, 2
- mov ax, [si]
- sub si, 2
- mov [calcY],ax
- bRow:
- mov cx, [calcX]
- mov dx, [calcY]
- mov al, [calcColor]
- mov ah, 0ch
- int 10h
- inc[calcY]
- add si, 6
- mov ax, [si]
- sub si, 6
- cmp [calcY], ax
- jbe bRow
- inc [calcX]
- add si, 4
- mov ax, [si]
- sub si, 4
- cmp [calcX], ax
- jbe button
- pop cx
- pop ax
- pop bp
- ret 2
- drawRect endp
- ;Function checks which numeric button was pressed.
- ;Input: The offsets of the current operand array and the screen position.
- ;Output: The operand recieves the correct character, and it is printed on the screen.
- checkPressedNumButton proc
- push bp
- mov bp, sp
- pressDot:
- cmp cx, 64
- jl press0
- cmp cx, 109
- jg press0
- cmp dx, 155
- jl press0
- cmp dx, 185
- jg press0
- mov di, [bp+6]
- mov bl, 2Eh
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call drawDot
- jmp pressDone
- press0:
- cmp cx, 15
- jl press1
- cmp cx, 60
- jg press1
- cmp dx, 155
- jl press1
- cmp dx, 185
- jg press1
- mov di, [bp+6]
- mov bl, 0
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw0
- jmp pressDone
- press1:
- cmp cx, 15
- jl press2
- cmp cx, 60
- jg press2
- cmp dx, 120
- jl press2
- cmp dx, 150
- jg press2
- mov di, [bp+6]
- mov bl, 1
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw1
- jmp pressDone
- press2:
- cmp cx, 64
- jl press3
- cmp cx, 109
- jg press3
- cmp dx, 120
- jl press3
- cmp dx, 150
- jg press3
- mov di, [bp+6]
- mov bl, 2
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw2
- jmp pressDone
- press3:
- cmp cx, 113
- jl press4
- cmp cx, 158
- jg press4
- cmp dx, 120
- jl press4
- cmp dx, 150
- jg press4
- mov di, [bp+6]
- mov bl, 3
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw3
- jmp pressDone
- press4:
- cmp cx, 15
- jl press5
- cmp cx, 60
- jg press5
- cmp dx, 85
- jl press5
- cmp dx, 115
- jg press5
- mov di, [bp+6]
- mov bl, 4
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw4
- jmp pressDone
- press5:
- cmp cx, 64
- jl press6
- cmp cx, 109
- jg press6
- cmp dx, 85
- jl press6
- cmp dx, 115
- jg press6
- mov di, [bp+6]
- mov bl, 5
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw5
- jmp pressDone
- press6:
- cmp cx, 113
- jl press7
- cmp cx, 158
- jg press7
- cmp dx, 85
- jl press7
- cmp dx, 115
- jg press7
- mov di, [bp+6]
- mov bl, 6
- mov [di], bl
- mov [usedClick], 1
- mov si, [bp+4]
- push si
- call draw6
- jmp pressDone
- press7:
- cmp cx, 15
- jl press8
- cmp cx, 60
- jg press8
- cmp dx, 50
- jl press8
- cmp dx, 80
- jg press8
- mov [usedClick], 1
- mov di, [bp+6]
- mov bl, 7
- mov [di], bl
- mov si, [bp+4]
- push si
- call draw7
- jmp pressDone
- press8:
- cmp cx, 64
- jl press9
- cmp cx, 109
- jg press9
- cmp dx, 50
- jl press9
- cmp dx, 80
- jg press9
- mov [usedClick], 1
- mov di, [bp+6]
- mov bl, 8
- mov [di], bl
- mov si, [bp+4]
- push si
- call draw8
- jmp pressDone
- press9:
- cmp cx, 113
- jl pressDone
- cmp cx, 158
- jg pressDone
- cmp dx, 50
- jl pressDone
- cmp dx, 80
- jg pressDone
- mov [usedClick], 1
- mov di, [bp+6]
- mov bl, 9
- mov [di], bl
- mov si, [bp+4]
- push si
- call draw9
- pressDone:
- pop bp
- ret 4
- checkPressedNumButton endp
- ;Function checks if user pressed the delete button.
- ;Input: The cursor location, saved in CX and DX.
- ;Output: If the function confirms the user clicked on the delete button, it calls the reset function.
- pressDELETE proc
- cmp cx, 162
- jl noAC
- cmp cx, 256
- jg noAC
- cmp dx, 50
- jl noAC
- cmp dx, 80
- jg noAC
- call programReset
- noAC: ret
- pressDELETE endp
- ;The function draws the digit 9 on the screen.
- ;Input: Screen position
- ;Output: The digit 9 is printed on screen.
- draw9 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- xor bx,bx
- yes9:
- _callDrawRectangle si
- add si, 8
- inc bx
- cmp bx,4
- jle yes9
- add si, 8
- _callDrawRectangle si
- pop bp
- ret 2
- draw9 endp
- ;The function draws the digit 8 on the screen.
- ;Input: Screen position
- ;Output: The digit 8 is printed on screen.
- draw8 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- xor bx,bx
- yes8:
- _callDrawRectangle si
- add si, 8
- inc bx
- cmp bx,6
- jle yes8
- pop bp
- ret 2
- draw8 endp
- ;The function draws the digit 7 on the screen.
- ;Input: Screen position
- ;Output: The digit 7 is printed on screen.
- draw7 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si, 32
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- pop bp
- ret 2
- draw7 endp
- ;The function draws the digit 6 on the screen.
- ;Input: Screen position
- ;Output: The digit 6 is printed on screen.
- draw6 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- pop bp
- ret 2
- draw6 endp
- ;The function draws the digit 5 on the screen.
- ;Input: Screen position
- ;Output: The digit 5 is printed on screen.
- draw5 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 24
- _callDrawRectangle si
- pop bp
- ret 2
- draw5 endp
- ;The function draws the digit 4 on the screen.
- ;Input: Screen position
- ;Output: The digit 4 is printed on screen.
- draw4 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- pop bp
- ret 2
- draw4 endp
- ;The function draws the digit 3 on the screen.
- ;Input: Screen position
- ;Output: The digit 3 is printed on screen.
- draw3 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- pop bp
- ret 2
- draw3 endp
- ;The function draws the digit 2 on the screen.
- ;Input: Screen position
- ;Output: The digit 2 is printed on screen.
- draw2 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- pop bp
- ret 2
- draw2 endp
- ;The function draws the digit 1 on the screen.
- ;Input: Screen position
- ;Output: The digit 1 is printed on screen.
- draw1 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- add si,32
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- pop bp
- ret 2
- draw1 endp
- ;The function draws the digit 0 on the screen.
- ;Input: Screen position
- ;Output: The digit 0 is printed on screen.
- draw0 proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- _callDrawRectangle si
- add si,16
- xor bx,bx
- yes0:
- _callDrawRectangle si
- add si, 8
- inc bx
- cmp bx,5
- jle yes0
- pop bp
- ret 2
- draw0 endp
- ;The function draws a decimal dot on the screen.
- ;Input: Screen position
- ;Output: The character '.' is printed on screen.
- drawDot proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- add si, 56
- _callDrawRectangle si
- pop bp
- ret 2
- drawDot endp
- ;The function draws the negative sign on the screen.
- ;Input: Screen position
- ;Output: The negative sign is printed on screen.
- drawNeg proc
- push bp
- mov bp, sp
- mov si, [bp+4]
- add si, 8
- _callDrawRectangle si
- pop bp
- ret 2
- drawNeg endp
- ;******************************************************************
- pressPow proc
- cmp cx, 113
- jl noPow
- cmp cx, 158
- jg noPow
- cmp dx, 155
- jl noPow
- cmp dx, 185
- jg noPow
- lea si, buttonSqr
- _callDrawRectangle si
- add si,8
- _callDrawRectangle si
- add si,8
- _callDrawRectangle si
- mov [usedClick], 1
- mov [operatorFlag], 1
- mov[operator], 'P'
- noPow:
- ret
- pressPow endp
- pressPlus proc
- cmp cx, 162
- jl noPl
- cmp cx, 207
- jg noPl
- cmp dx, 120
- jl noPl
- cmp dx, 150
- jg noPl
- lea si, buttonPlu
- xor bx,bx
- yesPl:
- inc bx
- _callDrawRectangle si
- add si, 8
- cmp bx, 2
- jl yesPl
- mov [usedClick], 1
- mov [operatorFlag], 1
- mov[operator], '+'
- _resetScreen
- noPl:
- ret
- pressPlus endp
- pressMinus proc
- cmp cx, 211 ;Checking if the user clicked inside the minus button.
- jl noMi
- cmp cx, 256
- jg noMi
- cmp dx, 120
- jl noMi
- cmp dx, 150
- jg noMi
- ;Minus can also be used to represent a negative number.
- cmp si, offset pos0 ;If this is the first click, the first operand is negative.
- jne minusOP
- mov [oprnd1NegFlag], 1
- mov [usedClick], 1
- add si, 8
- _callDrawRectangle si
- jmp noMi
- minusOP:
- mov [calcColor], 19
- lea si, buttonMin
- _callDrawRectangle si
- mov [usedClick], 1
- mov [operatorFlag], 1
- mov[operator], '-'
- _resetScreen
- noMi:
- ret
- pressMinus endp
- pressMultiply proc
- cmp cx, 162 ;Checking if the user clicked inside the minus button.
- jl noMul
- cmp cx, 207
- jg noMul
- cmp dx, 85
- jl noMul
- cmp dx, 115
- jg noMul
- lea si, buttonMul
- mov cx, 9
- yesMul:
- _callDrawRectangle si
- add si, 8
- loop yesMul
- mov [usedClick], 1
- mov [operatorFlag], 1
- mov[operator], '*'
- _resetScreen
- noMul:
- ret
- pressMultiply endp
- pressDivide proc
- cmp cx, 211 ;Checking if the user clicked inside the divide button.
- jl noDiv
- cmp cx, 256
- jg noDiv
- cmp dx, 85
- jl noDiv
- cmp dx, 115
- jg noDiv
- lea si, buttonDiv
- mov cx, 3
- yesDiv:
- _callDrawRectangle si
- add si, 8
- loop yesDiv
- mov [usedClick], 1
- mov [operatorFlag], 1
- mov[operator], '/'
- _resetScreen
- noDiv:
- ret
- pressDivide endp
- pressEquals proc
- cmp cx, 211 ;Checking if the user clicked inside the minus button.
- jl noEqu
- cmp cx, 256
- jg noEqu
- cmp dx, 155
- jl noEqu
- cmp dx, 185
- jg noEqu
- mov [calcColor], 42
- lea si, buttonEqu
- mov cx, 2
- yesEqu:
- _callDrawRectangle si
- add si, 8
- loop yesEqu
- mov [usedClick], 1
- mov [equalsFlag], 1
- _resetScreen
- noEqu:
- ret
- pressEquals endp
- printAns proc
- push bp
- mov bp, sp
- mov di, [bp+4] ;di = screen pos
- mov si, [bp+6] ;si = ansInt digit
- add si, [bp+8]
- checkDigit:
- mov al, byte ptr [si]
- ans0:
- cmp al,0
- jne ans1
- push di
- call draw0
- jmp NothingToPrint
- ans1:
- cmp al, 1
- jne ans2
- push di
- call draw1
- jmp NothingToPrint
- ans2:
- cmp al, 2
- jne ans3
- push di
- call draw2
- jmp NothingToPrint
- ans3:
- cmp al, 3
- jne ans4
- push di
- call draw3
- jmp NothingToPrint
- ans4:
- cmp al, 4
- jne ans5
- push di
- call draw4
- jmp NothingToPrint
- ans5:
- cmp al, 5
- jne ans6
- push di
- call draw5
- jmp NothingToPrint
- ans6:
- cmp al, 6
- jne ans7
- push di
- call draw6
- jmp NothingToPrint
- ans7:
- cmp al, 7
- jne ans8
- push di
- call draw7
- jmp NothingToPrint
- ans8:
- cmp al, 8
- jne ans9
- push di
- call draw8
- jmp NothingToPrint
- ans9:
- cmp al, 9
- jne ansD
- push di
- call draw9
- jmp NothingToPrint
- ansD:
- cmp al, '.'
- jne ansN
- push di
- call drawDot
- jmp NothingToPrint
- ansN:
- cmp al, '-'
- jne NothingToPrint
- push di
- call drawNeg
- NothingToPrint:
- pop bp
- ret 6
- printAns endp
- createAnswerArray proc
- push bp
- mov bp, sp
- lea si, ans
- lea di, ansInt
- lea bx, ansFloat
- mov cx, 10
- copySign:
- cmp [sign], 1
- jne copyInt
- mov [si], byte ptr 2Dh
- inc si
- dec cx
- inc di
- copyInt:
- cmp cx, 1
- je numStart
- cmp byte ptr[di], 0
- jne numStart
- cmp [shortNumFlag], 0
- je numShort
- numStart:
- mov [shortNumFlag], 1
- mov al, byte ptr[di]
- mov [si], al
- inc si
- numShort: inc di
- loop copyInt
- xor cx,cx
- copyFloat:
- cmp cx, 9
- je copyDone
- mov al, [bx]
- mov [si], al
- inc si
- inc bx
- inc cx
- jmp copyFloat
- copyDone:
- pop bp
- ret
- createAnswerArray endp
- errorsHandler proc
- push bp
- mov bp, sp
- lea si, pos0
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- lea si, pos1
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, diagonal1
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, pos2
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, diagonal2
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, pos3
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, pos4
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 16
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, diagonal3
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- add si, 8
- _callDrawRectangle si
- lea si, pos5
- add si, 32
- _callDrawRectangle si
- add si, 24
- _callDrawRectangle si
- pop bp
- ret
- errorsHandler endp
- mov ax,4C00h
- int 21h
- end START
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement