Para leer tu teclado:
RB0 1 2 3
RB1 4 5 6
RB2 7 8 9
RB3 10 11 12
RB4 RB5 RB6
Indiqué el número de tecla. Obviamente el número no tiene que necesariamente corresponder a su significado(en un teclado común la posición 11 correspondería a la tecla 0 por ejemplo, la 10 al asterísco y la 12 al numeral).
;/////////////////////////////////
Tecla EQU 0xXX ;Indicará tecla actualmente leída
i EQU 0xXX+1 ;Contador
Aux EQU 0xXX+2 ;Variable Auxiliar
CantTeclas EQU 0xXX+3 ;Cantidad de teclas almacenadas al momento(0<CantTeclas<5)
;Estos 8 bytes a continuación deben ir ordenados consecutivamente y en este orden
Dig1Pass EQU 0xXX+4 ;Para almacenar el primer Digito del Password
Dig2Pass EQU 0xXX+5 ;Para almacenar el segundo Digito del Password
Dig3Pass EQU 0xXX+6 ;Para almacenar el tercer Digito del Password
Dig4Pass EQU 0xXX+7 ;Para almacenar el cuarto Digito del Password
Dig1Access EQU 0xXX+8 ;Para almacenar el primer Digito del Codigo ingresado
Dig2Access EQU 0xXX+9 ;Para almacenar el segundo Digito del Codigo ingresado
Dig3Access EQU 0xXX+10 ;Para almacenar el tercer Digito del Codigo ingresado
Dig4Access EQU 0xXX+11 ;Para almacenar el cuarto Digito del Codigo ingresado
Banderas EQU 0xXX+12 ;Indicadores que guardan el estado actual del sistema
#define YaIngresoPass Banderas,0
#define Onda Banderas,1
#define Buzzer Banderas,2
;//////////////////////
ValorTeclas ;Devuelve el valor ASCII según la tecla presionada(Se pueden cambiar a gusto)
addwf PCL,F
retlw "1"
retlw "2"
retlw "3"
retlw "4"
retlw "5"
retlw "6"
retlw "7"
retlw "8"
retlw "9"
retlw "*"
retlw "0"
retlw "#"
retlw "?" ;No debería caer nunca acá(si tecla=12 es porque no se encontró nada en el teclado) pero igual, por las dudas...

;/////////////////////////////////
;Lee el teclado. La variable Tecla contiene el numero de tecla presionada si es que hay alguna. Caso contrario Tecla vuelve valiendo .12
LeerTeclado
movlw .4
movwf i ;Indicar que el proceso se va a realizar 4 veces(son 4 filas, no?)
clrf Tecla ;Inicializar Tecla a 0
movlw 0x0F
iorwf PORTB ;Poner todas las filas en Alto
bcf STATUS,C ;Preparar Carry para inyectar un cero en RB0 en la primera rotación
ProxFila
rlf PORTB,W ;Rotar sin afectar al RB7(si no importara afectar a RB7(ya sea porque no lo usas o está configurado como entrada) el código se acortaría un poco...)
andlw 0x7F ;enmascarar bit7
movwf Aux ;guardar los 7 bis excepto el RB7
movlw 0x80
andwf PORTB,F ;poner a cero todos menos el RB7
movf Aux,W
iorwf PORTB,F ;y ahora incluir Aux en PORTB para conseguir el valor deseado
btfss PORTB,4 ;Columna1?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
btfss PORTB,5 ;Columna2?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
btfss PORTB,6 ;Columna3?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
bsf STATUS,C ;Preparar el Carry para inyectar un 1 por la derecha del PuertoB
decfsz i,F ;Ya escaneó las 4 filas?
goto ProxFila ;No, entonces proxima fila!
return ;Si...volver(Tecla=.12)
;//////////////////////
Programa_Principal
;Falta config inicial!
clrf CantTeclas ;Indicar 0 teclas ingresadas al momento
clrf Banderas ;Inicializar estado del sistema
movlw Dig1Pass
movwf FSR ;Cargar la posicion RAM de donde se guardará el primer digito ingresado del password en el registro de acceso indirecto
Loop
call LeerTeclado ;Buscar tecla presionada(si usaras la interrupción RB4-RB7 para detectarla quedaría más profesional)
movf Tecla,w
xorlw .12 ;Si tecla=12, no hay tecla presionada
btfsc STATUS,Z
goto Loop ;entonces, volver a Loop
;Se encontró una tecla!
;call DemoraAntiRebote ;Faltaría hacer esta subrutina
pageselw ValorTeclas ;Acomodar PCLATH para manejar la tabla correctamente
movf Tecla,W
call ValorTeclas ;buscar su valor ASCII
movwf INDF ;y guardarla en donde corresponda
incf FSR,F ;apuntar a próximo digito
incf CantTeclas,F ;incrementar cantidad de teclas presionadas
movf CantTeclas,w
xorlw 4
btfss STATUS,Z ;Se presionaron 4 teclas?
goto Loop ;no, seguir leyendo
clrf CantTeclas ;si. Reiniciar cantidad de teclas presionadas
btfsc YaIngresoPass,0 ;ya se ha ingresado el password?
goto Comparar ;Si. Entonces comparar valor ingresado con el password
bsf YaIngresoPass,0 ;No se había ingresado password, indicar que ahora si.
goto Loop ;Y volver al Loop para leer si las proximas 4 teclas a presionar concuerdan con el password
;//////////////////////
;/////////////////////////////////
Comparar
movlw .4
movwf i ;indicar 4 digitos a comparar
movlw Dig1Pass
movwf FSR ;apuntar al primer digito del Password
prox
movf INDF,W
movwf Aux ;Guardar valor actual en registro auxiliar
movlw .4
addwf FSR,F ;incrementar el acceso indirecto en 4(es decir,a la posición RAM del digito de acceso
;corespondiente(Dig1Pass+4=Dig1Access,Dig2Pass+4=Dig2Access,etc)
movf INDF,w
xorwf Aux,W ;Compararlos
btfss STATUS,Z ;Iguales?
goto NoCoinciden ;No.Ir a setear modo Buzzer
movlw .3
subwf FSR,F ;Apuntar al próximo digito del password
decfsz i,f ;Ya comparé los 4 digitos?
goto prox ;No, entonces comparar el próximo
Coinciden ;Coindicieron!
bcf Buzzer ;Desactivar modo buzzer y activar modo onda
bsf Onda
movlw Dig1Access
movwf FSR ;Cargar acceso indirecto para volver a leer el primer digito de acceso
goto Loop ;Volver al Loop
NoCoinciden ;No coincidieron
bcf Onda ;Desactivar modo onda y activar modo buzzer
bsf Buzzer
movlw Dig1Access
movwf FSR ;Cargar acceso indirecto para volver a leer el primer digito de acceso
goto Loop ;Volver al Loop
;//////////////////////
Lo programé "on the fly"(al vuelo), es decir que puede que haya errores y obviamente falta la parte de configuración inicial,etc...espero que lo estudies meticulosamente para poder comprender la idea que desarrollé acá. No es fácil si no sabes de assembly, pero con hoja, papel y mejor aún un buen simulador se puede.
Saludos.