;LCD text demo - 4 bit mode
;Nigel Goodwin 2002

	LIST	p=16F628		;tell assembler what chip we are using
	include "P16F628.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3D18			;sets the configuration settings (oscillator type etc.)




		cblock	0x20			;start of general purpose registers
			TIMERTCS		; Timer1 túlcsordulások számlálója
			TIMERTCS1
			TIMERTCS2
			TULCSORDUL
			TEMP1L			; CCP első érték átmeneti tároló, alsó bit
			TEMP1H			; CCP első érték átmeneti tároló, felső bit
			TEMP2L			; CCP második érték átmeneti tároló, alsó bit
			TEMP2H			; CCP második érték átmeneti tároló, felső bit
			TIMEL			; Idő alsó bájt
			TIMEH			; Idő felső bájt
			count           ; Számláló a ciklus-rutinokhoz.
			count1          ; Számlálók a késleltető rutinhoz.
			counta
			countb
			count2
			tmp1            ; Átmeneti tárolás.
			tmp2
			templcd         ; Átmeneti tároló a 4 bites módhoz.
			templcd2
			nratorH			; Számláló és eredmény felső bájt
			nratorM			; Számláló és eredmény középső bájt
			nratorL			; Számláló és eredmény alsó bájt
			denomH			; Nevező felső bájt
			denomM			; Nevező középső bájt
			denomL			; Nevező alsó bájt
			remainH			; Maradék felső bájt
			remainM			; Maradék középső bájt
			remainL			; Maradék alsó bájt
            BCount          ; Számláló az osztáshoz
            shiftH          ; Segédregiszter az osztáshoz
            shiftM          ; Segédregiszter az osztáshoz
            shiftL          ; Segédregiszter az osztáshoz
			d0				; A bináris ASCII átalakítás segédregisztere
			d1				; A bináris ASCII átalakítás segédregisztere
			d2				; A bináris ASCII átalakítás segédregisztere
			
		endc

LCD_PORT	Equ	PORTA
LCD_TRIS	Equ	TRISA
LCD_RS		Equ	0x04			;LCD handshake lines
LCD_RW		Equ	0x06
LCD_E		Equ	0x07

		org	0x0000

		movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)

Initialise	
		clrf	count
		clrf	PORTA
		clrf	PORTB



SetPorts
		bsf 	STATUS,RP0		;select bank 1
		movlw	0x00			;make all pins outputs
		movwf	LCD_TRIS
		movlw	b'00001000'
		movwf	TRISB
		movlw	0x04
		movwf	PIE1
		bcf 	STATUS,RP0		;select bank 0
		movlw	0x05
		movwf	CCP1CON
		movlw	0x01
		movwf	T1CON
		call	Delay100		;wait for LCD to settle
		call	LCD_Init		;setup LCD
		clrf	count			;set counter register to zero

Message		
		movlw	HIGH Text
		movwf	PCLATH
		movf	count, w		;put counter value in W
		call	Text			;get a character from the text table
		xorlw	0x00			;is it a zero?
		btfsc	STATUS, Z
		goto	EndMessage
		call	LCD_Char
		call	Delay20
		incf	count, f
		goto	Message



EndMessage	

		movlw	0x09
		call	LCD_Line1W
		clrf	PIR1
		
START:
	btfss	PIR1,2
	goto	START

MEGSZ_CCP:	
	bcf		PIR1,2				; A megszakítást jelző bit törlése
	movfw	CCPR1L				; W = CCPR2L
	movwf	TEMP1L				; TEMP1L = CCPR2L ("elso érték" alsó bájt elmentve)
	movfw	CCPR1H				; W = CCPR2H
	movwf	TEMP1H				; TEMP1H = CCPR2H ("elso érték" felső bájt elmentve)
	movfw	TIMERTCS
	movwf	TIMERTCS1
	
KIVON:
	movfw	TEMP2L 
	subwf	TEMP1L,w 
	movwf	TIMEL

	movfw	TEMP2H 
	skpc 
	incfsz	TEMP2H,w 
	subwf	TEMP1H,w
	movwf	TIMEH

	movfw	TIMERTCS2 
	skpc 
	incfsz	TIMERTCS2,w 
	subwf	TIMERTCS1,w
	movwf	TULCSORDUL
	
;	movfw	TEMP2L		;elmentjük az eredményeket
;	movwf	TIMEL
;	movfw	TEMP2H
;	movwf	TIMEH
;	movfw	TIMERTCS2
;	movwf	TULCSORDUL
	
	movfw	TEMP1L		;Az új lesz a régi
	movwf	TEMP2L
	movfw	TEMP1H
	movwf	TEMP2H
	movfw	TIMERTCS1
	movwf	TIMERTCS2
		
;*************** Idtartamszmts ********************************************
;			Kerk kerlet 1,2 m. Mivel a m/s s km/h kztt 3,6 a vltszm a s s a us kztt 1 000 000,
; gy kell szmolni, hogy 1,2x3 600 000/id (teht 4 320 000/id) . Ez km/h-t ad egsz rtkben.
; szmll: nratorH  nratorM  nratorL
; nevez: denomH   denomM   denomL
; Az eredmny a nratorH  nratorM  nratorL regiszterekbe kerl
Oszt:
	  movlw		b'01000001'		; A szmll 24 bites regiszterbe 4 320 000-et tltnk
	  movwf		nratorH
	  movlw		b'11101011'
	  movwf		nratorM
	  movlw		b'00000000'
	  movwf		nratorL
	  
	  movfw		TULCSORDUL
	  movwf		denomH
	  movfw		TIMEH
	  movwf		denomM
	  movfw		TIMEL
	  movwf		denomL	
Divide_24x24:
		movlw    	.24		; set decimal 24 loop count
		movwf    	BCount
		movf     	nratorH,w ; copy Numerator into Shift Holding ram registers
		movwf    	shiftH
		movf     	nratorM,w
		movwf    	shiftM
		movf     	nratorL,w
		movwf    	shiftL
		clrf     	nratorH	;  clear final Answer Numerator Ram locations
		clrf     	nratorM
		clrf     	nratorL
      ;
		clrf     	remainH  ;  clear final Answer Remainder Ram locations
		clrf     	remainM
		clrf     	remainL
dloop:
		bcf		STATUS, C  ; bit clear Carry Flag in STATUS register
		rlf		shiftL, f  ; Shift numerator(dividend) Left to move
		rlf		shiftM, f  ; next bit to remainder
		rlf		shiftH, f  ; and shift in next bit of result

		rlf		remainL, f ; shift carry (next Dividend bit) into remainder
		rlf		remainM, f
		rlf		remainH, f
		movf     	denomH,w
		subwf    	remainH,w  ; subtract divsor(denomH) from(newly shifted left) Remainder HIGH byte.
		btfss    	STATUS, Z
		goto     	nochk		  ; skip if result was ZERO from good subtraction result
      ;
		movf     	denomM,w
		subwf    	remainM,w  ; subtract divsor(denomM) from(newly shifted left) Remainder MIDDLE byte.
		btfss    	STATUS, Z
		goto     	nochk		  ; skip if result was ZERO from good subtraction result
      ;
		movf     	denomL,w
		subwf    	remainL,w  ; subtract divsor(denomL) from(newly shifted left) Remainder LOW byte.
nochk:
		btfss    	STATUS, C   ;  Carry SET? then denom is larger than reemainder
		goto     	nogo
;
		movf     	denomL,w			 
		subwf    	remainL, f   	 ; Subtract denominator from remainder value in Low Byte
		btfsc    	STATUS, C       ; Carry Set? Then execute fixup code for when a borrow is generated
		goto 		nodec_remainM   ; when no borrow bit is needed from the higher byte positions.
		decf     	remainM, f      ; Decrement to Borrow from Middle Byte, because carry was SET.
		movf     	remainM,w
		xorlw    	0xff				 ; Check if rollover from Borrow occurred. remainM value went from 0 to 0xFF 
		btfsc    	STATUS, Z
		decf     	remainH, f		 ; ZERO bit set, yes rollover, so Decrement to Borrow from High Byte, too!
nodec_remainM:
		movf     	denomM,w
		subwf    	remainM, f		 ; Subtract denominator from remainder value in Middle Byte
		btfss    	STATUS, C
		decf     	remainH ,f      ; Decrement High Byte, to borrow 1 bit
		movf     	denomH,w   		 
		subwf    	remainH, f      ; Subtract denominator from remainder value in High Byte
		bsf		STATUS, C       ; set CARRY bit to rotate in Numerator Result next.
nogo:
		rlf		nratorL, f  ; rotate Numerator result left 1 bit
		rlf		nratorM, f
		rlf		nratorH, f
		decfsz   	BCount, f   ; decrement the Loop Bit Counter
		goto     	dloop
		movfw		nratorL	

;***************** Konverzi (binris/ASCII) ***
	clrf	d2
	clrf 	d1
	clrf	d0 

; Test if W is more than 199 (200 to 255)
	addlw 	.256 - .200
	btfss 	STATUS,C
	goto  	digit100
	bsf   	d2,1
; Here we are in the 200 - 255 range, so it is possible to
; skip the .100 and .80 parts
	addlw 	.256 - .80
	goto  	digit40

; Now, we have a number from -200 to -1 (0..199),
; we add 100 to detect -100 to -1 (100..199).
digit100
	addlw 	.100
	btfss 	STATUS,C
	goto  	$+3
	bsf   	d2,0
	addlw 	.256 - .100

; Now, we have a number from -100 to -1 (0..99),
; we add 20 to detect -20 to -1 (80..99).
	addlw 	.20
	btfss 	STATUS,C
	goto  	digit40
	bsf   	d1,3
; We skip the 4 and 2, as the largest value is 8 + 1 = 9.
	addlw 	.256 - .20
	goto 	digit10

; Now, we have a number from -80 to -1 (0..79),
; we add 40 to detect -40 to -1 (40..79).
digit40
	addlw 	.40
	btfss 	STATUS,C
	goto  	$+3
	bsf   	d1,2
	addlw 	.256 - .40

; Now, we have a number from -40 to -1 (0..39),
; we add 20 to detect -20 to -1 (20..39).
	addlw 	.20
	btfss 	STATUS,C
	goto  	$+3
	bsf   	d1,1
	addlw 	.256 - .20

; Now, we have a number from -20 to -1 (0..19),
; we add 10 to detect -10 to -1 (10..19).
digit10
	addlw 	.10
	btfss 	STATUS,C
	goto  	$+3
	bsf   	d1,0
	addlw 	.256 - .10

; Now, we have a number from -10 to -1 (0..9),
; we add 58 to bring it from 48 to 57 (0..9).
	addlw 	.58
	movwf 	d0
	movlw 	0x30
	xorwf 	d1,f
	xorwf 	d2,f

;********************** Kijelzs vezrlse ************************************
;	movlw	0x09
;	call	LCD_Line2W		; A sebessg kijelzs helyre lltja a kurzort
;	movlw	0x01
;	subwf	NULLA,W			; 0-bl kivonjuk a NULLA regiszter rtkt
;	btfsc	STATUS,C		; Ha a NULLA regiszter rtke tbb mint 0
;	goto	Nem_megy		; akkor nullkat runk ki a sebessghez
	movfw	d2
	call	LCD_Char
	movfw	d1
	call	LCD_Char
	movfw	d0
	call	LCD_Char
;	bsf		T1CON,0				; TIMER1 indtsa
;	bsf		INTCON,7			; Megszaktsok engedlyezse
;	clrf	NULLA
;	goto	START

Stop		goto	EndMessage			;endless loop




;Subroutines and text tables

;LCD routines

;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	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_CharD	addlw	0x30
LCD_Char	movwf	templcd
		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 	Delay5
		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_HEX		movwf	tmp1
		swapf	tmp1,	w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		movf	tmp1, w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		retlw	0x00

Delay255	movlw	0xff		;delay 255 mS
		goto	k0
Delay100	movlw	d'100'		;delay 100mS
		goto	k0
Delay50		movlw	d'50'		;delay 50mS
		goto	k0
Delay20		movlw	d'20'		;delay 20mS
		goto	k0
Delay5		movlw	0x05		;delay 5.000 ms (4 MHz clock)
k0		movwf	count1
k1		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	k1
		retlw	0x00

Pulse_e		bsf	LCD_PORT, LCD_E
		nop
		bcf	LCD_PORT, LCD_E
		retlw	0x00

;end of LCD routines

HEX_Table  	ADDWF   PCL       , f
            	RETLW   0x30
            	RETLW   0x31
            	RETLW   0x32
            	RETLW   0x33
            	RETLW   0x34
            	RETLW   0x35
            	RETLW   0x36
            	RETLW   0x37
            	RETLW   0x38
            	RETLW   0x39
            	RETLW   0x41
            	RETLW   0x42
            	RETLW   0x43
            	RETLW   0x44
            	RETLW   0x45
            	RETLW   0x46

		org	0x0400

Text		addwf	PCL, f
		retlw	'S'
		retlw	'e'
		retlw	'b'
		retlw	'e'
		retlw	's'
		retlw	's'
		retlw	'e'
		retlw	'g'
		retlw	':'
		retlw	' '
		retlw	' '
		retlw	' '
		retlw	'k'
		retlw	'm'
		retlw	'/'
		retlw	'h'
		retlw	0x00


		end