;-----------------------------------------------------------------------------------------------------------------
; RECICLADO DE TECLADOS DE PORTATIL
; Programado: J. Rubio
; www.tecnofilos.org
;-----------------------------------------------------------------------------------------------------------------
	list	P=16F84
ind		equ	00h
rtcc		equ	01h
pc		equ	02h
status		equ	03h
fsr		equ	04h
port_a		equ	05h
port_b		equ	06h
eedata		equ	08h
eeadr		equ	09h
eecon1		equ	08h
; Variables del programa
GS		equ	03h
count1		equ	0Dh
count2		equ	0Eh
columna 	equ	0Fh
dato_serie 	equ	10h
dato		equ	11h


D		equ	4h
Ck		equ	5h
Latch		equ	6h



A0		equ	0h
A1		equ	1h
A2		equ	2h
W		equ	0h
F		equ	1h

c		equ	0h
dc		equ	1h
z		equ	2h
pd		equ	3h
to		equ	4h
rp0		equ	5h
rp1		equ     6h
irp		equ	7h



	org	0
	goto	inicio
                
;----------------------------------------------------------------------
delay:
	            ;delay en ms según valor del acumulador (4 MHz clock).
	movwf	count1
d1	movlw	0xA5
	movwf	count2
d2	decfsz	count2	,f
	goto	d2
	decfsz	count1	,f
	goto	d1
	retlw	0x00

;-------------------------------------------------------------------------------------------------
EnviaSerie:
	movwf	dato_serie   ;dato_serie = W

	btfsc	dato_serie,0   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,0   ;si es uno se salta la siguiente instruccion
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,1   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,1
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,2   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,2
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,3   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,3
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,4   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,4
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,5   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,5
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop
	
	btfsc	dato_serie,6   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,6
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	btfsc	dato_serie,7   ;si es cero se salta la siguiente instruccion
	bsf	port_b,D
	btfss	dato_serie,7
	bcf	port_b,D
	bcf	port_b,Ck
	nop
	bsf	port_b,Ck	;Flanco de subida
	nop

	bcf	port_b,Latch    ;Validacion de tecla
	bsf	port_b,Latch
	movlw	0x1
	call	delay 	;retardo de 1 ms

	return
;----------------------------------------------------------------------
; Genera código de exploración numerados ordinalmente.
;-------------------------------------------------------------------------
ConvierteCodigo:
			
	movwf	dato	;dato = W

	movf	dato,W	;W = dato
	sublw	0x70
	btfsc	status,z
	retlw	0x00			;TECLA:Escape

	movf	dato,W	;W = dato
	sublw	0x50
	btfsc	status,z
	retlw	0x01			;TECLA: F1

	movf	dato,W	;W = dato
	sublw	0x40
	btfsc	status,z
	retlw	0x02			;TECLA: F2

	movf	dato,W	;W = dato
	sublw	0x30
	btfsc	status,z
	retlw	0x03			;TECLA: F3

	movf	dato,W	;W = dato
	sublw	0x21
	btfsc	status,z
	retlw	0x04			;TECLA: F4

	movf	dato,W	;W = dato
	sublw	0x07
	btfsc	status,z
	retlw	0x05			;TECLA: F5

	movf	dato,W	;W = dato
	sublw	0x17
	btfsc	status,z
	retlw	0x06			;TECLA: F6

	movf	dato,W	;W = dato
	sublw	0x67
	btfsc	status,z
	retlw	0x07			;TECLA: F7

	movf	dato,W	;W = dato
	sublw	0xC7
	btfsc	status,z
	retlw	0x08			;TECLA: F8

	movf	dato,W	;W = dato
	sublw	0xF7
	btfsc	status,z
	retlw	0x09			;TECLA: F9

	movf	dato,W	;W = dato
	sublw	0xE7
	btfsc	status,z
	retlw	0x0A			;TECLA: F10

	movf	dato,W	;W = dato
	sublw	0xD7
	btfsc	status,z
	retlw	0x0B			;TECLA: Bloq Num

	movf	dato,W	;W = dato
	sublw	0xB7
	btfsc	status,z
	retlw	0x0C			;TECLA: Im Pan

	movf	dato,W	;W = dato
	sublw	0xA7
	btfsc	status,z
	retlw	0x0D			;TECLA: Bloq Desp

	movf	dato,W	;W = dato
	sublw	0x97
	btfsc	status,z
	retlw	0x0E			;TECLA: Pausa

	movf	dato,W	;W = dato
	sublw	0x87
	btfsc	status,z
	retlw	0x0F			;TECLA: Insert

	movf	dato,W	;W = dato
	sublw	0x86
	btfsc	status,z
	retlw	0x10			;TECLA: Supr

	movf	dato,W	;W = dato
	sublw	0x54
	btfsc	status,z
	retlw	0x11			;TECLA: 1

	movf	dato,W	;W = dato
	sublw	0x44
	btfsc	status,z
	retlw	0x12			;TECLA: 2

	movf	dato,W	;W = dato
	sublw	0x34
	btfsc	status,z
	retlw	0x13			;TECLA: 3

	movf	dato,W	;W = dato
	sublw	0x24
	btfsc	status,z
	retlw	0x14			;TECLA: 4

	movf	dato,W	;W = dato
	sublw	0x04
	btfsc	status,z
	retlw	0x15			;TECLA: 5

	movf	dato,W	;W = dato
	sublw	0x64
	btfsc	status,z
	retlw	0x16			;TECLA: 6

	movf	dato,W	;W = dato
	sublw	0xC4
	btfsc	status,z
	retlw	0x17			;TECLA: 7

	movf	dato,W	;W = dato
	sublw	0xF4
	btfsc	status,z
	retlw	0x18			;TECLA: 8

	movf	dato,W	;W = dato
	sublw	0xE4
	btfsc	status,z
	retlw	0x19			;TECLA: 9

	movf	dato,W	;W = dato
	sublw	0xD4
	btfsc	status,z
	retlw	0x1A			;TECLA: 0

	movf	dato,W	;W = dato
	sublw	0xB4
	btfsc	status,z
	retlw	0x1B			;TECLA: ?

	movf	dato,W	;W = dato
	sublw	0xA4
	btfsc	status,z
	retlw	0x1C			;TECLA: ¿

	movf	dato,W	;W = dato
	sublw	0x84
	btfsc	status,z
	retlw	0x1D			;TECLA: Retroceso

	movf	dato,W	;W = dato
	sublw	0x73
	btfsc	status,z
	retlw	0x1E			;TECLA: Tabulador

	movf	dato,W	;W = dato
	sublw	0x43
	btfsc	status,z
	retlw	0x1F			;TECLA: Q

	movf	dato,W	;W = dato
	sublw	0x33
	btfsc	status,z
	retlw	0x20			;TECLA: W

	movf	dato,W	;W = dato
	sublw	0x23
	btfsc	status,z
	retlw	0x21			;TECLA: E

	movf	dato,W	;W = dato
	sublw	0x03
	btfsc	status,z
	retlw	0x22			;TECLA: R

	movf	dato,W	;W = dato
	sublw	0x13
	btfsc	status,z
	retlw	0x23			;TECLA: T

	movf	dato,W	;W = dato
	sublw	0x63
	btfsc	status,z
	retlw	0x24			;TECLA: Y

	movf	dato,W	;W = dato
	sublw	0xC3
	btfsc	status,z
	retlw	0x25			;TECLA: U

	movf	dato,W	;W = dato
	sublw	0xD3
	btfsc	status,z
	retlw	0x25			;TECLA: I

	movf	dato,W	;W = dato
	sublw	0xF3
	btfsc	status,z
	retlw	0x26			;TECLA: O

	movf	dato,W	;W = dato
	sublw	0xE3
	btfsc	status,z
	retlw	0x27			;TECLA: P

	movf	dato,W	;W = dato
	sublw	0xB3
	btfsc	status,z
	retlw	0x28			;TECLA: ^

	movf	dato,W	;W = dato
	sublw	0xA3
	btfsc	status,z
	retlw	0x29			;TECLA: *

	movf	dato,W	;W = dato
	sublw	0x83
	btfsc	status,z
	retlw	0x2A			;TECLA: ç

	movf	dato,W	;W = dato
	sublw	0x52
	btfsc	status,z
	retlw	0x2B			;TECLA: Bloq Mays

	movf	dato,W	;W = dato
	sublw	0x42
	btfsc	status,z
	retlw	0x2C			;TECLA: A

	movf	dato,W	;W = dato
	sublw	0x32
	btfsc	status,z
	retlw	0x2D			;TECLA: S

	movf	dato,W	;W = dato
	sublw	0x22
	btfsc	status,z
	retlw	0x2E			;TECLA: D

	movf	dato,W	;W = dato
	sublw	0x02
	btfsc	status,z
	retlw	0x2F			;TECLA: F

	movf	dato,W	;W = dato
	sublw	0x12
	btfsc	status,z
	retlw	0x30			;TECLA: G

	movf	dato,W	;W = dato
	sublw	0x62
	btfsc	status,z
	retlw	0x31			;TECLA: H

	movf	dato,W	;W = dato
	sublw	0xC2
	btfsc	status,z
	retlw	0x32			;TECLA: J

	movf	dato,W	;W = dato
	sublw	0xD2
	btfsc	status,z
	retlw	0x33			;TECLA: K

	movf	dato,W	;W = dato
	sublw	0xF2
	btfsc	status,z
	retlw	0x34			;TECLA: L

	movf	dato,W	;W = dato
	sublw	0xE2
	btfsc	status,z
	retlw	0x35			;TECLA: Ñ

	movf	dato,W	;W = dato
	sublw	0xB2
	btfsc	status,z
	retlw	0x36			;TECLA: ¨

	movf	dato,W	;W = dato
	sublw	0x82
	btfsc	status,z
	retlw	0x37			;TECLA: Intro

	movf	dato,W	;W = dato
	sublw	0x36
	btfsc	status,z
	retlw	0x38			;TECLA: Shift Izq.

	movf	dato,W	;W = dato
	sublw	0x26
	btfsc	status,z
	retlw	0x39			;TECLA: Z

	movf	dato,W	;W = dato
	sublw	0x06
	btfsc	status,z
	retlw	0x3A			;TECLA: X

	movf	dato,W	;W = dato
	sublw	0x25
	btfsc	status,z
	retlw	0x3B			;TECLA: C

	movf	dato,W	;W = dato
	sublw	0x05
	btfsc	status,z
	retlw	0x3C			;TECLA: V

	movf	dato,W	;W = dato
	sublw	0x15
	btfsc	status,z
	retlw	0x3D			;TECLA: B

	movf	dato,W	;W = dato
	sublw	0x76
	btfsc	status,z
	retlw	0x3E			;TECLA: N

	movf	dato,W	;W = dato
	sublw	0xC5
	btfsc	status,z
	retlw	0x3F			;TECLA: M

	movf	dato,W	;W = dato
	sublw	0xA5
	btfsc	status,z
	retlw	0x40			;TECLA: ;

	movf	dato,W	;W = dato
	sublw	0xB5
	btfsc	status,z
	retlw	0x41			;TECLA: :

	movf	dato,W	;W = dato
	sublw	0x85
	btfsc	status,z
	retlw	0x42			;TECLA: Shift Der.

	movf	dato,W	;W = dato
	sublw	0x95
	btfsc	status,z
	retlw	0x43			;TECLA: Flecha Arriba

	movf	dato,W	;W = dato
	sublw	0xB6
	btfsc	status,z
	retlw	0x44			;TECLA: ª

	movf	dato,W	;W = dato
	sublw	0x75
	btfsc	status,z
	retlw	0x45			;TECLA: Fn

	movf	dato,W	;W = dato
	sublw	0x45
	btfsc	status,z
	retlw	0x46			;TECLA: Control

	movf	dato,W	;W = dato
	sublw	0x51
	btfsc	status,z
	retlw	0x47			;TECLA: Alt

	movf	dato,W	;W = dato
	sublw	0x61
	btfsc	status,z
	retlw	0x48			;TECLA: >

	movf	dato,W	;W = dato
	sublw	0x71
	btfsc	status,z
	retlw	0x49			;TECLA: Barra Espaciadora

	movf	dato,W	;W = dato
	sublw	0xE5
	btfsc	status,z
	retlw	0x4A			;TECLA: -

	movf	dato,W	;W = dato
	sublw	0xD6
	btfsc	status,z
	retlw	0x4B			;TECLA: Alt Gr

	movf	dato,W	;W = dato
	sublw	0xA6
	btfsc	status,z
	retlw	0x4C			;TECLA: Flecha Izq.

	movf	dato,W	;W = dato
	sublw	0x96
	btfsc	status,z
	retlw	0x4D			;TECLA: Flecha Abajo.

	movf	dato,W	;W = dato
	sublw	0x81
	btfsc	status,z
	retlw	0x4E			;TECLA: Flecha Derecha.

	return

;******************************************************************************
;                                   INICIO
;******************************************************************************
;
inicio:
	bcf	status,rp1
        clrf    port_a          ;instruction, write, enable low.
	movlw	b'00000000'
	tris	port_a		;Todo Salidas.

	clrf	port_b
	movlw	b'00001111'
	tris	port_b		;RB0-3 Entradas, resto salidas.

	movlw	0x00		;pone a cero el contador de columnas
	movwf	columna
	bcf	port_b,D
	bcf	port_b,Ck
	bcf	port_b,Latch

ciclo:				;Comienza el ciclo de refresco del teclado.
	movf	columna,W       ;W = columna
	movwf	port_a
	movlw	0x01
	call	delay         ;espera 1 ms

leetecla:
	
	btfss	port_b,GS	;si GS = 0 entoces salta  a la subrutina de pulsada.
	goto 	pulsada

	incf	columna	
	goto ciclo

;-------------------------------------------------------------------------------------------------
;	Tratamiento de la pulsación de una tecla.
;-------------------------------------------------------------------------------------------------
pulsada:	;llega aquí si se ha pulsado una tecla
	movf	port_b,W	;W=port_b
	xorlw	b'00000111'     ;complementa los bits 0-3
	andlw	b'00000111'	;pone a cero todos los bits menos 0-3
	movwf	dato		;dato=0 0 0 0 0 A2 A1 A0

	swapf	columna,W	
	andlw	b'11110000'	;W = C3 C2 C1 C0 0 0 0 0
	
	iorwf	dato,W		;W = dato OR columna(con los nibbles intercambiados)
				;En W tenemos nibble superior columna y nibble inferior dato.
	
	call	ConvierteCodigo
	call	EnviaSerie

	bcf	port_b,Latch 	;Latch = 0
	bsf	port_b,Latch	;Latch = 1 durante 1 ms
	movlw	0x01
	call	delay
	bcf	port_b,Latch    ;saca la validacion
	

	movlw	0x64   ;espera 100ms para eliminar rebotes.
	call	delay	

	goto	leetecla
	end



