;------------------------------------------------------------
;		HD44780 LCD Display Support
;------------------------------------------------------------
; Display module connections:-
;
; PORTB 7 = D7
;       6 = D6
;       5 = D5
;       4 = D4
;       3 = E
;       2 = RS 
;       1 
;       0


;------------------------------------------------------------
; Set LCD Controller to 4 Bit Data Mode 
;
; The Controller starts in 8 bit mode, but we can 
; only send the upper 4 bits. Luckily this is enough 
; to enable 4 bit mode, but the bits for number of 
; lines and matrix size are undefined. Therefore 
; after selecting 4 bit mode we have to send the 
; command again! 
;
set_4bit_mode
        movlw   B'00101000'	; function set
        movwf   PORTB           ; (bits 0-3 are undefined!)
 	andlw	B'11110111'               
        movwf   PORTB                         
        call    delay50		; wait 50uS
        movlw   B'00101000'	; 4 bit mode 
        movwf   PORTB           ; function set (high nybble)               
	andlw	B'11110111'               
        movwf   PORTB                  
        call    delay50		; wait 50uS
	IF	LCD2LINE
        movlw   B'10001000'	; 2 lines, 5x7 matrix
	ELSE
        movlw   B'00001000'	; 1 line, 5x7 matrix
	ENDIF
        movwf   PORTB           ; function set (low nybble) 
	andlw	B'11110111'               
        movwf   PORTB                    
        goto    delay50		; wait 50uS        

;-------------------------------------------------
;           Clear the Display
;
clear_display
        movlw   B'00001000'
        movwf   PORTB                   
        bcf     PORTB,3                 
        call    delay50		; wait 50uS
        movlw   B'00011000'
        movwf   PORTB                   
	andlw	B'11110111'               
        movwf   PORTB    
	movlw	1                                
        goto    dx2k            ; Wait 2mS        

;---------------------------------------------------
; Initialise the Display Controller
;
init_display
        movlw   B'00001000'
        movwf   PORTB                   
        bcf     PORTB,3                 
        call    delay50		; wait 50uS
        movlw   B'11001000'
        movwf   PORTB       
	andlw	B'11110111'               
        movwf   PORTB                             
        goto    delay50		; wait 50uS

;-----------------------------------------------------
; Position Cursor in Display RAM address
;
; Input: W = address
;
ddram_adress
        bsf     PORTB,3                 
        movwf   ADRESS
        movwf   ADRESS2                 
        movlw   B'01110000'            
        andwf   ADRESS,1
        movlw   B'10001000'            
        iorwf   ADRESS,0               
        movwf   PORTB                
	andlw	B'11110111'               
        movwf   PORTB                         
        call    delay50		; wait 50uS
        bsf     PORTB,3             
        swapf   ADRESS2,F
        movlw   B'11110000'           
        andwf   ADRESS2,F
        movlw   B'00001000'           
        iorwf   ADRESS2,W          
        movwf   PORTB
	andlw	B'11110111'               
        movwf   PORTB                          
        goto    delay50		; wait 50uS

;---------------------------------------------------
; Show an ASCII Character on the LCD
;
; Input: W = character
;
prt_char:
        bsf     PORTB,3                 
        movwf   CHAR
        movwf   CHAR2             
        movlw   B'11110000'         
        andwf   CHAR,F
        movlw   B'00001100'      
        iorwf   CHAR,W             
        movwf   PORTB  
	andlw	B'11110111'               
        movwf   PORTB                   
        call    delay50		; wait 50uS
        swapf   CHAR2,F
        movlw   B'11110000'           
        andwf   CHAR2,F
        movlw   B'00001100'         
        iorwf   CHAR2,W                 
        movwf   PORTB                 
	andlw	B'11110111'               
        movwf   PORTB                     
delay50:
	movlw	12*(4000/CLKFRQ); wait 50uS		

;---------------------------------------------------
;              Short Delay
;
; Input:  W = delay count 
;
; Output: waits for (W*4)+4 cycles
;
dx4:
        movwf   dx_temp1
dx4_loop:
        decf    dx_temp1	;
        skpz			; 4 cycles
        goto    dx4_loop	;
	return


;---------------------------------------------------
;              Long Delay
;
; Input:  W = delay count 
;
; Output: waits for W*2000 cycles
;

dx2k:	movwf	dx_temp1
dx2k_1: movlw	(2000/250)
	movwf   dx_temp2		
dx2k_2:	movlw	61*(4000/CLKFRQ) 
	movwf   dx_temp3	
dx2k_3: decf	dx_temp3	 
        skpz						
        goto    dx2k_3			; 4uS per loop
	decf    dx_temp2	
        skpz			
        goto    dx2k_2		 	; 
	decf	dx_temp1
	skpz
	goto	dx2k_1
	return


