; LCD_CTRL.ASM
;
; Provides a collection of routines to output to serial LCD at 2400
; Baud inverted.  
;
; LCD_CLR - clears LCD 
; LCD_LINE1 - sets cursor to beginning of line 1.
; LCD_LINE2 - sets cursor to beginning of line 2.
; LCD_CHAR - displays character in W on LCD.
; LCD_VAL - converts value in W to two hex characters and displays on LCD.
;
; This file is intended to be inlcuded in another file which calls these
; functions.
;
; PORTA, Bit 1 (terminal 18) ------ TX ----------> to RX on Serial LCD
;
; Uses 7 variables 29 - 2F
;
; Copyright, Peter H. Anderson, Morgan State University, June 14, '97

 
;	LIST p=16c84	; these lines not required when included in 
;			; another file
;	#include <c:\mplab\p16c84.inc>	
;	__CONFIG 11h
	

	CONSTANT _MAX_VAR=2FH

	CONSTANT TX=1	; PORTA, Bit 1

_SER_DATA EQU _MAX_VAR-0
_SER_LOOP EQU _MAX_VAR-1
_SER_TIME EQU _MAX_VAR-2

_TEMP1 EQU _MAX_VAR-3
_TEMP2 EQU _MAX_VAR-4

_SAVE_W EQU _MAX_VAR-5
_SAVE_STAT EQU _MAX_VAR-6

	ORG 380H

LCD_CLR:			; clears LCD panel
	MOVWF _SAVE_W		; save W and STATUS
	SWAPF STATUS, W
	MOVWF _SAVE_STAT

	BSF STATUS, RP0		; this was a natural place 
	BCF TRISA, TX		; to make TX bit an output
	BCF STATUS, RP0
	BCF PORTA, TX		; set to stop bit

	MOVLW   .255
        MOVWF	_SER_TIME    	; be sure stop bit has been high present
_LCD_CLR1:			; for some time
	DECFSZ  _SER_TIME, F
	GOTO _LCD_CLR1
	
	MOVLW 0FEH		; send FE 01 to LCD
	CALL _SEROUT
	MOVLW 01H
	CALL _SEROUT

	SWAPF _SAVE_STAT, W	; restore STATUS
	MOVWF STATUS
	SWAPF _SAVE_W, F	; get back W without altering STATUS
	SWAPF _SAVE_W, W

	RETURN

LCD_LINE1:			; causes cursor to go to beginning of
line1
	MOVWF _SAVE_W		; save W and STATUS
	SWAPF STATUS, W
	MOVWF _SAVE_STAT

	MOVLW 0FEH		; FE 80
	CALL _SEROUT
	MOVLW 80H
	CALL _SEROUT

	SWAPF _SAVE_STAT, W	; restore STATUS
	MOVWF STATUS
	SWAPF _SAVE_W, F	; get back W without altering STATUS
	SWAPF _SAVE_W, W

	RETURN

LCD_LINE2:			; same for line2
	MOVWF _SAVE_W		; save W and STATUS
	SWAPF STATUS, W
	MOVWF _SAVE_STAT

	MOVLW 0FEH		; FE %1100 0000
	CALL _SEROUT		;      ^ second line
	MOVLW 0C0H
	CALL _SEROUT

	SWAPF _SAVE_STAT, W	; restore STATUS
	MOVWF STATUS
	SWAPF _SAVE_W, F	; get back W without altering STATUS
	SWAPF _SAVE_W, W

	RETURN

LCD_VAL:	; converts byte in W to two characters and outputs
	MOVWF _SAVE_W		; save W and STATUS
	SWAPF STATUS, W
	MOVWF _SAVE_STAT

	MOVF _SAVE_W, W	; get back W
	MOVWF _TEMP1	; save a copy
	SWAPF _TEMP1, W	; high nibble now in lo nibble of W
	ANDLW 0FH	; 
	MOVWF _TEMP2	; copy to TEMP2
	SUBLW .9	; W = 9 - TEMP2		
	BTFSS STATUS, C	; TEMP2 > 9
	GOTO _ALPHA_HI	 

_NUMERIC_HI:
	MOVF _TEMP2, W	; get the original nibble
	ADDLW '0'	; add character 0
	GOTO _OUT_1_DIG_HI

_ALPHA_HI:
	MOVF _TEMP2, W
	ADDLW '0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_HI:

	CALL _SEROUT
			; now the lower nibble
	MOVF _TEMP1, W	; low nibble now in lo nibble of W
	ANDLW 0FH	; 
	MOVWF _TEMP2	; copy to TEMP2
	SUBLW .9	; W = 9 - TEMP2		
	BTFSS STATUS, C	; TEMP2 > 9
	GOTO _ALPHA_LO	 

_NUMERIC_LO:
	MOVF _TEMP2, W	; get the original nibble
	ADDLW '0'	; add character 0
	GOTO _OUT_1_DIG_LO

_ALPHA_LO:
	MOVF _TEMP2, W
	ADDLW '0'+7	; for 'A', 'B', 'C', 'D', 'E' and 'F'
	
_OUT_1_DIG_LO:

	CALL _SEROUT

	SWAPF _SAVE_STAT, W	; restore STATUS
	MOVWF STATUS
	SWAPF _SAVE_W, F	; get back W without altering STATUS
	SWAPF _SAVE_W, W

	RETURN

LCD_CHAR:	; outputs character in W to LCD
	MOVWF _SAVE_W		; save W and STATUS
	SWAPF STATUS, W
	MOVWF _SAVE_STAT

	MOVF _SAVE_W, W		; get back W
	CALL _SEROUT

	SWAPF _SAVE_STAT, W	; restore STATUS
	MOVWF STATUS
	SWAPF _SAVE_W, F	; get back W without altering STATUS
	SWAPF _SAVE_W, W

	RETURN

_SEROUT:			; transmits content of W at 2400 Baud

	MOVWF	_SER_DATA
	MOVLW 	.9
	MOVWF	_SER_LOOP
	BCF	STATUS, C	; set C to 0, start bit

_SEROUT1:
	BTFSC	STATUS, C
	BCF	PORTA, TX	; send a one
	BTFSS	STATUS, C
	BSF	PORTA, TX	; or a zero

	MOVLW   .135
        MOVWF	_SER_TIME     	; one bit delay.  416 usecs at 2400 baud
_SEROUT2:
	DECFSZ  _SER_TIME, F
        GOTO _SEROUT2
        NOP
	
	RRF	_SER_DATA, F	; least sign bit now in C
	DECFSZ	_SER_LOOP, F	; does not affect status
	GOTO 	_SEROUT1	; next character

	BCF	PORTA, TX	; send stop bit
	MOVLW   .135
        MOVWF	_SER_TIME    	; bit time delay, 416 uS at 2400 baud
_SEROUT3:
	DECFSZ  _SER_TIME, F
        GOTO _SEROUT3
        
	RETURN

	END