;Fordulatszámmérő PIC16F628A -val 2x 16 digites LCD-re
;		PORTA0	<17>	pl. hangszóró vagy ellenőrző LED
;		PORTA1	<18>	<ANALÓG BEMENET>
;		PORTA2	<1>	<ANALÓG BEMENET><fesz.referencia kimenet>
;		PORTA3	<2>	Nyomógomb (előre)
;		PORTA4	<3>	Nyomógomb (hátra)
;		PORTA5	<4>	Nyomógomb - RESET/MCLR
;		PORTA6	<15>	Oszcillátor <CLKOUT>
;		PORTA7	<16>	Oszcillátor <CLKIN>
;		PORTB0	<6>	RB0/INT -- fordszámérő bemenet - fotótranyó
;		PORTB1	<7>	Nyomógomb (SET)
;		PORTB2	<8>	LCD Enable
;		PORTB3	<9>	LCD RS
;		PORTB4	<10>	LCD DB4
;
;		PORTB7	<13>	LCD DB7

	list      p=16f628            ; list directive to define processor
	include <p16f628a.inc>        ; processor specific variable definitions
	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _LVP_OFF

	;megszakit shoz:
w_temp        EQU     0x70        ; variable used for context saving 
status_temp   EQU     0x71        ; variable used for context saving


	;LCD-hez
LCDEnable	EQU	2
LCDRS		EQU	3
LCDByte		EQU	0x20
HiByte		EQU	0x21
LoByte		EQU	0x22
LCDTar		EQU	0x23
LCDVez		EQU	0x24
LCDAdd		EQU	0x25
RSbit		EQU	0x2F
	;várakozáshoz
d1		EQU	0x2B
d2		EQU	0x2C
d3		EQU	0x2D
d4		EQU	0x2E

	;matekhez
REGA0		EQU	0x33		;lsb
REGA1		EQU	0x32
REGA2		EQU	0x31
REGA3		EQU	0x30		;msb	dec.'127' fölött a szám negativ!

REGB0		EQU	0x37		;lsb
REGB1		EQU	0x36
REGB2		EQU	0x35
REGB3		EQU	0x34		;msb	dec.'127' fölött a szám negativ!

REGC0		EQU	0x3B		;lsb
REGC1		EQU	0x3A
REGC2		EQU	0x39
REGC3		EQU	0x38		;msb	dec.'127' fölött a szám negativ!

DSIGN		EQU	0x50		;Digit Sign. 0=positive,1=negative
DIGIT1		EQU	0x51		;MSD
DIGIT2		EQU	0x52
DIGIT3		EQU	0x53
DIGIT4		EQU	0x54
DIGIT5		EQU	0x55		;Decimal (BCD) digits
DIGIT6		EQU	0x56
DIGIT7		EQU	0x57
DIGIT8		EQU	0x58
DIGIT9		EQU	0x59
DIGIT10		EQU	0x5A		;LSB
DIGIT11		EQU	0x5B
DIGIT12		EQU	0x5C
DIGIT13		EQU	0x5D
DIGIT14		EQU	0x5E
DIGIT15		EQU	0x5F



DIGIT20		EQU	0x60		;Digit Sign. 0=positive,1=negative
DIGIT21		EQU	0x61		;MSD
DIGIT22		EQU	0x62
DIGIT23		EQU	0x63
DIGIT24		EQU	0x64
DIGIT25		EQU	0x65		;Decimal (BCD) digits
DIGIT26		EQU	0x66
DIGIT27		EQU	0x67
DIGIT28		EQU	0x68
DIGIT29		EQU	0x69
DIGIT30		EQU	0x6A		;LSB
DIGIT31		EQU	0x6B
DIGIT32		EQU	0x6C
DIGIT33		EQU	0x6D
DIGIT34		EQU	0x6E
DIGIT35		EQU	0x6F

MTEMP		EQU	0x3E
MCOUNT		EQU	0x3D
DCOUNT		EQU	0x3C


   ;M‚r‚shez:
BeSzH		EQU	0x40		;bemeneti számláló
BeSzL		EQU	0x41

Tcs		EQU	0x43		;TMR1 túlcsordulás számláló
Konst1H		EQU	0x44		;konstans L
Konst1M		EQU	0x45		;konstans M
Konst1L		EQU	0x46		;konstans H

Jelszam		EQU	0x49		;jel/fordulat

	;kijelz”sz ml l˘k
KSZ		EQU	0x4A	;Karaktersz.
DSZ		EQU	0x4B	;Digitsz.
PSZ		EQU	0x4C	;Poziciósz.

FSR		EQU	0x04	;pointer to digits
ind		EQU	0x0	;dec. túlcsordulás

	;t rolt sz mok
T1H		EQU	0x70
T1L		EQU	0x71
T2H		EQU	0x72
T2M		EQU	0x73
T2L		EQU	0x74
T3H		EQU	0x75
T3M		EQU	0x76
T3L		EQU	0x77


	org	0x0000
	GOTO	KEZD

	ORG     0x004		; interrupt vector location
	BTFSC	INTCON,INTF	;PORT B0 okozta a megszakitást
	GOTO RBINT
;TMRINT:
;	movwf	w_temp
;	movf	STATUS,w	; move status register into W register
;	movwf	status_temp	; save off contents of STATUS register
;	.......	
	goto	Ki
RBINT:
	movwf	w_temp
	movf	STATUS,w	; move status register into W register
	movwf	status_temp	; save off contents of STATUS register
	BCF	T1CON,0		;TIMER1	leállitása
	movlw	0x0
	movwf	TMR1L
	movwf	TMR1H
	movwf	Tcs
	incfsz	BeSzL,f
	goto	Ki
	incf	BeSzH,f

Ki:	movf    status_temp,w	; retrieve copy of STATUS register
	movwf	STATUS		; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w	; restore pre-isr W register contents
	BSF	T1CON,0		;TIMER1 indul, vagy mehet tovább
;	BCF	INTCON,T0IF	;jelzőbit törlése -- HA Timer0 ........
	BCF	INTCON,INTF	;	-- HA RB0 okozta a megszakitást
	retfie			; return from interrupt


KEZD:
	movlw	0x0F		;xxx Konstans1=4MHz/4
	movwf	Konst1H
	movlw	0x42		;xxx
	movwf	Konst1M
	movlw	0x40		;xxx
	movwf	Konst1L		; =1000000

;megszakit0:		;INTCON--	bit7 GIE (=1 ált. megsz. eng.)
			;		bit6 PEIE (=1 periférikus megsz. ált. eng. /TIMER1, TIMER2, EEPROM, soros modul, PWM)
			;		bit5 T0IE (=1 TIMER0 túlcsordulás interraptját eng. ha a bit2=0)
			;		bit4 INTE (=1 RB0/INT megszakitás eng. ha a bit1=0)
			;		bit3 RBIE (=1 PORTB int. eng. ha a bit0=0)
			;PIE1--		bit7 EEIE (=1 belső EEPROM irásának befejezését jelző int. eng.)
			;		bit6 CM1E (=1 belső comparátorok átbillenésekor int eng.)
			;		bit5 RCIE (=1 RS232 vételi tároló megtelt int. eng.)
			;		bit4 TXIE (=1 RS232 adási tároló kiürült int.eng)
			;		bit3 ---
			;		bit2 CCPIE (=1 Capture-Compare-PWM modul int. eng.)
			;		bit1 TMR2IE (=1 Timer 2 int. eng.)
			;		bit0 TMR1IE (=1 Timer 1 int. eng.)
			;PIR1	( a PIE1 jelz<bitjei )
	;	movlw	b'11011000'
	;	movwf	INTCON		;nem most kezeljük!

	BCF	STATUS,IRP	;Bank 0,1
	BSF	STATUS,RP0	;Bank1
;	MOVLW	b'10001111'	;0-3 és 5. bit Vref.-et adja!
;	MOVWF	VRCON

	MOVLW	b'10001111'
	MOVWF	OPTION_REG
;	BSF	OPTION_REG,7	;'-RBPU' portB "pullupot" (gyenge felhúzás) Kikapcsolva
;	BCF	OPTION_REG,6	;'INTEDG' =1 RB0/INT lefutó élre; =0 felfutóra
;	BCF	OPTION_REG,5	;'T0CS' =1 TMR0 CLK Inp RA4-ről; =0 belső óráról
;	BCF	OPTION_REG,4	;'T0SE' =1 TMR0 lefutó élre léptet; =0 felfutóra
;	BSF	OPTION_REG,3	;elöosztó a WDT-hez, (0-- a Timer0-hoz)
;	BSF	OPTION_REG,2	;elöosztás=128	000-	1:1,  Timer0-nál	1:2
;	BSF	OPTION_REG,1	;			100-	1:16			1:32
;	BSF	OPTION_REG,0	;			111-	1:128			1:256
	BCF	STATUS,RP0	;Bank0

	MOVLW	b'10000111'		;3. bit RA0 és RA1-et választja ki
					;0-2. bit két comparátor belső Uref-el
	MOVWF	CMCON		;b'10000111' = comparátorok letiltva (port A0-A4 normál)


tmr1_alapra:
	movlw	b'00000000'	;0. bit kapcsolja ki (ill. be =1) az időzitőt
	movwf	T1CON
	movwf	TMR1L
	movwf	TMR1H

	CLRF	PORTA
	BSF	STATUS,RP0	;Bank1
	MOVLW	b'11111011'	;bitx=0 ->kimenet, =1 ->bemenet
	MOVWF	TRISA
	BCF	STATUS,RP0	;Bank0


	call LCDINIT


JELSZ:	movlw	' '
	movwf	DIGIT20	
	movlw	' '
	movwf	DIGIT21
	movlw	' '
	movwf	DIGIT22
	movlw	' '
	movwf	DIGIT23
	movlw	'J'
	movwf	DIGIT24
	movlw	'e'
	movwf	DIGIT25
	movlw	'l'
	movwf	DIGIT26
	movlw	'/'
	movwf	DIGIT27
	movlw	'f'
	movwf	DIGIT28
	movlw	'o'
	movwf	DIGIT29
	movlw	'r'
	movwf	DIGIT30
	movlw	'd'
	movwf	DIGIT31
	movlw	'u'
	movwf	DIGIT32
	movlw	'l'
	movwf	DIGIT33
	movlw	'a'
	movwf	DIGIT34
	movlw	't'
	movwf	DIGIT35

	movlw	0x2		;kezdőérték
	movwf	Jelszam

kerdez:	
	btfsc	PORTA,3		;"előre" megnyomva?
	goto	hatra1
;	goto	elore
elore:	incf	Jelszam,F
	CALL	LONGDLY_100
	goto	ker1
hatra1:	btfsc	PORTA,4		;"hátra" megnyomva?
	goto	ker1
;	goto	hatra
hatra:	decf	Jelszam,F
	CALL	LONGDLY_100

ker1:
	movf	Jelszam,W
	movwf	REGA0
	call	bin2dec
	movf	DIGIT10,W
	ADDLW	0x30
	movwf	DIGIT22
	movf	DIGIT9,W
	ADDLW	0x30
	movwf	DIGIT21
	movf	DIGIT8,W
	ADDLW	0x30
	movwf	DIGIT20

	call	LCDLINE2
	movlw	0x60		;második sor első karakter regisztercime
	movwf	DSZ
	movlw	0x40		;az első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10		;16 karaktert irunk ki
	movwf	PSZ
	call	KAR_KI

	btfss	PORTB,1		;"SET" megnyomva?
	goto	kerveg
	CALL	LONGDLY_100
	goto	kerdez
kerveg:

;test:	movlw	d'0'		;CSAK testhez!!!!!!!!!!!
;	movwf	BeSzH
;	movlw	d'1'
;	movwf	BeSzL
;	movlw	0x07
;	movwf	Tcs
;	movlw	0x90
;	movwf	TMR1H
;	movlw	0xB6
;	movwf	TMR1L



Meres0:
	movlw	0xFF
	movwf	BeSzL
	movwf	BeSzH
	

;	call	LedBe
	BCF	STATUS,RP0	;Bank0

;	BSF	INTCON,PEIE	;PIE-n belüli megszakitások figyelembevehetők
;	BSF	INTCON,TOIE	;TIMER0 megszakithat, MOST NEM

	BCF	INTCON,INTF	;jelzőbit törlése HA RB0 már bebillentette
	BSF	INTCON,INTE	;Bport megszakithat
	BSF	INTCON,GIE	;ált. megszakitás eng.
M0:	BTFSS	T1CON,0	
	GOTO	M0
PDelay	movlw	.14		; 1 sec. várakozás (.14 volt)
	movwf	d1
PLoop0	movlw	.72		; (.72 volt)
	movwf	d2
PLoop1	movlw	.246		; (.247 volt)
	movwf	d3
PLoop2	clrwdt			; 1 clear watchdog
	decfsz	d3,f
	goto	PLoop2

	btfss	PIR1,0		;TMR1 túlcsordult? bit0-> TMR1F
	goto	Ploop21
	bcf	PIR1,0
	incf	Tcs,f

Ploop21	decfsz	d2,f
	goto	PLoop1

Ploop3	decfsz	d1,f
	goto	PLoop0
PDelL1	goto	PDelL2		; 2 cycles delay
PDelL2	clrwdt			; 1 cycle delay

Merveg:	BCF	INTCON,GIE	;Megszakitások TILTVA
	BCF	T1CON,0		;TIMER1	leállitása
;	call	LedKi

	movlw	0x0
	addwf	BeSzL,w	
	btfss	STATUS,Z	;Zero flag=1 ,ha az eredmény =0
	goto	Szamitas
	addwf	BeSzH,w
	btfsc	STATUS,Z
	goto	Meres0		;Ha nincs ujabb jel 1 sec. belül,
				;ujabb meres -- 0-val nem osztunk!
Szamitas:
	
	movf	BeSzL,w
	movwf	REGA0
	movf	BeSzH,w
	movwf	REGA1
	movlw	d'20'
	movwf	REGB0

	movlw	0x0
	movwf	REGA2
	movwf	REGA3
	movwf	REGB1
	movwf	REGB2
	movwf	REGB3	
	call	multiply	;rega=rega*regb ->T1
	movf	REGA0,w
	movwf	T1L
	movf	REGA1,w
	movwf	T1H

sz2:	movf	Konst1L,w
	movwf	REGB0
	movf	Konst1M,w
	movwf	REGB1
	movf	Konst1H,w
	movwf	REGB2
	movlw	0x0
	movwf	REGB3
	call	add		;ER1=konst1+20*BeSz
	movf	BeSzL,w
	movwf	REGB0
	movf	BeSzH,w
	movwf	REGB1	
	movlw	0x0
	movwf	REGB2	
	movwf	REGB3

	call	divide		;T2=ER1/BeSz
	movf	REGA0,w
	movwf	T2L
	movf	REGA1,w
	movwf	T2M
	movf	REGA2,w
	movwf	T2H
sz3:	movf	TMR1L,w
	movwf	REGA0
	movf	TMR1H,w
	movwf	REGA1
	movf	Tcs,w
	movwf	REGA2
	movf	T1L,w
	movwf	REGB0
	movf	T1H,w
	movwf	REGB1
	movlw	0x0
	movwf	REGA3
	movwf	REGB2
	movwf	REGB3	
	CALL	add		;Korr.TMR1
	movf	BeSzL,w
	movwf	REGB0
	movf	BeSzH,w
	movwf	REGB1	
	movlw	0x0
	movwf	REGB2
	movwf	REGB3	
	CALL	divide		;Korr.TMR1/BeSz
	movf	REGA0,W
	movwf	REGB0
	movf	REGA1,W
	movwf	REGB1
	movf	REGA2,W
	movwf	REGB2
	movf	T2L,w
	movwf	REGA0
	movf	T2M,w
	movwf	REGA1
	movf	T2H,w
	movwf	REGA2
	movlw	0x0
	movwf	REGA3
	movwf	REGB3
	CALL	subtract	;T3
	movf	REGA0,w
	movwf	T3L
	movf	REGA1,w
	movwf	T3M
	movf	REGA2,w
	movwf	T3H
sz4:	movf	Konst1L,w
	movwf	REGA0
	movf	Konst1M,w
	movwf	REGA1
	movf	Konst1H,w
	movwf	REGA2
	movlw	d'60'
	movwf	REGB0
	movlw	0x0
	movwf	REGA3
	movwf	REGB1
	movwf	REGB2
	movwf	REGB3
	CALL	multiply	;60x ciklusszam
	movf	T3L,w
	movwf	REGB0
	movf	T3M,w
	movwf	REGB1
	movf	T3H,w
	movwf	REGB2
	movlw	0x0
	movwf	REGB3
	CALL	divide		;REGA-ban a fordulatszam

	movf	Jelszam,W	;"Jelszámmal" osztás
	movwf	REGB0
	movlw	0x0
	movwf	REGB1
	movwf	REGB2
	movwf	REGB3
	call	divide		;	
Atalakit:
	call	bin2dec		;rega-->decimálissá
	call	KAR_AT

	movlw	' '
	movwf	DIGIT11
	movlw	'/'
	movwf	DIGIT12
	movlw	'm'
	movwf	DIGIT13
	movlw	'i'
	movwf	DIGIT14
	movlw	'n'
	movwf	DIGIT15
;	movwf	DIGIT1
;	movlw	0x3d		;=
;	movwf	DIGIT2

	bcf	PORTA,2		;hangszóró ki

Kiir1:	call	LCDLINE1
	movlw	0x50		;első sor első karakter regisztercime
	movwf	DSZ
	movlw	0x0		;az első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10		;16 karaktert irunk ki
	movwf	PSZ
	call	KAR_KI

Kiir2:	call	LCDLINE2
	movlw	0x60		;második sor első karakter regisztercime
	movwf	DSZ
	movlw	0x40		;az első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10		;16 karaktert irunk ki
	movwf	PSZ
	call	KAR_KI

veg:
	goto	Meres0

;(rutinok:)

KAR_KI:	movf	KSZ,W		;PSZ számu karakter az LCD-re
	call	LCDPOZ
	movf	DSZ,W
	movwf	FSR		;fsr-ben a DSZ-digitszámláló
hz1	movlw	0x30		;ha "0" ...
	xorwf	ind,W
	btfss	STATUS,Z
	goto	hz2
	movlw	0x20		;első "0"-k helyett space
	movwf	LCDByte
	call	LCDBYTE
	incf	FSR,f
	decfsz	PSZ,f
	goto	hz1
	goto	hz2
hz2	movf	ind,W
	movwf	LCDByte
	call	LCDBYTE
	incf	FSR,f
	decfsz	PSZ,f
	goto	hz2
hz3	RETURN


KAR_AT:				;DEC.szám - karakterré
	movf	DSIGN,W
	ADDLW	0x30
	MOVWF	DSIGN
	movf	DIGIT1,W
	ADDLW	0x30
	MOVWF	DIGIT1
	movf	DIGIT2,W
	ADDLW	0x30
	MOVWF	DIGIT2
	movf	DIGIT3,W
	ADDLW	0x30
	MOVWF	DIGIT3
	movf	DIGIT4,W
	ADDLW	0x30
	MOVWF	DIGIT4
	movf	DIGIT5,W
	ADDLW	0x30
	MOVWF	DIGIT5
	movf	DIGIT6,W
	ADDLW	0x30
	MOVWF	DIGIT6
	movf	DIGIT7,W
	ADDLW	0x30
	MOVWF	DIGIT7
	movf	DIGIT8,W
	ADDLW	0x30
	MOVWF	DIGIT8
	movf	DIGIT9,W
	ADDLW	0x30
	MOVWF	DIGIT9
	movf	DIGIT10,W
	ADDLW	0x30
	MOVWF	DIGIT10
	RETURN


LedBe:	bsf PORTA,2	;LED bekapcs.
	return

LedKi:	bcf PORTA,2	;LED kikapcs.
	return

;	*	*	*	*	*	*	*	*	*	*	*	*
;		32 bites matek !!!

;	CALL	add		;REGA.=REGA.+REGB. (30-33 ill. 40-43)
;	CALL	subtract	;REGA.=REGA.-REGB. 
;	CALL	multiply	;REGA.=REGA.*REGB. 
; 	CALL	divide		;REGA.=REGA./REGB. 
;	CALL	round
;	CALL	sqrt		;REGA.=négyzetgyök (REGA.)
;	CALL	bin2dec		;eredmény 50-5A -ig (REGA. átalakitása decimŁlissá --> LCD )
;	movlw	0x0A		;alakitandó KARAKTEREK száma->W
;	call	dec2bin		;Digit1-től dec. szám binárissá -> regA-ba
;


      ;*** 32 BIT SIGNED SUTRACT ***
      ;REGA - REGB -> REGA
      ;Return carry set if overflow
subtract:
      	call	negateb		;Negate REGB
      	skpnc
      	return			;Overflow

      ;*** 32 BIT SIGNED ADD ***
      ;REGA + REGB -> REGA
      ;Return carry set if overflow

add:	movf	REGA3,w		;Compare signs
      	xorwf	REGB3,w
      	movwf	MTEMP

      	call	addba		;Add REGB to REGA

      	clrc			;Check signs
      	movf	REGB3,w		;If signs are same
      	xorwf	REGA3,w		;so must result sign
      	btfss	MTEMP,7		;else overflow
      	addlw	0x80
      	return

      ;*** 32 BIT SIGNED MULTIPLY ***
      ;REGA * REGB -> REGA
      ;Return carry set if overflow

multiply:
      	clrf	MTEMP		;Reset sign flag
      	call	absa		;Make REGA positive
      	skpc
      	call	absb		;Make REGB positive
      	skpnc
      	return			;Overflow

      	call	movac		;Move REGA to REGC
      	call	clra		;Clear product

      	movlw	D'31'		;Loop counter
      	movwf	MCOUNT

muloop:	call	slac		;Shift left product and multiplicand
      	
      	rlf	REGC3,w		;Test MSB of multiplicand
      	skpnc			;If multiplicand bit is a 1 then
      	call	addba		;add multiplier to product

      	skpc			;Check for overflow
      	rlf	REGA3,w
      	skpnc
      	return

      	decfsz	MCOUNT,f	;Next
      	goto	muloop

      	btfsc	MTEMP,0		;Check result sign
      	call	negatea		;Negative
      	return


      ;*** 32 BIT SIGNED DIVIDE ***
      ;REGA / REGB -> REGA
      ;Remainder in REGC
      ;Return carry set if overflow or division by zero

divide:	clrf	MTEMP		;Reset sign flag
      	movf	REGB0,w		;Trap division by zero
      	iorwf	REGB1,w
      	iorwf	REGB2,w
      	iorwf	REGB3,w
      	sublw	0
      	skpc
      	call	absa		;Make dividend (REGA) positive
      	skpc
      	call	absb		;Make divisor (REGB) positive
      	skpnc
      	return			;Overflow

      	clrf	REGC0		;Clear remainder
      	clrf	REGC1
      	clrf	REGC2
      	clrf	REGC3
      	call	slac		;Purge sign bit

      	movlw	D'31'		;Loop counter
      	movwf	MCOUNT

dvloop:	call	slac		;Shift dividend (REGA) msb into remainder (REGC)

      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
      	skpz
      	goto	dtstgt
      	movf	REGB2,w
      	subwf	REGC2,w
      	skpz
      	goto	dtstgt
      	movf	REGB1,w
      	subwf	REGC1,w
      	skpz
      	goto	dtstgt
      	movf	REGB0,w
      	subwf	REGC0,w
dtstgt:	skpc			;Carry set if remainder >= divisor
      	goto	dremlt

      	movf	REGB0,w		;Subtract divisor (REGB) from remainder (REGC)
      	subwf	REGC0,f
      	movf	REGB1,w
      	skpc
      	incfsz	REGB1,w
      	subwf	REGC1,f
      	movf	REGB2,w
      	skpc
      	incfsz	REGB2,w
      	subwf	REGC2,f
      	movf	REGB3,w
      	skpc
      	incfsz	REGB3,w
      	subwf	REGC3,f
      	clrc
      	bsf	REGA0,0		;Set quotient bit

dremlt:	decfsz	MCOUNT,f	;Next
      	goto	dvloop

      	btfsc	MTEMP,0		;Check result sign
      	call	negatea		;Negative
      	return

      ;*** ROUND RESULT OF DIVISION TO NEAREST INTEGER ***

round:	clrf	MTEMP		;Reset sign flag
      	call	absa		;Make positive
      	clrc
      	call	slc		;Multiply remainder by 2
      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
      	skpz
      	goto	rtstgt
      	movf	REGB2,w
      	subwf	REGC2,w
      	skpz
      	goto	dtstgt
      	movf	REGB1,w
      	subwf	REGC1,w
      	skpz
      	goto	rtstgt
      	movf	REGB0,w
      	subwf	REGC0,w
rtstgt:	skpc			;Carry set if remainder >= divisor
      	goto	rremlt
      	incfsz	REGA0,f		;Add 1 to quotient
      	goto	rremlt
      	incfsz	REGA1,f
      	goto	rremlt
      	incfsz	REGA2,f
      	goto	rremlt
      	incf	REGA3,f
      	skpnz
      	return			;Overflow,return carry set
rremlt:	btfsc	MTEMP,0		;Restore sign
      	call	negatea
      	return


      ;*** 32 BIT SQUARE ROOT ***
      ;sqrt(REGA) -> REGA
      ;Return carry set if negative

sqrt:		rlf	REGA3,w		;Trap negative values
      	skpnc
      	return

      	call	movac		;Move REGA to REGC
      	call	clrba		;Clear remainder (REGB) and root (REGA)

      	movlw	D'16'		;Loop counter
      	movwf	MCOUNT

sqloop:	rlf	REGC0,f		;Shift two msb's
      	rlf	REGC1,f		;into remainder
      	rlf	REGC2,f
      	rlf	REGC3,f
      	rlf	REGB0,f
      	rlf	REGB1,f
      	rlf	REGB2,f
      	rlf	REGC0,f
      	rlf	REGC1,f
      	rlf	REGC2,f
      	rlf	REGC3,f
      	rlf	REGB0,f
      	rlf	REGB1,f
      	rlf	REGB2,f

      	setc			;Add 1 to root
      	rlf	REGA0,f		;Align root
      	rlf	REGA1,f
      	rlf	REGA2,f

      	movf	REGA2,w		;Test if remdr (REGB) >= root (REGA)
      	subwf	REGB2,w
      	skpz
      	goto	ststgt
      	movf	REGA1,w
      	subwf	REGB1,w
      	skpz
      	goto	ststgt
      	movf	REGA0,w
      	subwf	REGB0,w
ststgt:	skpc			;Carry set if remdr >= root
      	goto	sremlt

      	movf	REGA0,w		;Subtract root (REGA) from remdr (REGB)
      	subwf	REGB0,f
      	movf	REGA1,w
      	skpc
      	incfsz	REGA1,w
      	subwf	REGB1,f
      	movf	REGA2,w
      	skpc
      	incfsz	REGA2,w
      	subwf	REGB2,f
      	bsf	REGA0,1		;Set current root bit

sremlt:	bcf	REGA0,0		;Clear test bit
      	decfsz	MCOUNT,f	;Next
      	goto	sqloop

      	clrc
      	rrf	REGA2,f		;Adjust root alignment
      	rrf	REGA1,f
      	rrf	REGA0,f
      	return


      ;*** 32 BIT SIGNED BINARY TO DECIMAL ***
      ;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN
      ;DSIGN = 0 if REGA is positive, 1 if negative
      ;Return carry set if overflow
      ;Uses FSR register

bin2dec:	clrf	MTEMP		;Reset sign flag
      	call	absa		;Make REGA positive
      	skpnc
      	return			;Overflow

      	call	clrdig		;Clear all digits

      	movlw	D'32'		;Loop counter
      	movwf	MCOUNT

b2dloop:	rlf	REGA0,f		;Shift msb into carry
      	rlf	REGA1,f
      	rlf	REGA2,f
      	rlf	REGA3,f

      	movlw	DIGIT10
      	movwf	FSR		;Pointer to digits
      	movlw	D'10'		;10 digits to do
      	movwf	DCOUNT

adjlp:	rlf	INDF,f		;Shift digit and carry 1 bit left
      	movlw	D'10'
      	subwf	INDF,w		;Check and adjust for decimal overflow
      	skpnc
      	movwf	INDF

      	decf	FSR,f		;Next digit
      	decfsz	DCOUNT,f
      	goto	adjlp

      	decfsz	MCOUNT,f	;Next bit
      	goto	b2dloop

      	btfsc	MTEMP,0		;Check sign
      	bsf	DSIGN,0		;Negative
      	clrc
      	return


      ;*** 32 BIT SIGNED DECIMAL TO BINARY ***
      ;Decimal DIGIT1 thro DIGIT(X) & DSIGN -> REGA
      ;Set DSIGN = 0 for positive, DSIGN = 1 for negative values
      ;Most significant digit in DIGIT1
      ;Enter this routine with digit count in w register
      ;Return carry set if overflow
      ;Uses FSR register

dec2bin:	movwf	MTEMP		;Save digit count

      	movlw	D'32'		;Outer bit loop counter
      	movwf	MCOUNT

d2blp1:	movlw	DIGIT1-1	;Set up pointer to MSD
      	movwf	FSR
      	movf	MTEMP,w		;Inner digit loop counter
      	movwf	DCOUNT

      	movlw	D'10'
      	clrc			;Bring in '0' bit into MSD

d2blp2:	incf	FSR,f
      	skpnc
      	addwf	INDF,f		;Add 10 if '1' bit from prev digit
           	rrf	INDF,f		;Shift out LSB of digit

      	decfsz	DCOUNT,f	;Next L.S. Digit
      	goto	d2blp2

      	rrf	REGA3,f		;Shift in carry from digits
      	rrf	REGA2,f
      	rrf	REGA1,f
      	rrf	REGA0,f

      	decfsz	MCOUNT,f	;Next bit
      	goto	d2blp1

      	movf	INDF,w		;Check for overflow
      	addlw	0xFF
      	skpc
      	rlf	REGA3,w
      	skpnc
      	return

      	btfsc	DSIGN,0		;Check result sign
      	call	negatea		;Negative
      	return


      ;UTILITY ROUTINES


      ;Add REGB to REGA (Unsigned)
      ;Used by add, multiply,

addba:	movf	REGB0,w		;Add lo byte
      	addwf	REGA0,f

      	movf	REGB1,w		;Add mid-lo byte
      	skpnc			;No carry_in, so just add
      	incfsz	REGB1,w		;Add carry_in to REGB
      	addwf	REGA1,f		;Add and propagate carry_out

      	movf	REGB2,w		;Add mid-hi byte
      	skpnc
      	incfsz	REGB2,w
      	addwf	REGA2,f

      	movf	REGB3,w		;Add hi byte
      	skpnc
      	incfsz	REGB3,w
      	addwf	REGA3,f
      	return


      ;Move REGA to REGC
      ;Used by multiply, sqrt

movac:	movf	REGA0,w
      	movwf	REGC0
      	movf	REGA1,w
      	movwf	REGC1
      	movf	REGA2,w
      	movwf	REGC2
      	movf	REGA3,w
      	movwf	REGC3
      	return


      ;Clear REGB and REGA
      ;Used by sqrt

clrba:	clrf	REGB0
      	clrf	REGB1
      	clrf	REGB2
      	clrf	REGB3

      ;Clear REGA
      ;Used by multiply, sqrt

clra:		clrf	REGA0
      	clrf	REGA1
      	clrf	REGA2
      	clrf	REGA3
      	return


      ;Check sign of REGA and convert negative to positive
      ;Used by multiply, divide, bin2dec, round

absa:		rlf	REGA3,w
      	skpc
      	return			;Positive

      ;Negate REGA
      ;Used by absa, multiply, divide, bin2dec, dec2bin, round

negatea:	movf	REGA3,w		;Save sign in w
      	andlw	0x80

      	comf	REGA0,f		;2's complement
      	comf	REGA1,f
      	comf	REGA2,f
      	comf	REGA3,f
      	incfsz	REGA0,f
      	goto	nega1
      	incfsz	REGA1,f
      	goto	nega1
      	incfsz	REGA2,f
      	goto	nega1
      	incf	REGA3,f

nega1:     	incf	MTEMP,f		;flip sign flag
      	addwf	REGA3,w		;Return carry set if -2147483648
      	return


      ;Check sign of REGB and convert negative to positive
      ;Used by multiply, divide

absb:		rlf	REGB3,w
      	skpc
      	return			;Positive

      ;Negate REGB
      ;Used by absb, subtract, multiply, divide

negateb:	movf	REGB3,w		;Save sign in w
      	andlw	0x80

      	comf	REGB0,f		;2's complement
      	comf	REGB1,f
      	comf	REGB2,f
      	comf	REGB3,f
      	incfsz	REGB0,f
      	goto	negb1
      	incfsz	REGB1,f
      	goto	negb1
      	incfsz	REGB2,f
      	goto	negb1
      	incf	REGB3,f

negb1:     	incf	MTEMP,f		;flip sign flag
      	addwf	REGB3,w		;Return carry set if -2147483648
      	return


      ;Shift left REGA and REGC
      ;Used by multiply, divide, round

slac:		rlf	REGA0,f
      	rlf	REGA1,f
      	rlf	REGA2,f
      	rlf	REGA3,f
slc:		rlf	REGC0,f
      	rlf	REGC1,f
      	rlf	REGC2,f
      	rlf	REGC3,f
      	return


      ;Set all digits to 0
      ;Used by bin2dec

clrdig:	clrf	DSIGN
      	clrf	DIGIT1
      	clrf	DIGIT2
      	clrf	DIGIT3
      	clrf	DIGIT4
      	clrf	DIGIT5
      	clrf	DIGIT6
      	clrf	DIGIT7
      	clrf	DIGIT8
      	clrf	DIGIT9
      	clrf	DIGIT10
      	return


;	*	*	*	*	*	*	*	*	*	*	*	*	*


; LCD: DISPLAYTECH 162B ~ HD44780		file:PIC_LCD4.ASM
; LCD vez‚rl‚s:
;	RS -- RB3
;	R/-W -- GND!!!
;	E ----- RB2
;LCD adatok:
;	D4 ---- RB4
;	D5 ---- RB5
;	D6 ---- RB6
;	D7 ---- RB7

;To use this code, firstly set the relevent TRIS bits, then initialise the LCD: 
;	CALL LONGDLY
;	CALL LCDFUN 	; sets the LCD's function to 4 bit, 2 line, 5x7 font
;       CALL LONGDLY 	
;       CALL LCDDISP ; Turns on the display and cursor
;       CALL LONGDLY
;	CALL LCDENT 	; sets auto increment right after write (like a typewriter)
;       CALL LCDCLR
  
;You know the LCD is initialized when iot is totally blank. If you get the one row solid black and the other clear, the LCD has not been initialised properly. 
;Now, there are 2 ways to write to the LCD. Firstly, you can use the LCDChar method. This is nice because it automatcally word wraps the text, and prevents you writing to non- visible memory. For instance: 
;	movlw "A"
;	movwf LCDByte
;	CALL LCDCHAR
  
;To write different commands to the LCD, such as different function select bytes, set the relevent RS bit, put the data in LCDByte, then call LCDBYTE. This is only for the LCD gurus! 
;To change the address, call LCDVEZ eg to go to address 3, 
;	movlw 3
;	movwf LCDadd
;	CALL LCDVEZ 
;To clear the LCD, 
;	CALL LCDCLR. 
;To 'backspace',
;	CALL LCDBACKSPACE
;If you need a hand, email me @ a.borowski@student.qut.edu.au
;or visit my website at http://www.alborowski.tk 

;    forr snak felhaszn lva --> ALAKITVA !!!!!!

LCDINIT:
	BCF	STATUS,RP0	;Bank1
	CLRF	PORTB
	BSF STATUS,RP0
	MOVLW	b'00000011'	;RB2-RB7 LCD
	MOVWF	TRISB
	BCF	STATUS,RP0	;Bank0
	CALL	LONGDLY_100
	MOVLW	b'00110100'	;FUNKCIO 8 bites interface
	MOVWF	PORTB
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	CALL	SHORTDLY
	NOP
	MOVLW	b'00100100'	;FUNKCIO 4 bites interface
	MOVWF	PORTB
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	CALL	SHORTDLY
	MOVLW	b'00101000'	;2 SOROS norm l FONT
	MOVWF	LCDByte
	CALL	LCDBYTE
	MOVLW	b'00001100'	;Display ON, Cursor OFF, Blink OFF
	MOVWF	LCDByte
	CALL	LCDBYTE
	MOVLW	b'00000110'	;Entry m˘d: Cursor increment, Display shift No
	MOVWF	LCDByte
	CALL	LCDBYTE
	MOVLW	b'10000001'	;Set DD RAM, '01'
	MOVWF	LCDByte
	CALL	LCDBYTE
	BCF	PORTB,LCDRS	;Vez‚rl‚s k”vetkezik	
	MOVLW	b'00000001'	;Dislpay Clear
	MOVWF	LCDByte
	CALL	LCDBYTE
	BSF	PORTB,LCDRS	;Vez‚rl‚s v‚ge, karakter k”vetkezik
	CALL	SHORTDLY
	RETURN


LCDVEZ ; makes LCDVez the current LCD Address
	nop
	BCF PORTB,LCDRS
	movf	LCDVez,W	;vez‚rl‹byte	LCDVez->W
	movwf LCDByte
	CALL LCDBYTE
	bsf PORTB,LCDRS
	nop
	nop 
	RETURN

LCDLINE1:	; here we must go to the new line
	movlw b'00000000'	;0h
	movwf LCDVez
	bsf	LCDVez,0x7
	CALL LCDVEZ
	RETURN

LCDLINE2:	; here we must go to the new line
	movlw b'01000000'	;40h
	movwf LCDVez
	bsf	LCDVez,0x7
	CALL LCDVEZ
	RETURN

LCDPOZ:		;MOVLW	h'x' -els< sorba xx=0-F=d'0-15'
		;MOVLW	h'xx' -m sodik sorba xx=40-4F
	movwf LCDVez
	bsf	LCDVez,0x7
	CALL LCDVEZ
	RETURN

LCDBYTE:	; sends a byte to the LCD, in 4bit fashion
      	; responsible for breaking up the byte to send into high and low nibbles
		; and dumps them to LCD
	
		;NOT responsible for the status of the LCDRS line, nor the major delays

		; IN: LCDByte  - distructive OUT: hiByte, loByte
			;RS-t ˙t kell engedni'''
	MOVF	PORTB,W	; RSbit let rol sa
	MOVWF	RSbit	
	MOVLW	b'00001000'	;maszk RS-hez
	ANDWF	RSbit,f	;vez'rl's-> RSbit=0, karakter-> RSbit=1

	clrf HiByte 	; clears the vars, to prevent bugs
	clrf LoByte

	MOVF LCDByte,W	; Karakter a W-be
	MOVWF HiByte
	MOVWF LoByte
	rlf LoByte, 1
	rlf LoByte, 1
	rlf LoByte, 1
	rlf LoByte, 1
	MOVLW 0xF0		; W=b'11110000'
	ANDWF LoByte,f
	MOVLW 0xF0		; W=b'11110000'
	ANDWF HiByte,f	; 
	MOVF	HiByte,W	; W-ben A HiByte
	IORWF	RSbit,W
	MOVWF	LCDTar
	BSF	LCDTar,LCDEnable
	MOVF	LCDTar,W
	MOVWF PORTB
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	CALL	SHORTDLY
	NOP
	MOVF LoByte,W	; W-ben A LoByte
	IORWF	RSbit,W
	MOVWF	LCDTar
	BSF	LCDTar,LCDEnable
	MOVF	LCDTar,W
	MOVWF PORTB
	CALL	SHORTDLY
	BCF PORTB,LCDEnable
	CALL	SHORTDLY
	BSF PORTB,LCDEnable
	NOP
	RETURN	

SHORTDLY:	; around 100us
		;100 cycles
	movlw	0x21
	movwf	d1
SHORTDLY_0:
	decfsz	d1, f
	goto	SHORTDLY_0
			;4 cycles (including call)
	RETURN

LONGDLY_1:	; 1msec delay
		; * 998 * cycles
	movlw	0xC7
	movwf	d1
	movlw	0x01
	movwf	d2
	goto	LONGDLY_0
LONGDLY_100:	; 0,1sec delay
		; * 999998 * cycles
	movlw	0x1F
	movwf	d1
	movlw	0x4F
	movwf	d2
LONGDLY_0:
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	LONGDLY_0
				;2 cycles
	goto	$+1
	nop
	RETURN			;4 cycles (including call)

	end
