; 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
			Tmp0
			char
			
			endc
;RCREG		Equ	0x1A
SW_PORT		Equ	PORTA
LCD_TRIS	Equ	TRISB
LCD_PORT	Equ	PORTB
LCD_RS		Equ	0x00			;LCD handshake lines
LCD_E		Equ	0x03
SW1			Equ	0x02
LCD_RW		Equ	0x00

		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	b'00100010'
		movwf	TXSTA
		movlw	b'00000010'		;make outputs
		movwf	TRISB
		movlw 	b'11111110'
		movwf	PORTA		;make inputs
		;movlw	b'10010000'
		;movwf	RCSTA'
	; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw .51              ; .51=4800 bps (0, 0x19 - 9600 x0C=19200 bps)
        movwf SPBRG
        movlw b'00100000'       ; brgh = low (2)
        movwf TXSTA             ; enable Async Transmission, set brgh

        bcf STATUS,RP0          ; RAM PAGE 0

        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA 
	
		call	Delay50

		call 	LCD_Init
		call	LCD_Line1
		movf RCREG,W
        movf RCREG,W
        movf RCREG,W 
ciklus
		call 	fogad
		call 	LCD_Char
		goto ciklus
		
;Initialise LCD
LCD_Init
		movlw	0x20			;Set 4 bit mode
		call	LCD_Cmd

		movlw	0x28			;Set display shift
		call	LCD_Cmd

		movlw	0x06			;Set display character mode
		call	LCD_Cmd

		movlw	0x0d			;Set display on/off and cursor command
		call	LCD_Cmd

		call	LCD_Clr			;clear display

		retlw	0x00

; command set routine
LCD_Cmd		movwf	templcd
		;swapf	templcd,	w	;send upper nibble
		andlw	0xf0			;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
		movwf	templcd			;clear upper 4 bits of W
		swapf	templcd,	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
; text routine
; command set routine
LCD_Char
		movwf	templcd
		;swapf	templcd,	w	;send upper nibble
		andlw	0xf0			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf		LCD_PORT, LCD_RS	;RS line to 0
		call	Pulse_e			;Pulse the E line high
		movf	templcd,	w	;send lower nibble
		andlw	0x0f
		movwf	templcd			;clear upper 4 bits of W
		swapf	templcd,	w
		movwf	LCD_PORT
		bsf		LCD_PORT, LCD_RS	;RS line to 0
		call	Pulse_e			;Pulse the E line high
		bcf		LCD_PORT, LCD_RS
		call 	LCD_Busy
		retlw	0x00

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

LCD_Line1W	
		addlw	0x80			;move to 1st row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_Line2W	
		addlw	0xc0			;move to 2nd row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_CurOn
		movlw	0x0d			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_CurOff
		movlw	0x0c			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_Clr	
		movlw	0x01			;Clear display
		call	LCD_Cmd
		retlw	0x00

LCD_Busy
		bsf		STATUS,	RP0		;set bank 1
		movlw	b'11110010'			;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, 0	;setup to read busy flag
		bsf		LCD_PORT, LCD_E
		;swapf	LCD_PORT, w		;read upper nibble (busy flag)
		movfw	LCD_PORT
		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	b'00000010'			;set Port for output
		movwf	LCD_TRIS
		bcf		STATUS,	RP0		;set bank 0
		return



fogad 	btfss	PIR1,RCIF         ; (5) check for received data
        goto 	fogad
		bcf		PIR1,RCIF
        movf 	RCREG,	W
		clrf	RCREG	            ; save received data in W
		return 



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

Pulse_e		bsf	LCD_PORT, LCD_E
		nop

		bcf	LCD_PORT, LCD_E
		retlw	0x00
text



		movlw	'D'
		call	LCD_Char
		movlw	'e'
		call	LCD_Char
		movlw	'n'
		call	LCD_Char
		movlw	'i'
		call	LCD_Char
		movlw	's'
		call	LCD_Char
		movlw	'z'
		call	LCD_Char
		end