;LCD control test program

	INCLUDE"p16F84A.inc"
	list p=16F84A

	__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF

Memory	EQU	0x0C	
DX	EQU	Memory+0	; "DX" File Register for LCD
DXX	EQU	Memory+1	; "DXX" File Register for LCD
WORK1	EQU	Memory+2	; File Register for Cursor Position (1st line)
WORK2	EQU	Memory+3	; File Register for Cursor Position (2nd line)
TIME1	EQU	Memory+4
TIME2	EQU	Memory+5

CHARA	EQU	Memory+6
CUR1 	EQU	Memory+7
CUR2	EQU	Memory+8

	ORG	0
	GOTO	START
	ORG	4

START

	MOVLW	0x41	;Chara Code "A"
	MOVWF	CHARA
	MOVLW	B'10000000'
	MOVWF	CUR1	;Cursor position(1st line)
	MOVLW	B'11000000'
	MOVWF	CUR2	;Cursor position(2nd line)

;------------Port Setting-----------------------
	BSF	STATUS, RP0	;selection of Bank1
	MOVLW	0x00
	MOVWF	TRISA	;PORTA: output
	MOVLW	B'00000111'
	MOVWF	TRISB	;RB0-2: input, RB3-7: output
	BCF	STATUS, RP0	;selection of Bank0
;-----------------------------------------------


;-----------------------------------------------
	CALL	ini_lcd	;Initialization
;-----------------------------------------------

	MOVF	CUR1,0
	MOVWF	WORK1	;Cursor position on the 1st line
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR	;Chara. on the initial position(1st line)

	MOVF	CUR2,0
	MOVWF	WORK2	;Cursor position on the 2nd line
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR	;Chara. on the initial position(2nd line)
;-----------------------------------------------

;------------------Main Routine-----------------
LOOP1	BTFSS	PORTB,0	;If RB0 = 1 then skip next line
	CALL	MOV1    	;           else CALL MOV1
	BTFSS	PORTB,1	;If RB1 = 1 then skip next line
	CALL	MOV2	;           else CALL MOV2
	BTFSS	PORTB,2	;If RB1 = 3 then skip next line
	CALL	MOV3	;           else CALL MOV3
	GOTO	LOOP1
;-----------------------------------------------

;-----Shift of "Chara" on the 1st line to the next position on the right----------
MOV1	MOVF	WORK1,0	;Cursor on the 1st line
	CALL	SETMODE
	MOVLW	0x20	;0x20 = " ", Erase of character
	CALL	PUTCHAR

	INCF	WORK1,1	;Cursor -> Next position on the right hand side
	MOVF	WORK1,0
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR	;Displaying Chara. routine

	MOVLW	D'300'	;Waiting routine
	call	wait_ms
	RETURN
;---------------------------------------------------

;-----Shift of "Chara" on the 2ND line to the next position on the right----------
MOV2	MOVF	WORK2,0	;Cursor on the 2nd line
	CALL	SETMODE
	MOVLW	0x20
	CALL	PUTCHAR	

	INCF	WORK2,1
	MOVF	WORK2,0
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR

	MOVLW	D'300'
	call	wait_ms
	RETURN
;---------------------------------------------------

;-----Shift of "Chara" to the original position----------
MOV3	MOVF	WORK1,0
	CALL	SETMODE
	MOVLW	0x20	; 0x20 = " " (Blank)
	CALL	PUTCHAR

	MOVF	WORK2,0
	CALL	SETMODE
	MOVLW	0x20	; 0x20 = " "
	CALL	PUTCHAR

	MOVF	CUR1,0
	MOVWF	WORK1	;Cursor position on the 1st line
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR	

	MOVF	CUR2,0
	MOVWF	WORK2	;Cursor position on the 2nd line
	CALL	SETMODE
	MOVF	CHARA,0	;Chara Code -> Working Register
	CALL 	PUTCHAR	
	
	MOVLW	D'300'
	call	wait_ms
	RETURN
;---------------------------------------------------

;----------Cursor Pos. Setting Mode--------------------
SETMODE	BCF	PORTA,1		;RS = 0 (LCD: Cursor position setting mode)
	MOVWF	DXX
	CALL	WR_LCD4
	RETURN

;----Character Display Sub Program-----------
PUTCHAR	BSF	PORTA,1		;RS =1 (LCD: Character writing mode)
	MOVWF	DXX
	CALL	WR_LCD4
	RETURN

WR_LCD4
	MOVF	DXX,0
	MOVWF	DX
	CALL	WR_LCD8
	SWAPF	DX,1
	CALL	WR_LCD8
	RETURN

WR_LCD8	MOVF	DX,0		;LCD mode setting and character writing routine
	MOVWF	PORTB
	NOP
	BSF	PORTA,0
	NOP
	BCF	PORTA,0
	MOVLW	D'20'
	call	wait_ms
	RETURN

;--------Waiting time Sub Program--------------
wait_ms	MOVWF	TIME1
STEPM	MOVLW	0xFF	
	MOVWF	TIME2
STEPM1	MOVLW	0xFF
	DECFSZ	TIME2,1
	GOTO	STEPM1
	DECFSZ	TIME1,1
	GOTO	STEPM
	RETURN


;--------Initialization-----------------
ini_lcd	MOVLW	D'255'
	call	wait_ms
	MOVLW	B'00000000'
	MOVWF	PORTA
	MOVLW	B'00110000'
	MOVWF	DX
	CALL	WR_LCD8
	MOVLW	D'255'
	call	wait_ms
	MOVLW	B'00110000'
	MOVWF	DX
	CALL	WR_LCD8
	MOVLW	D'255'
	call	wait_ms
	MOVLW	B'00110000'
	MOVWF	DX
	CALL	WR_LCD8
	
	MOVLW	B'00100000'
	MOVWF	DX
	CALL	WR_LCD8
	MOVLW	B'00101000'
	MOVWF	DXX
	CALL	WR_LCD4
	MOVLW	B'00000001'
	MOVWF	DXX
	CALL	WR_LCD4
	MOVLW	D'255'
	call	wait_ms
	MOVLW	B'00000110'
	MOVWF	DXX
	CALL	WR_LCD4
	MOVLW	B'00001110'
	MOVWF	DXX
	CALL	WR_LCD4
	RETURN

	END


