org 0
num1 EQU 30H           ;first digit in number 1 in loc 30h
        num2 EQU 31H             ;second digit in number 1 in loc 31h
        num3 EQU 32H             ;second digit in number 1 in loc 31h
        op EQU 33H              ; operation in loc 32h
        num4 EQU 34H            ;first digit in number 2 in loc 30h
        num5 EQU 35H               ;second digit in number 2 in loc 31h
        num6 EQU 36H               ;second digit in number 2 in loc 31h
        RS bit P2.4
        RW bit P2.5
        E bit P2.6
        commandOrData EQU P3
        ;keyboard subroutine. This program sends the ASCII
        ;code for pressed key to P0.1
        ;P1.0-P1.3 connected to rows, P2.0-P2.3 to column
        MOV P2,#0FFH ;make P2 an input port
        Lcall lcdInitial      ;on CURSOR of lcd
        main:
        Lcall waitForKey
        mov A,20H
        CJNE A,#'c',w1     ;c for clear in key pad
        lcall cleaar
        ljmp main
        w1:Lcall lcdWrite ;20H
        Lcall DELAY
        Mov num1,20H       ;first digit of num1
      Lcall waitForKey
      Mov A,20H
      CJNE A,#'c',w2
      lcall cleaar
      ljmp main
      w2:
    Lcall lcdWrite ;20H
      Lcall DELAY
      Mov num2,20H         ;second digit of num1
      Lcall waitForKey
      Mov A,20H
      CJNE A,#'c',w3
      lcall cleaar
      ljmp main
      w3:
    Lcall lcdWrite ;20H
      Lcall DELAY
      Mov num3,20H         ;third digit of num1
        Lcall waitForKey
        mov A,20H
        CJNE A,#'c',oper
        lcall cleaar
        ljmp main
        oper:Lcall lcdWrite ;20H
        Lcall DELAY
        Mov op,20H     ;operation
     Lcall waitForKey
     mov A,20H
     CJNE A,#'c',w4
     lcall cleaar
     ljmp main
     w4:Lcall lcdWrite ;20H
     Lcall DELAY
     Mov num4,20H         ;first digit of num2
      Lcall waitForKey
      Mov A,20H
      CJNE A,#'c',w5
      lcall cleaar
      ljmp main
      w5:
   Lcall lcdWrite ;20H
      Lcall DELAY
      Mov num5,20H        ;second digit of num2
      Lcall waitForKey
      Mov A,20H
      CJNE A,#'c',w6
      lcall cleaar
      ljmp main
      w6:
    Lcall lcdWrite ;20H
      Lcall DELAY
      Mov num6,20H         ;third digit of num2
Process:
      ANl num1,#0FH
      ANl num2,#0FH
      ANl num3,#0FH
      ANl num4,#0FH
      ANl num5,#0FH
      ANl num6,#0FH
      mov A,num1
    mov b,#100
      mul Ab
      mov r6,A
      mov A,num2
      mov b,#10
      mul Ab
      add A,r6
      add A,num3
      mov num1,A           ; the first number in 3 digit in decimal
      mov A,num4
    mov b,#100
      mul Ab
      mov r7,A
      mov A,num5
      mov b,#10
      mul Ab
      add A,r7
      add A,num3
      mov num2,A          ;the second number in 3 digit in decimal
  mov A,op
  N4:CJNE A, #'+',N1
  lcall equal      ; put(=)
  lcall sum          ;put the result of sum
  Ljmp main
  N1:CJNE A, #'-',N2
  lcall equal     ; put(=)
  lcall sub       ;put the result of sub
  Ljmp main
  N2:CJNE A, #'*', N3
  lcall equal   ; put(=)
  lcall prod     ;put the result of prod
  Ljmp main
  N3:CJNE A, #'/', N4
lcall equal   ; put(=)
  lcall divid    ;put the result of divid
  Ljmp main
 sum:
        Mov A,num1
        ADD A,num2
        mov b,#100
        div Ab
        ORL A,#30H     ; ascii
        Mov 20H,A
        Lcall lcdWrite
        Lcall DELAY
        mov A,b
        mov b,#10
        div Ab
        ORL A,#30H
        Mov 20H,A
        Lcall lcdWrite
        Lcall DELAY
        ORL b,#30H
        Mov 20H,b
        Lcall lcdWrite
        Lcall DELAY
        lcall donee
        Lcall DELAY
        lcall cleaar
        Lcall DELAY
        ljmp main
 sub:
        Mov A,num1
        subb A,num2
        mov b,#100
        div Ab
        ORL A,#30H     ; ascii
        Mov 20H,A
        Lcall lcdWrite
        Lcall DELAY
        mov A,b
        mov b,#10
        div Ab
        ORL A,#30H
               Mov 20H,A
               Lcall lcdWrite
               Lcall DELAY
               ORL b,#30H
               Mov 20H,b
               Lcall lcdWrite
               Lcall DELAY
               lcall donee
               Lcall DELAY
               lcall cleaar
               Lcall DELAY
               ljmp main
prod:
mov   A,num1
mov   b,num2
mul   Ab
mov   b,#100
               div Ab
               ORL A,#30H     ; ascii
               Mov 20H,A
               Lcall lcdWrite
               Lcall DELAY
               mov A,b
               mov b,#10
               div Ab
               ORL A,#30H
               Mov 20H,A
               Lcall lcdWrite
               Lcall DELAY
               ORL b,#30H
               Mov 20H,b
               Lcall lcdWrite
               Lcall DELAY
lcall donee
Lcall DELAY
lcall cleaar
Lcall DELAY
ljmp main
        divid:
              mov b,num2
              mov A,b
              CJNE A,#000H,dividd
              lcall cleaar
              Lcall DELAY
              lcall erorrr
              lcall cleaar
              Lcall DELAY
              ljmp main
          dividd:
              mov A,num1
              div Ab
              mov r2,b
              mov b,#100
     div Ab
     ORL A,#30H     ; ascii
     Mov 20H,A
     Lcall lcdWrite
     Lcall DELAY
     mov A,b
     mov b,#10
     div Ab
     ORL A,#30H
     Mov 20H,A
     Lcall lcdWrite
     Lcall DELAY
     ORL b,#30H
     Mov 20H,b
     Lcall lcdWrite
     Lcall DELAY
     mov A,r2
     CJNE A,#000H,h
     lcall donee
     Lcall DELAY
     lcall cleaar
     Lcall DELAY
     ret
h:
     Mov 20H,#'.'
     Lcall lcdWrite
     Lcall DELAY
     mov A,r2
     mov b,#10
     mul Ab
     mov b,num2
     div Ab
     ORL A,#30H
     Mov 20H,A
     Lcall lcdWrite
     Lcall DELAY
     ret
     equal:
     Lcall waitForKey
     Mov A,20H
     q:cjne A,#'=' ,q
     Lcall lcdWrite
     Lcall DELAY
     ret
     donee:
     mov dptr,#700H
     ppack:mov A,#0
     movc A,@A+dptr
     jz ffinsh
     mov 20H,A
     Lcall lcdWrite
     Lcall DELAY
     inc dptr
     sjmp ppack
     ffinsh:ret
     org 700H
     mmsg:db "done",0
cleaar:
      Mov A,#01H
      Lcall COMNWRT ;20H
      Lcall DELAY
      ret
erorrr:
      lcall cleaar
            mov 20H,#'e'
            Lcall lcdWrite
          Lcall DELAY
            mov 20H,#'r'
            Lcall lcdWrite
          Lcall DELAY
            mov 20H,#'r'
            Lcall lcdWrite
          Lcall DELAY
            mov 20H,#'o'
            Lcall lcdWrite
          Lcall DELAY
            mov 20H,#'r'
            Lcall lcdWrite
          Lcall DELAY
            lcall cleaar
waitForKey:
K1: MOV P1,#0 ;ground all rows at once
MOV A,P2 ;read all col
;(ensure keys open)
ANL A,#00001111B ;masked unused bits
CJNE A,#00001111B,K1 ;till all keys release
;K2: LCALL DELAY ;call 20 msec delay
;MOV A,P2 ;see if any key is pressed
;ANL A,#00001111B ;mask unused bits
;CJNE A,#00001111B,OVER;key pressed, find row
;SJMP K2 ;check till key pressed
OVER: LCALL DELAY ;wait 20 msec debounce time
MOV A,P2 ;check key closure
ANL A,#00001111B ;mask unused bits
CJNE A,#00001111B,OVER1;key pressed, find row
SJMP over ;if none, keep polling
OVER1: MOV P1, #11111110B ;ground row 0
MOV A,P2 ;read all columns
ANL A,#00001111B ;mask unused bits
CJNE A,#00001111B,ROW_0 ;key row 0, find col.
MOV P1,#11111101B ;ground row 1
MOV A,P2 ;read all columns
ANL A,#00001111B ;mask unused bits
CJNE A,#00001111B,ROW_1 ;key row 1, find col.
MOV P1,#11111011B ;ground row 2
MOV A,P2 ;read all columns
ANL A,#00001111B ;mask unused bits
CJNE A,#00001111B,ROW_2 ;key row 2, find col.
MOV P1,#11110111B ;ground row 3
MOV A,P2 ;read all columns
ANL A,#00001111B ;mask unused bits
CJNE A,#00001111B,ROW_3 ;key row 3, find col.
LJMP over ;if none, false input, ;repeat
ROW_0: MOV DPTR,#KCODE0 ;set DPTR=start   of row 0
SJMP FIND ;find col. Key belongs to
ROW_1: MOV DPTR,#KCODE1 ;set DPTR=start   of row
SJMP FIND ;find col. Key belongs to
ROW_2: MOV DPTR,#KCODE2 ;set DPTR=start   of row 2
SJMP FIND ;find col. Key belongs to
ROW_3: MOV DPTR,#KCODE3 ;set DPTR=start   of row 3
FIND: RRC A ;see if any CY bit low
JNC MATCH ;if zero, get ASCII code
INC DPTR ;point to next col. addr
SJMP FIND ;keep searching
MATCH: CLR A ;set A=0 (match is found)
MOVC A,@A+DPTR ;get ASCII from table
MOV P3,A ;display pressed key
Mov 20H,A
;LCALL lcdWrite
;LCALL Delay
ret
; ASCII LOOK-UP TABLE FOR EACH ROW
ORG 300H
KCODE0: DB '/','9','8','7' ;ROW 0
KCODE1: DB '*','6','5','4' ;ROW 1
KCODE2: DB '-','3','2','1' ;ROW 2
KCODE3: DB '+','=','0','c' ;ROW 3
     Delay:Mov R0,#255
     here1:Mov R1,#255
     here:DJNZ R1,here
     DJNZ R0,here1
     ret
      DELAY1: Mov R1,#6
HERE3:MOV R3,#255 ;50 or higher for fast CPUs
HERE2: MOV R4,#255 ;R4 = 255
HERE4: DJNZ R4,HERE4 ;stay until R4 becomes 0
DJNZ R3, HERE2
DJNZ R1, HERE3
RET
      org 200H
            lcdInitial:MOV A,#38H ;INIT. LCD 2 LINES, 5X7 MATRIX
            LCALL COMNWRT ;call command subroutine
            LCALL DELAY ;give LCD some time
            MOV A,#0EH ;display on, cursor on
            LCALL COMNWRT ;call command subroutine
            LCALL DELAY ;give LCD some time
            ret
           lcdWrite:
           ;MOV A,#01 ;clear LCD
           ;LCALL COMNWRT ;call command subroutine
           ;LCALL DELAY ;give LCD some time
           MOV A,20H ;display letter N
           LCALL DATAWRT ;call display subroutine
                 LCALL DELAY ;give LCD some time
                 ret
                 COMNWRT: ;send command to LCD
                       MOV commandOrData,A ;copy reg A to port 1
                       CLR RS ;RS=0 for command
                       CLR RW ;R/W=0 for write
                       SETB E ;E=1 for high pulse
                       CLR E ;E=0 for H-to-L pulse
                       RET
      DATAWRT: ;write data to LCD
                  MOV commandOrData,A ;copy reg A to port 1
                  SETB RS ;RS=1 for DATA
                  CLR RW;R/W=0 for write
                  SETB E ;E=1 for high pulse
                  CLR E ;E=0 for H-to-L pulse
      RET
End