;*********************************************************************************************************
;************************************   Xiamen DISPLAY   *************************************************
;*********************************************************************************************************

	list p=16f76
	include "p16f76.inc"
	errorlevel -302 ; supress "register not in bank0, check page bits" message
	__CONFIG _PWRTE_OFF & _BODEN_OFF &_HS_OSC & _WDT_OFF

#DEFINE lcd_RS		PORTA, 0		;LCD Register Select
#DEFINE lcd_RW		PORTA, 1		;LCD Read/Write
#DEFINE lcd_E		PORTA, 2		;LCD Enable
#DEFINE lcd_LED		PORTA, 3		;LCD Reset
#DEFINE lcd_DAT		PORTB

J		equ	0x20
K		equ	0x21
PDel0	equ	0x22
PDel1	equ	0x23
PDel2	equ	0x24
PDel3	equ	0x25
Dig		equ	0x26

		org		0x00		;Program start
		goto	INICIO

;*****************************************************************************************
;Main program
;*****************************************************************************************
INICIO:
		clrf	STATUS
		bsf		STATUS,RP0	;Change to Bank 1
		movlw	0x06
		movwf	ADCON1
	    movlw   0x00    	;Set w = 00000000
    	movwf   PORTA  		;Set PORTA & PORTB as outputs
    	movwf   PORTB
		bcf		STATUS,RP0	;Change to Bank 0

		call	LCD_INI

		CLRF    Dig			;Pone a 0 la variable digito                              
REPETIR	MOVF    Dig,w		;W=Digito
		CALL    DATO_1		;Coge el caracter
		IORLW   0			;Compara
		BTFSC   STATUS,2	;Es el ultimo?
		GOTO    acabar		;Si
		CALL    LCD_DAT		;Visualiza caracter
		CALL	lcd_data
		INCF    Dig,f		;Incrementa numero de Digito
		GOTO    REPETIR		;Vuelve a escribir

acabar	nop
		goto	acabar		;Buclee infinito

;*****************************************************************************************
;Subroutines
;*****************************************************************************************
LCD_INI:
	clrf	PORTA		;PORTA = w = 00000000
	clrf	PORTB		;PORTB = w = 00000000

	call	Delay_32ms
	movlw   0x38		;Function Set
	movwf   lcd_DAT		;Place data in PORTB
	call	LCD_CMD

	call	Delay_5us
	movlw   0x0C		;Display ON/OFF Control
	movwf   lcd_DAT		;Place data in PORTB
	call	LCD_CMD

	call	Delay_5us
	movlw   0x01		;Clear Display
	movwf   lcd_DAT		;Place data in PORTB
	call	LCD_CMD

	call	Delay_2ms
	movlw   0x06		;Entry Mode Set
	movwf   lcd_DAT		;Place data in PORTB
	call	LCD_CMD
	return

LCD_E:
	bsf		lcd_E
	nop
	bcf		lcd_E
	return

LCD_BUSY:
	bsf		lcd_RW
	bsf		STATUS,RP0	;Change to Bank 1
	movlw	0xff
    movwf   PORTB
	bcf		STATUS,RP0	;Change to Bank 0
	bsf		lcd_E
	BSF		lcd_RW			;MODO LECTURA
	BCF		lcd_RS			;MODO COMANDO

LCD_CMD:
	bcf		lcd_E		;E=0
	bcf		lcd_RW		;Activate Write operation RW=0
	bcf		lcd_RS		;RS=0

	bsf		lcd_E		;E=1
	bcf		lcd_E		;E=0

	return

LCD_DAT:
	bcf		lcd_E		;E=0
	bcf		lcd_RW		;Activate Write operation RW=0
	bsf		lcd_RS		;RS=1
	movwf	PORTB
	call	LCD_BUSY
	bsf		lcd_RW		;RW=1
	bsf		lcd_E		;E=1
	bcf		lcd_E		;E=0
	return

;*****************************************************************************************
;Send Data to LCD Subroutine
;*****************************************************************************************
lcd_data:
	bcf		lcd_E		;E=0
	bcf		lcd_RW		;Activate Write operation RW=0
	bsf		lcd_RS		;RS=1

	bsf		lcd_E		;E=1
	bcf		lcd_E		;E=0

	return

;*****************************************************************************************
;Delay 5 useg subroutine
;*****************************************************************************************
Delay_5us:
	goto D1         ; 2 ciclos delay
D1  goto D2         ; 2 ciclos delay
D2  goto D3         ; 2 ciclos delay
D3  goto D4         ; 2 ciclos delay
D4  goto D5         ; 2 ciclos delay
D5  
	return            ; 2+2 Fin.

;*****************************************************************************************
;Delay 2 mseg subroutine
;*****************************************************************************************
Delay_2ms:
		movlw     .5        ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .159      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        return              ; 2+2 Fin.

;*****************************************************************************************
;Delay 50 mseg subroutine
;*****************************************************************************************
Delay_32ms:
		movlw     .89       ; 1 set numero de repeticion  (B)
		movwf     PDel2     ; 1 |
PLoop3  movlw     .143      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3                      ; 1 ciclo delay
        return              ; 2+2 Fin.

;<<<<<<---------------------- TABLA DE DATOS ------------------------->>>>>>> 
                                                                   
DATO_1          ADDWF   PCL,1                  
                RETLW   'H'             
                RETLW   'O'
                RETLW   'L'           
                RETLW   'A'           
                RETLW   ' '           
                RETLW   'M'           
                RETLW   'U'           
                RETLW   'N'           
                RETLW   'D'           
                RETLW   'O'           
                RETLW 	0x00           
	end
