; RB4-DB4, RB5-DB5, RB6-DB6, RB7-DB7, RB3-ENABLE, RB0-RS, RA0-RW
;16 MHz


	list p=16F628 ; list directive to define processor
#include p16F628.inc ; processor specific variable definitions

	errorlevel -302 ; suppress message 302 from list file 
	__config _HS_OSC &_CP_OFF &_WDT_OFF &_MCLRE_OFF &_BODEN_OFF &_LVP_OFF

		cblock	0x20		;start of general purpose registers
			count			;used in looping routines
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			tmp1			;temporary storage
			tmp2
			templcd			;temp store for 4 bit mode
			templcd2
			kapcs
			endc

LCD_PORT	Equ	PORTB
LCD_TRIS	Equ	TRISB
SW_PORT		Equ	PORTA

LCD_RS		Equ	0x00			;LCD handshake lines
LCD_RW		Equ	0x00
LCD_E		Equ	0x03
SW1			Equ	0x02

		org	0x0000

		movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)

Initialise	
		clrf	PORTA
		clrf	PORTB
		clrf	count



SetPorts	
		bsf 	STATUS,		RP0	;select bank 1
		movlw	0x00			;make outputs
		movwf	TRISB
		movlw 	0xFF
		movwf	SW_PORT		;make inputs
		bcf 	STATUS,		RP0	
		call	Delay100 ; waiting for LCD	



		call	LCD_Init
		;call 	text
		call	text
ciklus	goto	ciklus
		

;inicializalas

;Initialise LCD
LCD_Init	
		movlw	b'0010'
		movwf	LCD_PORT
		call	Pulse_e		;Set 4 bit mode
		movlw	b'0000'
		movwf	LCD_PORT
		call	Pulse_e
		
		movlw	b'0010'			;Set display shift
		movwf	LCD_PORT
		call	Pulse_e
		movlw	b'1000'
		movwf	LCD_PORT
		call	Pulse_e
		movwf	LCD_PORT
		
		movlw	b'0000'	
		movwf	LCD_PORT		;Set display character mode
		call	Pulse_e
		movlw	b'0110'
		movwf	LCD_PORT
		call	Pulse_e
		
		movlw	b'0000'	
		movwf	LCD_PORT		;Set display on/off and cursor command
		call	Pulse_e
		movlw	b'1101'
		movwf	LCD_PORT
		call	Pulse_e
			
		movlw	b'0000'	
		movwf	LCD_PORT			;clear display
		call	Pulse_e
		movlw	b'0001'
		movwf	LCD_PORT
		call	Pulse_e

		retlw	0x00

; command set routine
LCD_Cmd
		movwf	templcd
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf		LCD_PORT, LCD_RS	;RS line to 0
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf		LCD_PORT, LCD_RS	;RS line to 0
		call	Pulse_e			;Pulse the E line high
		call 	Delay5

		retlw	0x00

LCD_Char	
		movwf	templcd			;display character in W register
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf		LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf		LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high
		call 	LCD_Busy
		retlw	0x00


LCD_Clr	
		movlw	b'00000001'			;Clear display
		call	LCD_Cmd
		retlw	0x00

		
Pulse_e		
		bsf	LCD_PORT, LCD_E
		nop
		bcf	LCD_PORT, LCD_E
		retlw	0x00

LCD_Busy
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x0f			;set Port for input
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		bcf	LCD_PORT, LCD_RS	;set LCD for command mode
		bsf	SW_PORT, LCD_RW	;setup to read busy flag
		bsf	LCD_PORT, LCD_E
		swapf	LCD_PORT, w		;read upper nibble (busy flag)
		bcf	LCD_PORT, LCD_E		
		movwf	templcd2 
		bsf	LCD_PORT, LCD_E		;dummy read of lower nibble
		bcf	LCD_PORT, LCD_E
		btfsc	templcd2, 7		;check busy flag, high = busy
		goto	LCD_Busy		;if busy check again
		bcf	SW_PORT, LCD_RW
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x00			;set Port for output
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		return

LCD_Line1

		movlw	0x80			;move to 1st row, first column
		call	LCD_Cmd
		retlw	0x00

LCD_Line2
		movlw	0xc0			;move to 2nd row, first column
		call	LCD_Cmd
		retlw	0x00

text	

		movlw	'D'
		call	LCD_Char
		movlw	0x45
		call	LCD_Char
		movlw	0x4E
		call	LCD_Char
		movlw	0x49
		call	LCD_Char
		movlw 	0x53
		call	LCD_Char
		movlw	0x5A
		call	LCD_Char	
		retlw	0x00

	

Delay255	
		movlw	0xff		;delay 255 mS
		goto	d0
Delay100
		movlw	d'100'		;delay 100mS
		goto	d0
Delay50		
		movlw	d'50'		;delay 50mS
		goto	d0
Delay20		
		movlw	d'20'		;delay 20mS
		goto	d0
Delay5		
		movlw	0x05		;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7			;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

		end