; Copia docente con correcciones de etiquetas/exportacion. Original: proyecto 2526.P2.1.
; No compilada con TI CCS ni validada en hardware durante esta revision.
;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file
            
;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section.
            .retainrefs                     ; And retain any sections that have
                                            ; references to current section.

SEGERR		.equ	-1

			.global lcda2seg, lcdIni, lcdPintaIzq, lcdPintaDer, lcdBorra, lcdBorraTodo, lcdBateria, lcdIconos, lcdInterDigito, lcdTest

;Posición de los dígitos en la memoria de vídeo
DIG1		.equ	LCDM10
DIG2		.equ	LCDM6
DIG3		.equ	LCDM4
DIG4		.equ	LCDM19
DIG5		.equ	LCDM15
DIG6		.equ	LCDM8

;Caracteres definidos en la tabla de conversión
PRIMERO		.equ	' '
ULTIMO		.equ	127

;-------------------------------------------------------------------------------
; void lcdIni (void)
;-------------------------------------------------------------------------------
lcdIni		;Conectar puertos del LCD con el exterior
			mov.w	#0xFFD0, &LCDCPCTL0
			mov.w	#0xFC3F, &LCDCPCTL1
			mov.w	#0x00F8, &LCDCPCTL2

			;Reloj=ACLK, Divisor=2, Predivisor=16, 4MUX, Low power
			mov.w	#LCDDIV_1 | LCDPRE__16 | LCD4MUX | LCDLP, &LCDCCTL0;

 			;VLCD=2'6 interno, V2-V5 interno, V5=0, charge pump con referencia interna
 			mov.w	#VLCD_1 | VLCDREF_0 | LCDCPEN, &LCDCVCTL
 			;Habilitar sincronización de reloj
 			mov.w	#LCDCPCLKSYNC, &LCDCCPCTL
 			mov.w	#LCDCLRM, &LCDCMEMCTL	;Borrar memoria del LCD

			bis.w	#LCDON, &LCDCCTL0		;Encender LCD_C
			ret


;-------------------------------------------------------------------------------
; void lcdPintaIzq (char c);
;-------------------------------------------------------------------------------
lcdPintaIzq	call	#lcda2seg				;Obtener código de 14 segmentos
			cmp.w	#SEGERR, r12			;Si el carácter está fuera de rango, salir sin hacer nada
			jeq		lcdPintaIzqFin

			mov.b	#BIT2|BIT0, r13
			;DIG1 <- DIG2
			mov.b	&DIG2, &DIG1
			xor.b	&DIG2+1, &DIG1+1
			and.b	r13, &DIG1+1
			xor.b	&DIG2+1, &DIG1+1
			;DIG2 <- DIG3
			mov.b	&DIG3, &DIG2
			xor.b	&DIG3+1, &DIG2+1
			and.b	r13, &DIG2+1
			xor.b	&DIG3+1, &DIG2+1
			;DIG3 <- DIG4
			mov.b	&DIG4, &DIG3
			xor.b	&DIG4+1, &DIG3+1
			and.b	r13, &DIG3+1
			xor.b	&DIG4+1, &DIG3+1
			;DIG4 <- DIG5
			mov.b	&DIG5, &DIG4
			xor.b	&DIG5+1, &DIG4+1
			and.b	r13, &DIG4+1
			xor.b	&DIG5+1, &DIG4+1
			;DIG5 <- DIG6
			mov.b	&DIG6, &DIG5
			xor.b	&DIG6+1, &DIG5+1
			and.b	r13, &DIG5+1
			xor.b	&DIG6+1, &DIG5+1
			;DIG6 <- c
			mov.b	r12, &DIG6			;Escribir segmentos a-m
			swpb	r12					;Acceder al byte alto
			xor.b	&DIG6+1, r12		;Escribir resto de segmentos respetando los especiales
			bic.b	r13, r12
			xor.b	&DIG6+1, r12
			mov.b	r12, &DIG6+1
lcdPintaIzqFin	ret


;-------------------------------------------------------------------------------
; void lcdPintaDer (char c);
;-------------------------------------------------------------------------------
lcdPintaDer	call	#lcda2seg			;Obtener código de 14 segmentos
			cmp.w	#SEGERR, r12			;Si el carácter está fuera de rango, salir sin hacer nada
			jeq		lcdPintaDerFin

			mov.b	#BIT2|BIT0, r13
			;DIG6 <- DIG5
			mov.b	&DIG5, &DIG6
			xor.b	&DIG5+1, &DIG6+1
			and.b	r13, &DIG6+1
			xor.b	&DIG5+1, &DIG6+1
			;DIG5 <- DIG4
			mov.b	&DIG4, &DIG5
			xor.b	&DIG4+1, &DIG5+1
			and.b	r13, &DIG5+1
			xor.b	&DIG4+1, &DIG5+1
			;DIG4 <- DIG3
			mov.b	&DIG3, &DIG4
			xor.b	&DIG3+1, &DIG4+1
			and.b	r13, &DIG4+1
			xor.b	&DIG3+1, &DIG4+1
			;DIG3 <- DIG2
			mov.b	&DIG2, &DIG3
			xor.b	&DIG2+1, &DIG3+1
			and.b	r13, &DIG3+1
			xor.b	&DIG2+1, &DIG3+1
			;DIG2 <- DIG1
			mov.b	&DIG1, &DIG2
			xor.b	&DIG1+1, &DIG2+1
			and.b	r13, &DIG2+1
			xor.b	&DIG1+1, &DIG2+1
			;DIG1 <- c
			mov.b	r12, &DIG1			;Escribir segmentos a-m
			swpb	r12					;Acceder al byte alto
			xor.b	&DIG1+1, r12		;Escribir resto de segmentos respetando los especiales
			bic.b	r13, r12
			xor.b	&DIG1+1, r12
			mov.b	r12, &DIG1+1
lcdPintaDerFin	ret

;-------------------------------------------------------------------------------
; void lcdBorra (void)
;-------------------------------------------------------------------------------
lcdBorra	mov.w	#BIT2|BIT0, r12
			clr.b	&DIG1
			and.b	r12, &DIG1+1
			clr.b	&DIG2
			and.b	r12, &DIG2+1
			clr.b	&DIG3
			and.b	r12, &DIG3+1
			clr.b	&DIG4
			and.b	r12, &DIG4+1
			clr.b	&DIG5
			and.b	r12, &DIG5+1
			clr.b	&DIG6
			and.b	r12, &DIG6+1
			ret

;-------------------------------------------------------------------------------
; void lcdBorraTodo (void)
;-------------------------------------------------------------------------------
lcdBorraTodo
			mov.w	#LCDCLRM, &LCDCMEMCTL	;Borrar memoria del LCD
			ret

;-------------------------------------------------------------------------------
; uint8_t lcdBateria (uint8_t map)
;-------------------------------------------------------------------------------
lcdBateria	mov.w	#TabIcBat, r13
			jmp		MapIconos

;-------------------------------------------------------------------------------
; uint8_t lcdIconos (uint8_t map)
;-------------------------------------------------------------------------------
lcdIconos	mov.w	#TabIconos, r13
			jmp		MapIconos

;-------------------------------------------------------------------------------
; uint8_t lcdInterDigito (uint8_t map)
;-------------------------------------------------------------------------------
lcdInterDigito
			mov.w	#TabIcIntDig, r13
			jmp		MapIconos

;-------------------------------------------------------------------------------
; void lcdTest (void)
;-------------------------------------------------------------------------------
lcdTest		mov.w	#LCDM1, r12
lcdTestBuc	mov.b	#255, 0(r12)
			inc.w	r12
			cmp.w	#LCDM22+1, r12
			jlo		lcdTestBuc
			ret

;****************
; Objetos locales
;****************

;*******************************************************************************************************
; uint8_t MapIconos (uint8_t map, uint32_t *tab)
;
; Servicio general de mapeado de iconos en un byte. map es el paquete de iconos a establecer.
; tab es un puntero a la tabla de descripción de posición de los iconos. Se trata de un vector de 8 palabras largas
; en el que la palabra baja es la dirección del registro de E/S en el que está el bit y la palabra alta es una máscara
; en la que se encuentra el bit. Se devuelve el valor anterior de los mismos bits por R12.
; Gracias a ella se pueden hacer distintos servicios de mapeado de iconos cambiando la dirección de la tabla
;*******************************************************************************************************
MapIconos	mov.b	#8, r11					;R11 variable control de bucle. Son 8 bits
MapIcBuc	mov.w	@r13+, r14				;R14 es la dirección del registro de E/S
			mov.w	@r13+, r15				;R15 es el bit a leer/escribir
			bit.b	r15, 0(r14)				;Copiar el bit en el carry
			rrc.b	r12						;Ensamblar bits leídos en R12 por izqda y sacar un bit a escribir por dcha
			jc		MapIcSet1				;Es 1? Escribir 1
MapIcSet0	bic.b	r15, 0(r14)				;...no. Escribir 0
			jmp		MapIcFinBuc
MapIcSet1	bis.b	r15, 0(r14)				;Escribir 1
MapIcFinBuc	dec.b	r11						;Un bit menos
			jnz		MapIcBuc				;Quedan? Sí, seguir
			ret

;*******************************************************************************************************
; lcda2seg
;*******************************************************************************************************
lcda2seg	mov.b	r12, r13			;Quedarse sólo con LSB
			sub.b	#PRIMERO, r13		;r13 es el índice en la tabla
			jn		lcda2segErr
			cmp.b	#ULTIMO-PRIMERO+1, r13
			jge		lcda2segErr
			rla.w	r13					;r13 es el desplazamiento
			mov.w	Tab14Seg(r13),r12	;Información de 14 segmentos en r12
			jmp		lcda2segFin
lcda2segErr	mov.w	#SEGERR, r12
lcda2segFin	ret

;-------------------------------------------------------------------------------
; Tabla de iconos de la batería
;-------------------------------------------------------------------------------
TabIcBat	.word	LCDM18, BIT5			;B1
			.word	LCDM14, BIT5 			;B2
			.word	LCDM18, BIT6 			;B3
			.word	LCDM14, BIT6 			;B4
			.word	LCDM18, BIT7 			;B5
			.word	LCDM14, BIT7 			;B6
			.word	LCDM18, BIT4 			;[    ]
			.word	LCDM14, BIT4 			; +

;-------------------------------------------------------------------------------
; Tabla de iconos generales
;-------------------------------------------------------------------------------
TabIconos	.word	LCDM3 , BIT0			;!
			.word	LCDM3 , BIT1 			;REC
			.word	LCDM3 , BIT2 			;HRT
			.word	LCDM3 , BIT3 			;TMR
			.word	LCDM9 , BIT0 			;Rx
			.word	LCDM5 , BIT2 			;Ant
			.word	LCDM9 , BIT2 			;Tx
			.word	LCDM16, BIT2 			;º

;-------------------------------------------------------------------------------
; Tabla de iconos interdígitos
;-------------------------------------------------------------------------------
TabIcIntDig	.word	LCDM11, BIT2			;NEG
			.word	LCDM11, BIT0 			;A1DP
			.word	LCDM7 , BIT0 			;A2DP
			.word	LCDM5 , BIT0 			;A3DP
			.word	LCDM20, BIT0 			;A4DP
			.word	LCDM16, BIT0 			;A5DP
			.word	LCDM20, BIT2 			;A4COL
			.word	LCDM7 , BIT2 			;A2COL

;-------------------------------------------------------------------------------
; Tabla de conversión de 14 segmentos
;-------------------------------------------------------------------------------
			;       abcdefgm   hjkpq-n-
Tab14Seg	.byte	00000000b, 00000000b	;Espacio
			.byte	00000000b, 00000000b	;!
			.byte	00000000b, 00000000b	;"
			.byte	00000000b, 00000000b	;#
			.byte	00000000b, 00000000b	;$
			.byte	00000000b, 00000000b	;%
			.byte	00000000b, 00000000b	;&
			.byte	00000000b, 00000000b	;'
			.byte	00000000b, 00000000b	;(
			.byte	00000000b, 00000000b	;)
			.byte	00000011b, 11111010b	;*
			.byte	00000011b, 01010000b	;+
			.byte	00000000b, 00000000b	;,
			.byte	00000011b, 00000000b	;-
			.byte	00000000b, 00000000b	;.
			.byte	00000000b, 00101000b	;/
			;       abcdefgm   hjkpq-n-
			.byte	11111100b, 00101000b	;0
			.byte	01100000b, 00100000b	;1
			.byte	11011011b, 00000000b	;2
			.byte	11110011b, 00000000b	;3
			.byte	01100111b, 00000000b	;4
			.byte	10110111b, 00000000b	;5
			.byte	10111111b, 00000000b	;6
			.byte	10000000b, 00110000b	;7
			.byte	11111111b, 00000000b	;8
			.byte	11100111b, 00000000b	;9
			.byte	00000000b, 00000000b	;:
			.byte	00000000b, 00000000b	;;
			.byte	00000000b, 00100010b	;<
			.byte	00010011b, 00000000b	;=
			.byte	00000000b, 10001000b	;>
			.byte	00000000b, 00000000b	;?
			;       abcdefgm   hjkpq-n-
			.byte	00000000b, 00000000b	;@
			.byte	01100001b, 00101000b	;A
			.byte	11110001b, 01010000b	;B
			.byte	10011100b, 00000000b	;C
			.byte	11110000b, 01010000b	;D
			.byte	10011110b, 00000000b	;E
			.byte	10001110b, 00000000b	;F
			.byte	10111101b, 00000000b	;G
			.byte	01101111b, 00000000b	;H
			.byte	10010000b, 01010000b	;I
			.byte	01111000b, 00000000b	;J
			.byte	00001110b, 00100010b	;K
			.byte	00011100b, 00000000b	;L
			.byte	01101100b, 10100000b	;M
			.byte	01101100b, 10000010b	;N
			.byte	11111100b, 00000000b	;O
			;       abcdefgm   hjkpq-n-
			.byte	11001111b, 00000000b	;P
			.byte	11111100b, 00000010b	;Q
			.byte	11001111b, 00000010b	;R
			.byte	10110111b, 00000000b	;S
			.byte	10000000b, 01010000b	;T
			.byte	01111100b, 00000000b	;U
			.byte	01100000b, 10000010b	;V
			.byte	01101100b, 00001010b	;W
			.byte	00000000b, 10101010b	;X
			.byte	00000000b, 10110000b	;Y
			.byte	10010000b, 00101000b	;Z
			.byte	10011100b, 00000000b	;[
			.byte	00000000b, 10000010b	;\
			.byte	11110000b, 00000000b	;]
			.byte	01000000b, 00100000b	;^
			.byte	00010000b, 00000000b	;_
			;       abcdefgm   hjkpq-n-
			.byte	00000000b, 10000000b	;`
			.byte	00011010b, 00010000b	;a
			.byte	00111111b, 00000000b	;b
			.byte	00011011b, 00000000b	;c
			.byte	01111011b, 00000000b	;d
			.byte	00011010b, 00001000b	;e
			.byte	10001110b, 00000000b	;f
			.byte	11110111b, 00000000b	;g
			.byte	00101111b, 00000000b	;h
			.byte	00000000b, 00010000b	;i
			.byte	01110000b, 00000000b	;j
			.byte	00000000b, 01110010b	;k
			.byte	00000000b, 01010000b	;l
			.byte	00101011b, 00010000b	;m
			.byte	00100001b, 00010000b	;n
			.byte	00111011b, 00000000b	;o
			;       abcdefgm   hjkpq-n-
			.byte	00001110b, 10000000b	;p
			.byte	11100111b, 00000000b	;q
			.byte	00000001b, 00010000b	;r
			.byte	00010001b, 00000010b	;s
			.byte	00000011b, 01010000b	;t
			.byte	00111000b, 00000000b	;u
			.byte	00100000b, 00000010b	;v
			.byte	00101000b, 00001010b	;w
			.byte	00000000b, 10101010b	;x
			.byte	01110001b, 01000000b	;y
			.byte	00010010b, 00001000b	;z
			.byte	00000000b, 00000000b	;{
			.byte	00000000b, 00000000b	;|
			.byte	00000000b, 00000000b	;}
			.byte	00000000b, 00000000b	;~
			.byte	00000000b, 00000000b	;
