; 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
;
; 10 msec pacing delay between characters sent to the LCD.
;
; Copyright, Peter H. Anderson, Morgan State University, June 14, '97
; Added 10 msec timing and trisa to _SERIAL routine - July 22, '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

_LOOP1	EQU _MAX_VAR-1	; used for pace timing, same location as _SER_LOOP
_LOOP2	EQU _MAX_VAR-2	; used for pace timing, same location as _SER_TIME

	ORG 380H

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

	
	
	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
	CALL _DELAY10

	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

	BSF STATUS, RP0		; make TX bit an output 
	BCF TRISA, TX		; 
	BCF STATUS, RP0
	BCF PORTA, TX		; set to stop bit

	MOVLW   .255
        MOVWF	_SER_TIME    	; be sure stop bit has been high present
_SEROUT1:			; for some time
	DECFSZ  _SER_TIME, F
	GOTO _SEROUT1

	MOVLW 	.9
	MOVWF	_SER_LOOP

	BCF	STATUS, C	; set C to 0, start bit

_SEROUT2:
	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
_SEROUT3:
	DECFSZ  _SER_TIME, F
        GOTO _SEROUT3
        NOP
	
	RRF	_SER_DATA, F	; least sign bit now in C
	DECFSZ	_SER_LOOP, F	; does not affect status
	GOTO 	_SEROUT2	; next character

	BCF	PORTA, TX	; send stop bit
	CALL	_DELAY10	; 10 msecs between characters
        
	RETURN

_DELAY10:
	MOVLW .10	; 10 msec delay
	MOVWF _LOOP1
_DELAY_1:
	MOVLW	.110	; close to 1.0 msec delay when set to .110
	MOVWF 	_LOOP2
_DELAY_2:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ	_LOOP2, F	; decrement and leave result in LOOP2 
				; skip next statement if zero
	GOTO _DELAY_2
	DECFSZ 	_LOOP1, F
	GOTO _DELAY_1
	RETURN

	END