



DELAY_HIGH EQU   003H
DELAY_LOW  EQU   018H
           
Key0pressed EQU   031H
FLAG_1     EQU   Key0pressed+1
FLAG_2     EQU   033H
FLAG_3     EQU   034H
FLAG_4     EQU   035H
FLAG_5     EQU   036H
FLAG_6     EQU   037H
FLAG_7     EQU   038H
FLAG_INVALIDKEY EQU 039H
FLAG_PUSH  EQU   040H
NEWKEY     EQU   041H

       ORG 000H
           MOV   SP,#050H
           LJMP  START
           
       ORG 000BH
           ACALL T0_ISR
           RETI
                 
       ORG 001BH
           AJMP  T1_ISR

START:     MOV   IE,#08AH
           MOV   TMOD,#011H
           MOV   P1,#0FFH; make PORT 1 as an input port
           MOV   P2,#00H
           MOV   R0,#00H
           MOV   R7,#00H
           CLR   Key0pressed
           CLR   FLAG_1
           CLR   FLAG_2
           CLR   FLAG_3
           CLR   FLAG_4
           CLR   FLAG_5
           CLR   FLAG_6
           CLR   FLAG_7
           ACALL TIMER_1
KEY:       MOV   A,P1
           CPL   A
           JMP   KEY


;; timer 1 interrupt
;; performs ??????????????
T1_ISR:    PUSH  ACC
           PUSH  PSW
           CLR   TR1
           MOV   PSW,#00H
           ACALL ReadKeys;             ; check whether any key is pressed or not
           JNZ   CALCULATE             ; key is pressed then jump to calculate to check is the key     
                                       ; pressed is valid key or the previous key is kept pressed till    
                                       ; now
           JMP   ALTER;                ; If no key is pressed then clear the flag which check whether the 
                                       ;  previous key is kept pressed till now

CALCULATE: ACALL ReadKeys              ; again check whether key is pressed or not
           JZ    ALTER                 ; if no key is pressed then jump tp clear the flags and start the  
                                       ; TIMER 1  again
           ACALL CONVERT               ; if the key is pressed then check the key pressed is a valid key  

                                       ; or not depending on the flag FLAG_INVALIDKEY
           JBC   FLAG_INVALIDKEY,ALTER ; if this flag is set then the key is invalid and go to ALTER
           ACALL TIMER_0               ;if the key pressed is valid then jump to TIMER 0 for the debounce delay
           POP   ACC
           POP   PSW
           RETI

ALTER:     CLR   FLAG_PUSH             ;clear this flag indicating that the previous key is not being     
                                       ; kept pressed and the key which is pressed is now released
AGAIN:     ACALL TIMER_1               ; call to timer 1 for again scanning the keys
           POP   PSW
           POP   ACC
           RETI
           


;; timer 0 interrupt
;; performs ??????????????
T0_ISR:
       PUSH ACC
       PUSH PSW
       MOV PSW,#00H
       CLR TR0 
       ACALL ReadKeys                  ;chekh whhether the key is pressed or not again
       JZ ALTER_1                      ;if not pressed then jump to ALTER 1 for clearing the flags   

                                       ; and call to TIMER 1 agan for scanning the key's
       ACALL CONVERT                   ;if key is pressed check it is valid or not
       JBC FLAG_INVALIDKEY,ALTER_1     ; invalid key indication if this flag is set
       JB FLAG_PUSH,COMPARE            ; if this flag is found set then it means that the key found  

                                       ; to be pressed is the same key previously kept pressed
       SETB FLAG_PUSH                  ; if FLAG_PUSH is not found to be set then it means that the  

                                       ; valid key is a new key
       MOV NEWKEY,A                    ; move this newkey value to the flag NEWKEY
       JMP HOME                        ; jump to home

COMPARE:
        CJNE A,NEWKEY,CLEAR            ; if the FLAG_PUSH is found to be set then control comes to this      

                                       ; statement for checking whether the key kept pressed for a long time      

                                       ; is the previous one or not
        JMP AGAIN_1                    ; if it is the same key kept pressed then do nothing and              

                                       ; again call to TIMER 1 so that scanning of keys can be done again    

                                       ; but dont clear the FLAG_PUSH flag this time because the key kept       

                                       ;pressed has not indicated to be released till now

HOME:            
 JB ACC.0,COOL_0; if these bits are ON then it means 
 JB ACC.1,COOL_1; which key is pressed at this moment
 JB ACC.2,COOL_2; and accordingly jump to that 
 JB ACC.3,COOL_3; 
 JB ACC.4,COOL_4
 JB ACC.5,COOL_5
 JB ACC.6,COOL_6
 JB ACC.7,COOL_7

CLEAR:
     CLR FLAG_PUSH   ; If the key being kept pressed is not the same previous key then            

                     ; it means that the previous key kept pressed has been released              

                     ; and this is the new key which is pressed and it is valid ... so            

                     ; jump to HOME
     JMP HOME
                                       
ALTER_1:
    CLR FLAG_PUSH
AGAIN_1:
    ACALL TIMER_1
    POP PSW
    POP ACC
    RET
                                            
COOL_0:
    JB Key0pressed,WORLD ; if this flag is found to be set then it means the key is being pressed      

                    ;previously and so jump to WORLD for making OFF LED that is corresponding to  

                   ; this key
    SETB Key0pressed     ; set this flag coz the key is pressed fot the 1st time
    JMP UNIVERSE    ; jump to universe to make the corrersponding LED ON

COOL_1:
    JB FLAG_1,WORLD
    SETB FLAG_1
    JMP UNIVERSE

COOL_2:
   JB FLAG_2,WORLD
   SETB FLAG_2
   JMP UNIVERSE
COOL_3:
   JB FLAG_3,WORLD
   SETB FLAG_3
   JMP UNIVERSE
COOL_4:
   JB FLAG_4,WORLD
   SETB FLAG_4
   JMP UNIVERSE

COOL_5:
   JB FLAG_5,WORLD
   SETB FLAG_5
   JMP UNIVERSE
COOL_6:
   JB FLAG_6,WORLD
   SETB FLAG_6
   JMP UNIVERSE
COOL_7:
   JB FLAG_7,WORLD
   SETB FLAG_7
   JMP UNIVERSE


WORLD:
    MOV R0,A   ; if the key is pressed second time then
    MOV A,P2   ; make the corresponding LED OFF while all
    ORL A,R0   ; other LED's are not been effected at all
    XRL A,R0
    MOV P2,A
    JMP STATUS ;jump to status to CLEAR the flag which indicated the key is being pressed for the 

               ; 1st time or 2nd time
                                            
UNIVERSE:
    ORL A,P2  ; If the control comes here then it means that the key being pressed is pressed for 

              ; the first time and so the corresponding LED is maked ON
    MOV P2,A
    JMP AGAIN_1

STATUS:
    JBC Key0pressed,AGAIN_1; flag is cleared to make it fresh key
    JBC FLAG_1,AGAIN_1
    JBC FLAG_2,AGAIN_1
    JBC FLAG_3,AGAIN_1
    JBC FLAG_4,AGAIN_1
    JBC FLAG_5,AGAIN_1
    JBC FLAG_6,AGAIN_1
    JBC FLAG_7,AGAIN_1

ReadKeys:
    MOV A,P1; the key pressed 
            ; bit will be low so the value is transfered to ACCUMULATOR for further processing
    CPL A   ; the value in ACC is complimented coz all the bits in PORT 1 are high as it is an input port
    RET
                                       

TIMER_0:
    MOV TL0,#DELAY_LOW
    MOV TH0,#DELAY_HIGH
    SETB TR0
    RET
                                            
TIMER_1:
    MOV TL1,#0E0H
    MOV TH1,#0B1H
    SETB TR1
    RET
                                       
CONVERT:
     CLR FLAG_INVALIDKEY ; this subrountine check the validity of the key that is pressed ... and 

                         ; indicates it by the flag FLAG_INALIDKEY                  
      CJNE A,#01H,SECOND
      RET
SECOND:
      CJNE A,#02H,THIRD
      RET
THIRD:
     CJNE A,#04H,FOURTH
     RET
                                                      
FOURTH:
     CJNE A,#08H,FIVE
     RET
FIVE:
     CJNE A,#010H,SIX
     RET
SIX:
     CJNE A,#020H,SEVEN
     RET
SEVEN:
     CJNE A,#040H,EIGHT
     RET
EIGHT:
     CJNE A,#080H,BAD
     RET
BAD:
     SETB FLAG_INVALIDKEY
     RET


;************************************************************************************************

**
    END