;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                              ;
;                      Keypad Interface Small Board                            ;
;                         Author: Jake Sutherland                              ;
;                                                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        list            p=pic16f627a
        include         p16f627a.inc
        __config b'10000100010000'
        errorlevel      -302    ;Eliminate bank warning

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                              ;
;                         PIC16F627 Microcontroller                            ;
;                                  ____ ____                                   ;
;           Chip Enable LED  RA2 -|    -    |- RA1  Keypad / Push On Push Off  ;
;      Push On Push Off LED  RA3 -|         |- RA0  Keypad / Momentary On      ;
;          Momentary On LED  RA4 -|         |- RA7  Keypad                     ;
;              Push Buttons  RA5 -|         |- RA6  Keypad                     ;
;                            GND -|         |- VCC                             ;
;              DIP Switch 1  RB0 -|         |- RB7  Keypad                     ;
;              DIP Switch 2  RB1 -|         |- RB6  Keypad                     ;
;              74HC164 CLOCK RB2 -|         |- RB5  Keypad                     ;
;             74HC164  DATA  RB3 -|_________|- RB4  Keypad                     ;
;                                                                              ;
;                                                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FUNCTION_SET_REG   EQU   0x25
DIGIT_STORAGE_REG  EQU   0X26
COUNTDOWN_REG      EQU   0X27


SETIO
        CLRF    PORTA               ; Initialise PORT A by setting ouput data latches
        MOVLW   0x07                ; Turn Comparators off and enable pins for I/O functions
        MOVWF   CMCON               ;
        BCF     STATUS, RP1         ; Bank 1
        BSF     STATUS, RP0         ; Bank 1
        MOVLW   b'00000000'         ; RA<7:0> Ouputs.
        MOVWF   TRISA               ;

        MOVLW   b'00000011'         ; RB<1:0> Inputs. RB<7:2> Ouputs.
        MOVWF   TRISB               ;

        BCF     STATUS, RP1         ; Bank 0
        BCF     STATUS, RP0         ; Bank 0










ONE_OFF_INITIALISE
        CLRF    FUNCTION_SET_REG    ; Function Set Register
        CLRF    DIGIT_STORAGE_REG
        CLRF    COUNTDOWN_REG
        CLRF    0x05                ;
        CLRF    0x06                ;
        BSF     0X05,2              ; Chip Enable LOW  *remember it is inverted so setting the pin turns the LED off.
        BSF     0x06,2              ; Set clock line. (Data transfer on falling edge)










LIGHT_SCROLL
        MOVLW   B'0001'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0010'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0100'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'1000'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0100'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0010'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0001'
        CALL    MOVE_TO_164
        CALL    DELAY_100ms
        MOVLW   B'0000'
        CALL    MOVE_TO_164
        CALL    DELAY_200ms
        MOVLW   B'1111'
        CALL    MOVE_TO_164
        CALL    DELAY_200ms
        MOVLW   B'0000'
        CALL    MOVE_TO_164











TEST_FOR_FUNCTION
        BTFSC   0x06,0              ; DIP Switch SW1, Keypad Arrangement
        BSF     FUNCTION_SET_REG,1  ; SW=1   Custom Arrangement
        BTFSS   0x06,0              ;
        BCF     FUNCTION_SET_REG,1  ; SW=0   c1c2c3c4r1r2r3r4

        BTFSC   0x06,1              ; DIP Switch SW2, Mode
        BSF     FUNCTION_SET_REG,0  ; SW=1   DTMF Mode
        BTFSS   0x06,1              ;
        BCF     FUNCTION_SET_REG,0  ; SW=0   Normal Mode



        INCF    FUNCTION_SET_REG    ; Increments Function Set Reg so we can decrement it before testing.

        DECFSZ  FUNCTION_SET_REG    ; eg. If Function Set was 00, Inc to 01, DECF brings it back to 00 (now 'skip if zero'), so it skips the goto instruction and goes to Function_1 (which is 00 of the DIP switch)
        GOTO    $+2                 ; If it is not zero, we skip the next GOTO instruction
        GOTO    FUNCTION_1          ;

        DECFSZ  FUNCTION_SET_REG    ; eg. If Function Set was 01, Inc to 10, DECF brings it back to 01, and because it is not zero, the GOTO $+2 is exected in the above paragraph, which brings us to this DECFSZ here. so we have 01, DEC, gives us 00, skips the GGOTO $+2 just below and goes to Function_2
        GOTO    $+2                 ;
        GOTO    FUNCTION_2          ;

        DECFSZ  FUNCTION_SET_REG    ;
        GOTO    $+2                 ;
        GOTO    FUNCTION_3          ;

        DECFSZ  FUNCTION_SET_REG    ;
        GOTO    $+2                 ;
        GOTO    FUNCTION_4          ;

        GOTO    TEST_FOR_FUNCTION










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                           SET CUSTOM KEYPAD ARRANGEMENT AND PORT I/O'S                           ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; How To Setup A Custom Keypad Arragement...
;
; 1st Step
;         Define EQU values for new Row And Columns
;
; 2nd Step
;         Set I/O's for Custom Keypad Arragement under the heading SETIO_CUSTOM_ARRANGMENT
;         This is done by changing the corresponding Columns to Outputs and the Rows to Inputs
;
; 3rd Step
;         If using a 3x4 Matrix where the 4th column is not going to be used, you must comment out
;         appropriate lines under function 3 and 4. (functions 3 and 4 are for custom arrangement)
;


;Example of a working layout for 4x4 matrix reading, C1 C2 C3 C4 R1 R2 R3 R4 on pins left to right.
; COL_1_PORT   EQU   PORTA
; COL_2_PORT   EQU   PORTA
; COL_3_PORT   EQU   PORTA
; COL_4_PORT   EQU   PORTA
; ROW_1_PORT   EQU   PORTB
; ROW_2_PORT   EQU   PORTB
; ROW_3_PORT   EQU   PORTB
; ROW_4_PORT   EQU   PORTB
; ROW_5_PORT   EQU   PORTA
; COL_1        EQU   1
; COL_2        EQU   0
; COL_3        EQU   7
; COL_4        EQU   6
; ROW_1        EQU   7
; ROW_2        EQU   6
; ROW_3        EQU   5
; ROW_4        EQU   4
; ROW_5        EQU   5
;
; SETIO_CUSTOM_ARRANGMENT
;         BCF     STATUS, RP1         ; Bank 1
;         BSF     STATUS, RP0         ; Bank 1
;         MOVLW   b'00100000'         ; RA<7:6>,<4:0> Ouputs. RA<5> Inputs.
;         MOVWF   TRISA               ;
;
;         MOVLW   b'11110011'         ; RB<7:4>,<1:0> Inputs. RB<3:2> Ouputs.
;         MOVWF   TRISB               ;
;
;         BCF     STATUS, RP1         ; Bank 0
;         BCF     STATUS, RP0         ; Bank 0
;
;         RETURN


COL_1_PORT   EQU   PORTA
COL_2_PORT   EQU   PORTA
COL_3_PORT   EQU   PORTB
;COL_4_PORT   EQU      PORTB
ROW_1_PORT   EQU   PORTA
ROW_2_PORT   EQU   PORTB
ROW_3_PORT   EQU   PORTB
ROW_4_PORT   EQU   PORTB
ROW_5_PORT   EQU   PORTA
COL_1        EQU   6
COL_2        EQU   0
COL_3        EQU   6
;COL_4        EQU      7
ROW_1        EQU   7
ROW_2        EQU   4
ROW_3        EQU   5
ROW_4        EQU   7
ROW_5        EQU   5

SETIO_CUSTOM_ARRANGMENT
        BCF     STATUS, RP1         ; Bank 1
        BSF     STATUS, RP0         ; Bank 1
        MOVLW   b'10100000'         ; RA<7:6>,<4:0> Ouputs. RA<5> Inputs.
        MOVWF   TRISA               ;

        MOVLW   b'10110011'         ; RB<7:4>,<1:0> Inputs. RB<3:2> Ouputs.
        MOVWF   TRISB               ;

        BCF     STATUS, RP1         ; Bank 0
        BCF     STATUS, RP0         ; Bank 0

        RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                           SET CUSTOM KEYPAD ARRANGEMENT AND PORT I/O'S                           ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                          FUNCTION 1                                              ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Keypad Matrix Arrangement: C1 C2 C3 C4 R1 R2 R3 R4
; Mode:                      Normal BCD output
;          _   _   _   _
;   Row 1 |_| |_| |_| |_|
;          _   _   _   _
;   Row 2 |_| |_| |_| |_|
;          _   _   _   _
;   Row 3 |_| |_| |_| |_|
;          _   _   _   _
;   Row 4 |_| |_| |_| |_|
;
;          C   C   C   C
;          O   O   O   O
;          L   L   L   L
;          1   2   3   4
;
; Col 1 = Pin 1 = RA1
; Col 2 = Pin 2 = RA0
; Col 3 = Pin 3 = RA7
; Col 4 = Pin 4 = RA6
; Row 1 = Pin 5 = RB7
; Row 2 = Pin 6 = RB6
; Row 3 = Pin 7 = RB5
; Row 4 = Pin 8 = RB4

FUNCTION_1
SETIO_F1
        BCF     STATUS, RP1         ; Bank 1
        BSF     STATUS, RP0         ; Bank 1
        MOVLW   b'00100000'         ; RA<7:6>,<4:0> Ouputs. RA<5> Inputs.
        MOVWF   TRISA               ;

        MOVLW   b'11110011'         ; RB<7:4>,<1:0> Inputs. RB<3:2> Ouputs.
        MOVWF   TRISB               ;

        BCF     STATUS, RP1         ; Bank 0
        BCF     STATUS, RP0         ; Bank 0

TEST_KEYPAD_F1
        BSF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_1_F1            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_4_F1            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_7_F1            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_F_F1            ; Key Detected
        BTFSC   0x05,5              ; Keypad Row 5
        GOTO    KEY_POPO_F1         ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BSF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_2_F1            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_5_F1            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_8_F1            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_0_F1            ; Key Detected
        BTFSC   0x05,5              ; Keypad Row 5
        GOTO    KEY_MO_F1           ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BSF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_3_F1            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_6_F1            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_9_F1            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_E_F1            ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BSF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_A_F1               ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_B_F1               ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_C_F1               ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_D_F1               ; Key Detected

        GOTO    TEST_FOR_FUNCTION


KEY_0_F1   ; 0000
        MOVLW   B'0000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_1_F1   ; 0001
        MOVLW   B'0001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_2_F1   ; 0010
        MOVLW   B'0010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_3_F1   ; 0011
        MOVLW   B'0011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_4_F1   ; 0100
        MOVLW   B'0100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_5_F1   ; 0101
        MOVLW   B'0101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_6_F1   ; 0110
        MOVLW   B'0110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_7_F1   ; 0111
        MOVLW   B'0111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_8_F1   ; 1000
        MOVLW   B'1000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_9_F1   ; 1001
        MOVLW   B'1001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_A_F1   ; 1010
        MOVLW   B'1010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_B_F1   ; 1011
        MOVLW   B'1011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_C_F1   ; 1100
        MOVLW   B'1100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_D_F1   ; 1101
        MOVLW   B'1101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_E_F1   ; 1110
        MOVLW   B'1110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_F_F1   ; 1111
        MOVLW   B'1111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_POPO_F1
        BTFSS   0X05,3              ; Test what state the "Push on Push off" bit is
        GOTO    POPO_HI_F1          ; If off (clear), Set it (by going to this routine)
        GOTO    POPO_LOW_F1         ; If on (set), Clear it (by going to this routine)
POPO_HI_F1
        BSF     0X05,3              ; Set "Push on Push off" bit (turns LED on)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   0x05,5              ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting
POPO_LOW_F1
        BCF     0X05,3              ; Clear "Push on Push off" bit (turns LED off)
        CALL    DELAY_100ms         ; Wait 200ms
        BTFSC   0x05,5              ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_MO_F1
        BSF     0X05,4              ; Set "Momentary On" LED
        CALL    DELAY_100ms         ; Wait 100ms
        BTFSC   0x05,5              ; Test to check if key has been released (if held down, LED stays on)
        GOTO    $-1                 ; If not execute previous instruction
        BCF     0X05,4              ; Clear "Momentary On" LED
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                          FUNCTION 1                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                          FUNCTION 2                                              ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Keypad Matrix Arrangement: C1 C2 C3 C4 R1 R2 R3 R4
; Mode:                      DTMF / Telephone Output
;          _   _   _   _
;   Row 1 |_| |_| |_| |_|
;          _   _   _   _
;   Row 2 |_| |_| |_| |_|
;          _   _   _   _
;   Row 3 |_| |_| |_| |_|
;          _   _   _   _
;   Row 4 |_| |_| |_| |_|
;
;          C   C   C   C
;          O   O   O   O
;          L   L   L   L
;          1   2   3   4
;
; Col 1 = Pin 1 = RA1
; Col 2 = Pin 2 = RA0
; Col 3 = Pin 3 = RA7
; Col 4 = Pin 4 = RA6
; Row 1 = Pin 5 = RB7
; Row 2 = Pin 6 = RB6
; Row 3 = Pin 7 = RB5
; Row 4 = Pin 8 = RB4

FUNCTION_2
SETIO_F2
        BCF     STATUS, RP1         ; Bank 1
        BSF     STATUS, RP0         ; Bank 1
        MOVLW   b'00100000'         ; RA<7:6>,<4:0> Ouputs. RA<5> Inputs.
        MOVWF   TRISA               ;

        MOVLW   b'11110011'         ; RB<7:4>,<1:0> Inputs. RB<3:2> Ouputs.
        MOVWF   TRISB               ;

        BCF     STATUS, RP1         ; Bank 0
        BCF     STATUS, RP0         ; Bank 0

TEST_KEYPAD_F2
        BSF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_1_F2            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_4_F2            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_7_F2            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_F_F2            ; Key Detected
        BTFSC   0x05,5              ; Keypad Row 5
        GOTO    KEY_POPO_F2         ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BSF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_2_F2            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_5_F2            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_8_F2            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_0_F2            ; Key Detected
        BTFSC   0x05,5              ; Keypad Row 5
        GOTO    KEY_MO_F2           ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BSF     0x05,7              ; Keypad Column 3
        BCF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_3_F2            ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_6_F2            ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_9_F2            ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_E_F2            ; Key Detected

        BCF     0x05,1              ; Keypad Column 1
        BCF     0x05,0              ; Keypad Column 2
        BCF     0x05,7              ; Keypad Column 3
        BSF     0x05,6              ; Keypad Column 4

        BTFSC   0x06,7              ; Keypad Row 1
        GOTO    KEY_A_F2               ; Key Detected
        BTFSC   0x06,6              ; Keypad Row 2
        GOTO    KEY_B_F2               ; Key Detected
        BTFSC   0x06,5              ; Keypad Row 3
        GOTO    KEY_C_F2               ; Key Detected
        BTFSC   0x06,4              ; Keypad Row 4
        GOTO    KEY_D_F2               ; Key Detected

        GOTO    TEST_FOR_FUNCTION


KEY_0_F2   ; 0000   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_1_F2   ; 0001
        MOVLW   B'0001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_2_F2   ; 0010
        MOVLW   B'0010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_3_F2   ; 0011
        MOVLW   B'0011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_4_F2   ; 0100
        MOVLW   B'0100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_5_F2   ; 0101
        MOVLW   B'0101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_6_F2   ; 0110
        MOVLW   B'0110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_7_F2   ; 0111
        MOVLW   B'0111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_8_F2   ; 1000
        MOVLW   B'1000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_9_F2   ; 1001
        MOVLW   B'1001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_A_F2   ; 1010   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,7              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_B_F2   ; 1011   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,6              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_C_F2   ; 1100   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,5              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_D_F2   ; 1101   DTMF SUBSTITUTE!!!!!
        MOVLW   B'0000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_E_F2   ; 1110   DTMF SUBSTITUTE!!!!!   HASH KEY
        MOVLW   B'1100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_F_F2   ; 1111   DTMF SUBSTITUTE!!!!!   ASTERISK KEY
        MOVLW   B'1011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   0x06,4              ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_POPO_F2
        BTFSS   0X05,3              ; Test what state the "Push on Push off" bit is
        GOTO    POPO_HI_F1          ; If off (clear), Set it (by going to this routine)
        GOTO    POPO_LOW_F1         ; If on (set), Clear it (by going to this routine)
POPO_HI_F2
        BSF     0X05,3              ; Set "Push on Push off" bit (turns LED on)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   0x05,5              ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting
POPO_LOW_F2
        BCF     0X05,3              ; Clear "Push on Push off" bit (turns LED off)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   0x05,5              ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_MO_F2
        BSF     0X05,4              ; Set "Momentary On" LED
        CALL    DELAY_100ms         ; Wait 100ms
        BTFSC   0x05,5              ; Test to check if key has been released (if held down, LED stays on)
        GOTO    $-1                 ; If not execute previous instruction
        BCF     0X05,4              ; Clear "Momentary On" LED
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                          FUNCTION 2                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                          FUNCTION 3                                              ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Keypad Matrix Arrangement: Custom Arrangement
; Mode:                      Normal BCD Out
;
; REFER TO "SET CUSTOM KEYPAD ARRANGEMENT AND PORT I/O'S" ABOVE, FOR CUSTOM DETAILS...
;

FUNCTION_3
        CALL    SETIO_CUSTOM_ARRANGMENT

TEST_KEYPAD_F3
        BSF     COL_1_PORT, COL_1   ; Keypad Column 1
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_1_F3            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_4_F3            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_7_F3            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_F_F3            ; Key Detected

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1
        BSF     COL_2_PORT, COL_2   ; Keypad Column 2
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_2_F3            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_5_F3            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_8_F3            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_0_F3            ; Key Detected

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2
        BSF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_3_F3            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_6_F3            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_9_F3            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_E_F3            ; Key Detected

;        BCF     COL_1_PORT, COL_1   ; Keypad Column 1
;        BCF     COL_2_PORT, COL_2   ; Keypad Column 2
;        BCF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BSF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;
;        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_A_F3            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_B_F3            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_C_F3            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_D_F3            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1        \
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2         |
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3         |
        BSF     0X05,1              ;                         |
                                    ;                         |
        BTFSC   ROW_5_PORT, ROW_5   ; Keypad Row 5            |
        GOTO    KEY_POPO_F3         ; Key Detected            | Beacause columns/rows of the custom arrangement will change,
                                    ;                         | we need to test the Momentary On and Push On Push Off buttons
        BCF     COL_1_PORT, COL_1   ; Keypad Column 1         | separate from the rest of the test routine becasue these pins
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2         | remain constant.
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3         |
        BSF     0X05,0              ;                         |
                                    ;                         |
        BTFSC   ROW_5_PORT, ROW_5   ; Keypad Row 5            |
        GOTO    KEY_MO_F3           ; Key Detected           /

        GOTO    TEST_FOR_FUNCTION


KEY_0_F3   ; 0000
        MOVLW   B'0000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_1_F3   ; 0001
        MOVLW   B'0001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_2_F3   ; 0010
        MOVLW   B'0010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_3_F3   ; 0011
        MOVLW   B'0011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_4_F3   ; 0100
        MOVLW   B'0100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_5_F3   ; 0101
        MOVLW   B'0101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_6_F3   ; 0110
        MOVLW   B'0110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_7_F3   ; 0111
        MOVLW   B'0111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_8_F3   ; 1000
        MOVLW   B'1000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_9_F3   ; 1001
        MOVLW   B'1001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_A_F3   ; 1010
        MOVLW   B'1010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_B_F3   ; 1011
        MOVLW   B'1011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_C_F3   ; 1100
        MOVLW   B'1100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_D_F3   ; 1101
        MOVLW   B'1101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_E_F3   ; 1110
        MOVLW   B'1110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_F_F3   ; 1111
        MOVLW   B'1111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_POPO_F3
        BTFSS   0X05,3              ; Test what state the "Push on Push off" bit is
        GOTO    POPO_HI_F1          ; If off (clear), Set it (by going to this routine)
        GOTO    POPO_LOW_F1         ; If on (set), Clear it (by going to this routine)
POPO_HI_F3
        BSF     0X05,3              ; Set "Push on Push off" bit (turns LED on)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting
POPO_LOW_F3
        BCF     0X05,3              ; Clear "Push on Push off" bit (turns LED off)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_MO_F3
        BSF     0X05,4              ; Set "Momentary On" LED
        CALL    DELAY_100ms         ; Wait 100ms
        CALL    DELAY_40ms          ; Wait 40ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released (if held down, LED stays on)
        GOTO    $-1                 ; If not execute previous instruction
        BCF     0X05,4              ; Clear "Momentary On" LED
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                          FUNCTION 3                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                          FUNCTION 4                                              ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Keypad Matrix Arrangement: Custom Arrangement
; Mode:                      DTMF / Telephone Output
;
; REFER TO "SET CUSTOM KEYPAD ARRANGEMENT AND PORT I/O'S" ABOVE, FOR CUSTOM DETAILS...
;


FUNCTION_4
        CALL    SETIO_CUSTOM_ARRANGMENT

TEST_KEYPAD_F4
        BSF     COL_1_PORT, COL_1   ; Keypad Column 1
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_1_F4            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_4_F4            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_7_F4            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_F_F4            ; Key Detected

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1
        BSF     COL_2_PORT, COL_2   ; Keypad Column 2
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_2_F4            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_5_F4            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_8_F4            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_0_F4            ; Key Detected

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2
        BSF     COL_3_PORT, COL_3   ; Keypad Column 3
;        BCF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1
        GOTO    KEY_3_F4            ; Key Detected
        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2
        GOTO    KEY_6_F4            ; Key Detected
        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3
        GOTO    KEY_9_F4            ; Key Detected
        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4
        GOTO    KEY_E_F4            ; Key Detected

;        BCF     COL_1_PORT, COL_1   ; Keypad Column 1                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BCF     COL_2_PORT, COL_2   ; Keypad Column 2                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BCF     COL_3_PORT, COL_3   ; Keypad Column 3                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BSF     COL_4_PORT, COL_4   ; Keypad Column 4                * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;
;        BTFSC   ROW_1_PORT, ROW_1   ; Keypad Row 1                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_A_F4            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_2_PORT, ROW_2   ; Keypad Row 2                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_B_F4            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_3_PORT, ROW_3   ; Keypad Row 3                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_C_F4            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        BTFSC   ROW_4_PORT, ROW_4   ; Keypad Row 4                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!
;        GOTO    KEY_D_F4            ; Key Detected                   * COMMENT OUT FOR 3X4 MATRIX!!!!!!!!

        BCF     COL_1_PORT, COL_1   ; Keypad Column 1        \
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2         |
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3         |
        BSF     0X05,1              ;                         |
                                    ;                         |
        BTFSC   ROW_5_PORT, ROW_5   ; Keypad Row 5            |
        GOTO    KEY_POPO_F3         ; Key Detected            | Beacause columns/rows of the custom arrangement will change,
                                    ;                         | we need to test the Momentary On and Push On Push Off buttons
        BCF     COL_1_PORT, COL_1   ; Keypad Column 1         | separate from the rest of the test routine.
        BCF     COL_2_PORT, COL_2   ; Keypad Column 2         |
        BCF     COL_3_PORT, COL_3   ; Keypad Column 3         |
        BSF     0X05,0              ;                         |
                                    ;                         |
        BTFSC   ROW_5_PORT, ROW_5   ; Keypad Row 5            |
        GOTO    KEY_MO_F3           ; Key Detected           /



        GOTO    TEST_FOR_FUNCTION


KEY_0_F4   ; 0000   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_1_F4   ; 0001
        MOVLW   B'0001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_2_F4   ; 0010
        MOVLW   B'0010'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_3_F4   ; 0011
        MOVLW   B'0011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_4_F4   ; 0100
        MOVLW   B'0100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_5_F4   ; 0101
        MOVLW   B'0101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_6_F4   ; 0110
        MOVLW   B'0110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_7_F4   ; 0111
        MOVLW   B'0111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_8_F4   ; 1000
        MOVLW   B'1000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_9_F4   ; 1001
        MOVLW   B'1001'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_A_F4   ; 1010   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1101'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_1_PORT, ROW_1   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_B_F4   ; 1011   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1110'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_2_PORT, ROW_2   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_C_F4   ; 1100   DTMF SUBSTITUTE!!!!!
        MOVLW   B'1111'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_3_PORT, ROW_3   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_D_F4   ; 1101   DTMF SUBSTITUTE!!!!!
        MOVLW   B'0000'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_E_F4   ; 1110   DTMF SUBSTITUTE!!!!!   HASH KEY
        MOVLW   B'1100'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_F_F4   ; 1111   DTMF SUBSTITUTE!!!!!   ASTERISK KEY
        MOVLW   B'1011'             ; Binary Digit for Hex Digit F
        CALL    MOVE_TO_164         ; Calling this routine Clocks the Binary Digit into the 74HC164
        BCF     0X05,2              ; Clears the CHIP ENABLE pin
        BTFSC   ROW_4_PORT, ROW_4   ; Wait for key to be released
        GOTO    $-1                 ; Skips this step when released. When held down, GOTO this line less 1. (one line up)
        CALL    DELAY_40ms          ; 40ms is the minimum time it takes the telephone exchange to recognise a DTMF tone
        BSF     0X05,2              ; Sets the CHIP ENABLE pin
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_POPO_F4
        BTFSS   0X05,3              ; Test what state the "Push on Push off" bit is
        GOTO    POPO_HI_F1          ; If off (clear), Set it (by going to this routine)
        GOTO    POPO_LOW_F1         ; If on (set), Clear it (by going to this routine)
POPO_HI_F4
        BSF     0X05,3              ; Set "Push on Push off" bit (turns LED on)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting
POPO_LOW_F4
        BCF     0X05,3              ; Clear "Push on Push off" bit (turns LED off)
        CALL    DELAY_200ms         ; Wait 200ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released
        GOTO    $-1                 ; If not execute previous instruction
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting

KEY_MO_F4
        BSF     0X05,4              ; Set "Momentary On" LED
        CALL    DELAY_100ms         ; Wait 100ms
        CALL    DELAY_40ms          ; Wait 40ms
        BTFSC   ROW_5_PORT, ROW_5   ; Test to check if key has been released (if held down, LED stays on)
        GOTO    $-1                 ; If not execute previous instruction
        BCF     0X05,4              ; Clear "Momentary On" LED
        GOTO    TEST_FOR_FUNCTION   ; Back to the very top, re-test function setting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                          FUNCTION 4                                              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                       CLOCK DATA INTO 164                                        ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVE_TO_164                         ;
        MOVWF   DIGIT_STORAGE_REG   ; Stores the Digit the was put into the 'w' reg
        MOVLW   D'4'                ; We want to clock only a nibble (4 bits) into the 164 so we will do it X amount of times
        MOVWF   COUNTDOWN_REG       ; Move the 4 into the countdown reg
        CALL    CLOCK_IN            ; Calls CLOCK_IN routine
        RETURN                      ; When finished clocking in the nibble, Return and wait for key to be released

CLOCK_IN
        BTFSC   DIGIT_STORAGE_REG,3 ; This determines if we need to clock a 1 or a 0 into the 74HC164 depending on weather bit 3 of the nibble is a 1 or a 0
        GOTO    CLK_HI              ; We need to clock in a 1
        GOTO    CLK_LOW             ; We need to clock in a 0

CLK_HI
        BSF     0X06,3              ; 74HC164 DATA  SET data line for a 1
        BCF     0X06,2              ; 74HC164 CLOCK
        BSF     0X06,2              ; 74HC164 CLOCK
        GOTO    CLOCK_IN_NEXT

CLK_LOW
        BCF     0X06,3              ; 74HC164 DATA  CLEAR data line for a 0
        BCF     0X06,2              ; 74HC164 CLOCK
        BSF     0X06,2              ; 74HC164 CLOCK
        GOTO    CLOCK_IN_NEXT

CLOCK_IN_NEXT
        RLF     DIGIT_STORAGE_REG
        BCF     STATUS,Z
        DECF    COUNTDOWN_REG,F
        BTFSC   STATUS,Z
        RETURN
        GOTO    CLOCK_IN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                       CLOCK DATA INTO 164                                        ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;










;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                          DELAY ROUTINES                                          ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_40ms
        MOVLW   0x3E                ;
        MOVWF   0X20                ;
        MOVLW   0x20                ;
        MOVWF   0X21                ;
DELAY_40                            ;
        DECFSZ  0X20, f             ;
        GOTO    $+2                 ;
        DECFSZ  0X21, f             ;
        GOTO    DELAY_40            ;39993 cycles
        GOTO    $+1                 ;
        NOP                         ;3 cycles
        RETURN                      ;4 cycles (including call)

DELAY_100ms
        MOVLW   0x1E                ;
        MOVWF   0X20                ;
        MOVLW   0x4F                ;
        MOVWF   0X21                ;
DELAY_100                           ;
        DECFSZ  0X20, f             ;
        GOTO    $+2                 ;
        DECFSZ  0X21, f             ;
        GOTO    DELAY_100           ;99993 cycles
        GOTO    $+1                 ;
        NOP                         ;3 cycles
        RETURN                      ;4 cycles (including call)

DELAY_200ms
        MOVLW   0x3F                ;
        MOVWF   0X20                ;
        MOVLW   0x9D                ;
        MOVWF   0X21                ;
DELAY_200                           ;
        DECFSZ  0X20, f             ;
        GOTO    $+2                 ;
        DECFSZ  0X21, f             ;
        GOTO    DELAY_200           ;199998 cycles
        GOTO    $+1                 ;
        RETURN                      ;2 cycles

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                          DELAY ROUTINES                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


END