;fordulatszámmérés-csak-részlet PIC16F886-ra
;kapcsolat: ki: RS232(TTL) - USB-PC	
;	Vss		<19,8>	GND
;	Vdd		<20>	-	+5V
;	PORTA0	<2>	-	LCD	RS
;	PORTA1	<3>	-	LCD	Enable
;	PORTA2	<4>	-	LCD	DB4	+bill_ki 0
;	PORTA3	<5>	-	LCD	DB5	+bill_ki 1
;	PORTA4	<6>	-	LCD	DB6	+bill_ki 2
;	PORTA5	<7>	-	LCD	DB7	+bill_ki 3
;	PORTA6	<10>	---	Oszcillátor <CLKOUT>
;	PORTA7	<9>	---	Oszcillátor <CLKIN>
		
;	PORTB0	<21>	-	senzor0--(AN12)	forgás jel		
*
;**********************************************************************


	list		p=16f886	; list directive to define processor
	#include	<p16f886.inc>	; processor specific variable definitions
;	#include	<PIC_LCD4.inc>
;	#include	<PIC_LCD4.asm>

	

	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
	__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V


	ERRORLEVEL -302

#DEFINE	MHZ_20

#DEFINE	BAUD	d'9600'	;d'19200'
	IFDEF	MHZ_8
#DEFINE	FOSC	D'8000000'		;ÓRAJEL 8 MHZ
	ELSE
#DEFINE FOSC	D'20000000' 		;ÓRAJEL 20 MHZ
	ENDIF


#DEFINE	Konst_T1(X)	(FOSC/(4*X))
#DEFINE	Konst_F1(X)	(d'60'*FOSC/(4*X))	;ford/min számításához

LCDEnable	EQU 1
LCDRS		EQU 0
LCDRSmaszk	EQU b'00000001'	;2^LCDRS
LCDmaszk        EQU b'11000011'     ;LCD DB7-DB4 (TRIS-hez)	


#define	INFRA	PORTC,2



reg	UDATA	0x20	;bank0
Flag	RES 1
Gomb	RES 1
RESULTHI	RES 1
RESULTLO	RES 1
Tcs	res 1
BeSzL	res 1
BeSzH	res 1
Cikl3	res 1
Cikl2	res 1
Cikl1	res 1
Cikl0	res 1
M_cik3	res 1
M_cik2	res 1
M_cik1	res 1
M_cik0	res 1


	;várakozáshoz és converzióhoz
d1	RES 1	;
d2	RES 1	;
d3	RES 1
d4	RES 1

sz1	RES 1	;ált. célu számláló
sz2	RES 1	;

;	udata	0x30
MTEMP	RES 1	;
MCOUNT	RES 1	;
DCOUNT	RES 1	;
DSIGN	RES 1

KSZ	RES 1		;Karaktersz.
DSZ	RES 1		;Digitsz.
PSZ	RES 1		;Poziciósz.

count	RES 1
TEMP	RES 1
TEMP0	RES 1
TEMP1	RES 1	;0xA	;átalakításokhoz és billentyűzet kez.
TEMP2	RES 1

REGA4	RES 1
REGA3	RES 1
REGA2	RES 1
REGA1	RES 1
REGA0	RES 1
REGB3	res 1
REGB2	res 1
REGB1	res 1
REGB0	res 1
REGC3	res 1
REGC2	res 1
REGC1	res 1
REGC0	res 1

Ford_T4	res 1
Ford_T3	res 1
Ford_T2	res 1
Ford_T1	res 1
Ford_T0	res 1

CHARBUF	res 1

LCD	udata	0x5B
	;kijelzőszámlálók
LCDByte	RES 1	;
HiByte	RES 1	;
LoByte	RES 1	;
LCDTar	RES 1	;
LCDVez	RES 1	;
;LCDAdd	RES 1	;
;RSbit	RES 1	;
LCD_K	udata	0x60
DIGIT0	RES 1	;Digit Sign. 0=positive,1=negative
DIGIT1	RES 1	;MSD
DIGIT2	RES 1	;
DIGIT3	RES 1	;
DIGIT4	RES 1	;
DIGIT5	RES 1	;Decimal (BCD) digits
DIGIT6	RES 1	;
DIGIT7	RES 1	;
DIGIT8	RES 1	;
DIGIT9	RES 1	;
DIGIT10	RES 1	;LSB
DIGIT11	RES 1	;
DIGIT12	RES 1	;
DIGIT13	RES 1	;
DIGIT14	RES 1	;
DIGIT15	RES 1	;



adat	udata	0xA0	;bank1
adatbuff	RES d'20'


;
;***** VARIABLE DEFINITIONS megszakításhoz
INT_VAR	UDATA_SHR	;bank- 0x70-7F; F0-FF; 170-17F; 1F0-1FF
w_temp      	RES 1       ; variable used for context saving
status_temp	RES 1       ; variable used for context saving
pclath_temp	RES 1       ; variable used for context saving
FSR_temp	RES 1
SSTATUS		RES 1

;
;




	ORG	0X00
	nop
	GOTO	Kezd_init
	
	ORG	0X04
	movwf	w_temp            ; save off current W register contents
	swapf	STATUS,w          ;adatlap szerint swapf-al kell!
	movwf	status_temp       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	pclath_temp	  ; save off contents of PCLATH register
	clrf	PCLATH

	btfss	INTCON,INTE
	goto	exit_isr	
	BTFSC	INTCON,INTF	;PORT B0 okozta a megszakitást
	goto	RBINT
	goto	exit_isr
RBINT:
	BCF	INTCON,INTF
	btfss	Flag,7
	goto	Mérés_indul
	goto	Mérés_leáll

;	btfsc	T1CON,0		;ha TIMER1 állt - indul, ha megy mérés folyamatban
;	goto	RB_megy
;;	BCF	T1CON,0		;TIMER1	leállitása
Mérés_indul:
	movlw	0x0
	movwf	TMR1L
	movwf	TMR1H
	BSF	T1CON,0		;TIMER1 indul, vagy mehet tovább
	movwf	Tcs
	bsf	Flag,7		;fordulatszám-mérés folyamatban
	goto	exit_isr
RB_megy:
Mérés_leáll:
	bcf	T1CON,0		;TIMER1	leállitása
	bcf	Flag,7		;fordulatszám-mérés leállítása
	goto	exit_isr

exit_isr:
	banksel	w_temp
	movf	pclath_temp,w	; retrieve copy of PCLATH register

	movwf	PCLATH		; restore pre-isr PCLATH register contents
	swapf	status_temp,w	; adatlap szerint swapf-al kell!
	movwf	STATUS		; restore pre-isr STATUS register contents
	swapf	w_temp,f
	swapf	w_temp,w	; restore pre-isr W register contents
	retfie			; return from interrupt


Kezd_init:
	BANKSEL	ANSEL
	CLRF	ANSEL		
	CLRF	ANSELH
	BANKSEL	PORTA
	CLRF	PORTA
	BANKSEL	TRISA
	MOVLW	B'11111111'	;A6,A7 qvarc, többi LCD	
	MOVWF	TRISA
			
	BANKSEL	PORTB
	CLRF	PORTB		;PortB debug módban nem megy!?
	BANKSEL	TRISB	
	MOVLW	B'10011111'	; B6,B7 ICSP
				; B0-B2 senzor bemenetek
	MOVWF	TRISB		; B3-B4 billenytyűzet olvasáshoz BEMENET
				; B5-LED jel/túlvezérlés

	BANKSEL	PORTC
	CLRF	PORTC	
	bsf	PORTC,RTS	;EUSART fogadás tiltása
	BANKSEL	TRISC	
	MOVLW	B'11111011'	; C2=Infra LED vezérlés, ( C3,C4 I2C-hez,)
	MOVWF	TRISC		;C6-C7 TX-RX lesz

	bcf	TRISC,RTS
	movlw	b'11011111'	;TMR0 belső órán, előosztó (1:128) WDT-re
	movwf	OPTION_REG
	
	BANKSEL	PORTA
	clrf	T1CON	;TIMER1 alapon
	pagesel	LCD	;LCD és matek rutinok page 1-en
	call	LCDINIT
	call	DIGITclear
	call	lcdclear
	call	INIT_LCD
	call	Kiir1
	call	vár_1sec
	call	LCD_CGRAM	;CGRAM feltöltés "á"-->'0x01', "é"-->'0x02'
	call	EUSART_INIT
;	call	vár_1sec
Kezd:
	pagesel	LCD
	call	DIGITclear
	call	lcdclear
	call	Beállít_LCD	;'Beállitás kész?'
	call	Kiir1
	call	vár_1sec
	call	DIGITclear
	call	Kiir2

;
Főprog:
	pagesel	Főprog
	bsf	Nagyjel_LED	; LED ki
	bcf	INFRA	;infra LED be
	call	Bilkez
	movf	Gomb,W
	sublw	0x1	;'YES?'
	btfsc	STATUS,Z
	goto	Fő_0
	goto	Főprog	
Fő_0:
;	bsf	INFRA	;infra LED ki
	pagesel	LCD
	call	Ford_LCD	;LCD-re "Ford mérés"
	call	Kiir1	;LCD-re	
	pagesel	Főprog

	pagesel	LCD
	call	Mérés_LCD	;LCD-re "Mérés indul?"
	call	Kiir2
	call	vár_1sec
	pagesel	Főprog
Bil1:	call	Bilkez
	movf	Gomb,W
	sublw	d'1'	;"YES"
	btfsc	STATUS,Z
	goto	Fő1
	movf	Gomb,W
	sublw	d'2'	;"No"
	btfsc	STATUS,Z
	goto	Kezd
	goto	Bil1

Fő1:
	pagesel	Főprog
Fő11:	call	Ford_m	;Fordulatszám mérése
	pagesel	LCD	;LCD és matek rutinok page 1-en
	call	Kiir1	;LCD-re "Ford xxxx 1/min"
	pagesel	Főprog
	nop

	pagesel	LCD
	call	Stabil_LCD	;LCD-re "stabil?"
	call	Kiir2
	pagesel	Főprog
;Bil2:
	call	Bilkez
	movf	Gomb,W
	sublw	d'0'	;"nem volt gombnyomás"
	btfsc	STATUS,Z
	goto	Fő11	;fordulatszámmérés itt - folyamatosan
	movf	Gomb,W
	sublw	d'1'	;"YES"
	btfsc	STATUS,Z
	goto	Fő2
	movf	Gomb,W
	sublw	d'2'	;"No"
	btfsc	STATUS,Z
	goto	Kezd
Fő2:
	pagesel	LCD
	call	DIGITclear	;LCD-ről "stabil?" törlése
	call	Kiir2
	pagesel	Főprog
	call	M_idő	;Mérési időintervallum meghatározása (ciklusszám)
	call	M_idő_LCD		;REGA-ban is a rezgésmérések ciklusszáma
	movf	M_cik2,W
	addlw	0x0
	btfss	STATUS,Z
	goto	Fő_0
	movf	M_cik3,W
	addlw	0x0
	btfss	STATUS,Z
	goto	Fő_0



;*********************************************
;	Alprogramok
;*********************************************	

Ford_m:	;Fordulatszám mérése
	bcf	INFRA	;infra LED be
	pagesel	LCD
	call	vár_100		;ford. szenzor kimenet stabilizálódására várunk
	pagesel	Főprog
	clrf	BeSzL
	clrf	BeSzH
	BCF	STATUS,RP0	;Bank0

	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

F0:	clrf	Tcs
	clrf	BeSzL
	clrf	BeSzH

	btfss	Flag,7	;megvárjuk amíg 0-ba megy
	goto	$-1
F1:	btfss	Flag,7
	goto	Merveg
	btfss	PIR1,TMR1IF
	goto	Időn_túl
	bcf	PIR1,TMR1IF
	incfsz	BeSzL,f
	goto	F1
	incfsz	BeSzH,f
	goto	F1
	incf	Tcs,f
;	goto	Ftmr1
Időn_túl:
	movlw	0x0
	subwf	Tcs,W
	btfsc	STATUS,Z
	goto	F1
	goto	F0


Merveg:	BCF	INTCON,GIE	;Megszakitások TILTVA
	bcf	INTCON,INTE	;Bport már nem szakithat meg
	BCF	T1CON,0		;TIMER1	leállitása

;	bsf	INFRA	;infra LED ki


;Foprdulatszám-számitas:
	movf	TMR1L,w
	movwf	Cikl0
	movf	TMR1H,w
	movwf	Cikl1
	movf	BeSzL,w
	movwf	Cikl2
	movf	BeSzH,w
	movwf	Cikl3	;ciklusszám 1 fordulatra

	clrf	REGB3
	clrf	REGA4

	movlw	Konst_F1(0x1000000)
	movwf	REGA3
	movlw	Konst_F1(0x10000)
	movwf	REGA2
	movlw	Konst_F1(0x100)
	movwf	REGA1
	movlw	Konst_F1(0x1)
	movwf	REGA0

	movf	TMR1L,w
	movwf	REGB0
	movf	TMR1H,w
	movwf	REGB1
	movf	BeSzL,w
	movwf	REGB2
	movf	BeSzH,w
	movwf	REGB3	;ciklusszám 1 fordulatra REGB-ben
	pagesel	LCD
	CALL	divide	;fordulatszám/min REGA-ban
	pagesel	Főprog

Atalakit:
	pagesel	LCD
	call	bin2dec		;rega-->decimálissá
	call	DEC_KAR_10	;karakter átalakítás
	pagesel	Főprog

	movlw	'F'
	movwf	DIGIT0
	movlw	'o'
	movwf	DIGIT1
	movlw	'r'
	movwf	DIGIT2
	movlw	'd'
	movwf	DIGIT3
	movlw	'='
	movwf	DIGIT4
	movlw	' '
	movwf	DIGIT11
	movlw	'/'
	movwf	DIGIT12
	movlw	'm'
	movwf	DIGIT13
	movlw	'i'
	movwf	DIGIT14
	movlw	'n'
	movwf	DIGIT15

	movf	DIGIT5,W	;elölfutó 0-k törlése
	sublw	0x30
	btfsc	STATUS,Z
	goto	Tör1
	goto	veg
Tör_1:	movf	DIGIT6,W
	sublw	0x30
	btfsc	STATUS,Z
	goto	Tör2
	goto	veg
Tör_2:	movf	DIGIT7,W
	sublw	0x30
	btfsc	STATUS,Z
	goto	Tör3
	goto	veg
Tör_3:	movf	DIGIT8,W
	sublw	0x30
	btfsc	STATUS,Z
	goto	Tör4
	goto	veg

Tör1:	movlw	0x20	;space
	movwf	DIGIT5
	goto	Tör_1
Tör2:	movlw	0x20
	movwf	DIGIT6
	goto	Tör_2
Tör3:	movlw	0x20
	movwf	DIGIT7
	goto	Tör_3
Tör4:	movlw	0x20
	movwf	DIGIT8
;	goto	Tör_4
veg:	;return

Ford_ment:
	movf	DIGIT10,W
	movwf	Ford_T0
	movf	DIGIT9,W
	movwf	Ford_T1
	movf	DIGIT8,W
	movwf	Ford_T2
	movf	DIGIT7,W
	movwf	Ford_T3
	movf	DIGIT6,W
	movwf	Ford_T4
	return

;******************************************

;****************************************************************
Bilkez:	;csak akkor jön ki belőle, ha (már-még) nincs gombnyomás!
	banksel	Gomb	;bank0
	clrf	Gomb
;	banksel	PORTLCD	;bank0
	clrf	TEMP
	bsf	TEMP,LCDEnable
	bsf	TEMP,LCDRS	;(karakter mód maradjon)
	movf	TEMP,W
	movwf	PORTLCD
	banksel	TRISLCD
;	movwf	TRISLCD		;LCD DB7-DB4 kimenet eng.
	clrf	TRISLCD	;RS és LCDEnable is eng. - hogy ne lebegjen
	banksel	PORTLCD

Bil_V:	bcf	bill_ki0
	bcf	bill_ki1
	bcf	bill_ki2
	bcf	bill_ki3

	bsf	bill_ki0	;-High
	pagesel	LCD
	call	vár_1
	pagesel	Főprog
	btfsc	bill_be1
	goto	bill01
;	btfsc	bill_be2	;2.bemenet most nincs használva
;	goto	bill02
	bcf	bill_ki0

	bsf	bill_ki1	;-High
	pagesel	LCD
	call	vár_1
	pagesel	Főprog
	btfsc	bill_be1
	goto	bill11
;	btfsc	bill_be2	;2.bemenet most nincs használva
;	goto	bill12
	bcf	bill_ki1

	bsf	bill_ki2	;-High
	pagesel	LCD
	call	vár_1
	pagesel	Főprog
	btfsc	bill_be1
	goto	bill21
;	btfsc	bill_be2	;2.bemenet most nincs használva
;	goto	bill22
	bcf	bill_ki2

	bsf	bill_ki3	;-High
	pagesel	LCD
	call	vár_1
	pagesel	Főprog
	btfsc	bill_be1
	goto	bill31
;	btfsc	bill_be2	;2.bemenet most nincs használva
;	goto	bill32
	bcf	bill_ki3
	goto	bilvég

bill01:	movlw	0x1	;föl
	movwf	Gomb
	goto	Bil_V	;bilvég
bill11:	movlw	0x2	;le
	movwf	Gomb
	goto	Bil_V	;bilvég
bill21:	movlw	0x3	;jobbra
	movwf	Gomb
	goto	Bil_V	;bilvég
bill31:	movlw	0x4	;balra
	movwf	Gomb
	goto	Bil_V	;bilvég

;bill02:	movlw	0x11	;mód	2.bemenet most nincs használva
;	movwf	Gomb
;	goto	bilvég
;bill12:	movlw	0x12	;Yes	2.bemenet most nincs használva
;	movwf	Gomb
;	goto	bilvég
;bill22:	movlw	0x13	;No	2.bemenet most nincs használva
;	movwf	Gomb
;	goto	bilvég
;bill32:	movlw	0x14	;?	2.bemenet most nincs használva
;	movwf	Gomb
;	goto	bilvég
bilvég:
	movlw	LCDmaszk
	movwf	TEMP
	comf	TEMP,W
	banksel	TRISLCD
	iorwf	TRISLCD,f	;LCD DB7-DB4 kimenet letíltva
	banksel	PORTLCD
	return





;*************************************************

;*************************************************

	org	0x800	;page1
LCD:		;page1 név

;soros (EUSART) regiszterek:
;		bit
;BAUDCTL	4--SCKP	;1- adat invertálás (TX)
;		3--BRG16	;1- 16 bites baudrate, 0- 8 bites
;INTCON	7--GIE	;
;		6--PEIE	;
;PIE1		1--TMR2IE	;
;PIR1		1--TMR2IF	;PR2-vel Comparál+Postscater(1:1-1:16)->flag
;		5--RCIF	;ha=1 - vételi buffer tele, =0 buffer üres
;RCREG	Recieve Data Register
;RCSTA	7-- SPEN	;=1	;soros port engedélyezése RX/TX pin
;		6-- RX9	;=0	;1-- 9 bites, 0-- 8 bites
;		5-- SREN	;=0	;csak synchron - master módban
;		4-- CREN	;=1	;vétel engedélyezése
;		3-- ADDEN	;=0	;cím detektálás engedélyezése, ha RX9=1
;		2-- FERR		;Framing Error bit (=1 nem valós byte, =0 nincs hiba)
;		1-- OERR		;Overrun Error (=0 nincs hiba)
;		0-- RX9D		;paritás vagy cím/adat bit feldolgozás felhasználói feladat
;SPBRG	BRG7- BRG0		;baudrate
;	pl.:	9600	Fosc=8MHz - SPBRG=51, SYNC=0, BRGH=1, BRG16=0
;			Fosc=20MHz - SPBRG=129, SYNC=0, BRGH=0, BRG16=0
;	pl.:	19,2k	Fosc=8MHz - SPBRG=25, SYNC=0, BRGH=1, BRG16=0
;			Fosc=20MHz - SPBRG=64, SYNC=0, BRGH=0, BRG16=0
;SPBRGH	BRG15- BRG8		;
;TRISC	TRISC7	;=1	;RX pin
;		TRISC6 	;=1	;TX pin
;		TRISC5		;
;		TRISC4		;
;		TRISC3		;
;		TRISC2		;
;		TRISC1		;
;		TRISC0		;
;TXREG	Transmit Data Register
;TXSTA	7--CSRC		;csak syncron módban
;		6--TX9		;1-- 9 bites, 0-- 8 bites
;		5--TXEN		;1-- adás engedélyezése
;		4--SYNC	;=0	;0-- asyncron mód
;		3--SENDB		;ha=1 - küldés folyamatban, =0 - átvitel befejeződött
;		2--BRGH		;=1-- nagy sebességü, =0-- kissebességü
;		1--TRMT		;=1-- TSR üres, =0-- TSR tele
;		0--TX9D		;9. bit lehet (cím/data vagy paritás)
;			
;*************************************************

;*************************************************
INIT_LCD:
	call	lcdclear
	movlw	' '
	movwf	DIGIT1
	movlw	' '
	movwf	DIGIT2
	movlw	' '
	movwf	DIGIT3
	movlw	'_'
	movwf	DIGIT4
	movlw	'I'
	movwf	DIGIT5
	movlw	'N'
	movwf	DIGIT6	
	movlw	'I'
	movwf	DIGIT7
	movlw	'T'
	movwf	DIGIT8
	call	Kiir1
	return
;*************************************************
Beállít_LCD:	;'Beállitás kész?'
	call	DIGITclear
	movlw	'B'
	movwf	DIGIT1
	movlw	'e'
	movwf	DIGIT2
	movlw	0x01	;'á'
	movwf	DIGIT3
	movlw	'l'
	movwf	DIGIT4
	movwf	DIGIT5
	movlw	'i'
	movwf	DIGIT6
	movlw	't'
	movwf	DIGIT7
	movlw	0x01	;'á'
	movwf	DIGIT8
	movlw	's'
	movwf	DIGIT9
	movlw	' '
	movwf	DIGIT10
	movlw	'k'
	movwf	DIGIT11
	movlw	0x02	;'é'
	movwf	DIGIT12
	movlw	's'
	movwf	DIGIT13
	movlw	'z'
	movwf	DIGIT14
	movlw	'?'
	movwf	DIGIT15
	return
;*************************************************
Ford_LCD:
	call	DIGITclear
	movlw	'F'
	movwf	DIGIT2
	movlw	'o'
	movwf	DIGIT3	
	movlw	'r'
	movwf	DIGIT4
	movlw	'd'
	movwf	DIGIT5
;	movlw	' '
;	movwf	DIGIT6
	movlw	'm'
	movwf	DIGIT7
	movlw	0x02	;'é'
	movwf	DIGIT8
	movlw	'r'
	movwf	DIGIT9
	movlw	0x02	;'é'
	movwf	DIGIT10
	movlw	's'
	movwf	DIGIT11
	return
;*************************************************
Stabil_LCD:
	call	DIGITclear
	movlw	's'
	movwf	DIGIT4
	movlw	't'
	movwf	DIGIT5	
	movlw	'a'
	movwf	DIGIT6
	movlw	'b'
	movwf	DIGIT7
	movlw	'i'
	movwf	DIGIT8
	movlw	'l'
	movwf	DIGIT9
	movlw	'?'
	movwf	DIGIT11
	return
;*************************************************
Mérés_LCD:
	call	DIGITclear
	movlw	'M'
	movwf	DIGIT1
	movlw	0x02	;'é'
	movwf	DIGIT2
	movlw	'r'
	movwf	DIGIT3
	movlw	0x02	;'é'
	movwf	DIGIT4
	movlw	's'
	movwf	DIGIT5
;	movlw	' '
;	movwf	DIGIT6	
	movlw	'i'
	movwf	DIGIT7
	movlw	'n'
	movwf	DIGIT8	
	movlw	'd'
	movwf	DIGIT9
	movlw	'?'
	movwf	DIGIT10
	return
;*************************************************
;*************************************************
;negativ:
;	comf	REGA0,f
;	comf	REGA1,f
;	comf	REGA2,f
;	comf	REGA3,f
;	return
;
;;;*************************************************


DIGITclear:
	banksel	DIGIT0
	movlw	' '	;0x20
	movwf	DIGIT0
	movwf	DIGIT1
	movwf	DIGIT2
	movwf	DIGIT3
	movwf	DIGIT4
	movwf	DIGIT5
	movwf	DIGIT6
	movwf	DIGIT7
	movwf	DIGIT8
	movwf	DIGIT9
	movwf	DIGIT10
	movwf	DIGIT11
	movwf	DIGIT12
	movwf	DIGIT13
	movwf	DIGIT14
	movwf	DIGIT15
	return
;*************************************************

;*************************************************

LCDINIT:
	banksel	PORTLCD	;Bank0
	bcf	PORTLCD,LCDRS	;vezérlés mód           
	call	vár_100
	call	vár_100
	call	vár_100
; lassú tápfelfutás miatt ajánlott:
	movlw	b'00110000'     ;b'00110100'    ;FUNKCIO 8 bites interface
	call	LCD_nible
	movlw	b'00110000'     ;b'00110100'    ;FUNKCIO 8 bites interface
	call	LCD_nible
	movlw	b'00110000'     ;b'00110100'    ;FUNKCIO 8 bites interface
	call	LCD_nible
	call	vár_100
	
	movlw	b'00100000'     ;b'00100100'    ;FUNKCIO 4 bites interface
	call	LCD_nible
	call	vár_100u
;
	movlw	b'00111000'     ;2 soros, norm 5x7 pixel
	movwf	LCDVez
	call	LCDVEZ
	call	vár_100u
	movlw	b'00001100'     ;kijelző be, kurzor aláhúzás ki, villogás ki
	movwf	LCDVez
	call	LCDVEZ
	call	vár_100u
	movlw	b'00000001'     ;kijelző tőrlés
	movwf	LCDVez
	call	LCDVEZ
	call	vár_1
	call	vár_1   
	movlw	b'00000110'     ;Entry(karakterbeviteli) mód: kursor increment, kijelző eltolás ki
	movwf	LCDVez
	call	LCDVEZ
	call	vár_100u
	RETURN


LCD_CGRAM:
JOG_kar:	;emberke karakter CGRAM-ba
	movlw	b'01000000'	;hiv. LCDByte= 0 vagy 8 --0x40
	MOVWF	LCDVez
	CALL	LCDVEZ
	movlw	b'00001110'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00010001' 	
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001110'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000100'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00011111'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000100'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001010'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00010001'
	movwf	LCDByte
	call	LCDBYTE

á:	;"á' karakter CGRAM-ba
	movlw	b'01001000'	;hiv. LCDByte= 1 vagy 9  --0x48
	MOVWF	LCDVez
	CALL	LCDVEZ
	movlw	b'00000010'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000100' 	
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001110'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000001'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00011111'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00010001'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001111'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000000'	;--aláhúzás helye
	movwf	LCDByte
	call	LCDBYTE

é:	;"é' karakter CGRAM-ba
	movlw	b'01010000'	;hiv. LCDByte= 1 vagy 9  --0x50
	MOVWF	LCDVez
	CALL	LCDVEZ
	movlw	b'00000010'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000100' 	
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001110'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00010001'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00011111'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00010000'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00001110'
	movwf	LCDByte
	call	LCDBYTE
	movlw	b'00000000'	;--aláhúzás helye
	movwf	LCDByte
	call	LCDBYTE
	return

lcdclear:
	movlw	0x01
	movwf	LCDVez
	call	LCDVEZ
	call	vár_100
	movlw	0x02	;kijelző és kurzor alaphelyzetbe
	movwf	LCDVez
	call	LCDVEZ
	call	vár_100
	return 
 
LCDLINE1:	; kurzor az 1. sor elejére
	movlw	b'00000000'	;0h
	movwf	LCDVez
	bsf	LCDVez,0x7
	goto	LCDVEZ
;	RETURN
LCDLINE2:	; 
	movlw	b'01000000'	;40h
	movwf	LCDVez
	bsf	LCDVez,0x7
	goto	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
	goto	LCDVEZ
;	RETURN

LCDVEZ:	; makes LCDVez the current LCD Address
	bcf	PORTLCD,LCDRS
	movf	LCDVez,W        ;parancsmód bekapcs.
	movwf	LCDByte
	call	LCDBYTE
	bsf	PORTLCD,LCDRS   ;vissza karaktermódba
	RETURN

LCDBYTE:	;1 byte az LCD-re,  4 bites interface
		; Be: LCDByte  - nibble ki: hiByte, loByte
		;RS-t  t kell engedni'''
	clrf	HiByte 
	clrf	LoByte
	movf	LCDByte,W	; Karakter a W-be
	movwf	HiByte
	movwf	LoByte
	swapf	LoByte,f
	movf	HiByte,W
	call	LCD_nible
	movf	LoByte,W
	call	LCD_nible
	RETURN

LCD_nible:
;		RSbit=1-> karakter
;		RSbit=0-> vezérlés
	banksel	PORTLCD
	movwf	LCDTar
	movlw	LCDmaszk
	movwf	TEMP
	comf	TEMP,W
	banksel	TRISLCD
	iorwf	TRISLCD,f	;LCD DB7-DB4 kimenet letíltva
	banksel	PORTLCD

	MOVLW	0xF0	; W=b'11110000'
	ANDWF	LCDTar,f
	rrf	LCDTar,f
	rrf	LCDTar,f

	movlw	LCDmaszk
	movwf	TEMP
	comf	TEMP,W
	comf	LCDTar,f
	xorwf	LCDTar,f
;	bsf	LCDTar,LCDEnable	;xor már 1-be tette
;	bsf	LCDTar,LCDRS	;xor már 1-be tette
	btfss	PORTLCD,LCDRS
	bcf	LCDTar,LCDRS    
	movf	LCDTar,W
	movwf	PORTLCD	;adat előkészítve

	movlw	LCDmaszk
	movwf	TEMP
	bcf	TEMP,LCDRS
	bcf	TEMP,LCDEnable
	movf	TEMP,W          
	banksel	TRISLCD
	andwf	TRISLCD,f	;adat a porton

	banksel	PORTLCD
	call	vár_100u                        
	bcf	PORTLCD,LCDEnable	;LCD olvas      
	call	vár_100u                        
	bsf	PORTLCD,LCDEnable
	movlw	LCDmaszk
	movwf	TEMP
	comf	TEMP,W
	banksel	TRISLCD
	iorwf	TRISLCD,f       ;LCD DB7-DB4 kimenet letíltva
	banksel	PORTLCD ;bank0          
	return

;*************************************************
	
Kiir1:;	call	LCDLINE1
	movlw	#DIGIT0		;regisztercim, a sor első karaktere
	movwf	DSZ
	movlw	0x0		;1. sor első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10		;16 karaktert irunk ki
	movwf	PSZ
	goto	KAR_KI

Kiir2:;	call	LCDLINE2
	movlw	#DIGIT0
	movwf	DSZ
	movlw	0x40		;2. sor első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10
	movwf	PSZ
	goto	KAR_KI

Kiir3:;	call	LCDLINE2
	movlw	#DIGIT0
	movwf	DSZ
	movlw	0x10		;3. sor első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10
	movwf	PSZ
	goto	KAR_KI

Kiir4:;	call	LCDLINE2
	movlw	#DIGIT0
	movwf	DSZ
	movlw	0x50		;4. sor első kar. cime az LCD-n
	movwf	KSZ
	movlw	0x10
	movwf	PSZ
	goto	KAR_KI

;*************************************************
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	INDF,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	INDF,W
	movwf	LCDByte
	call	LCDBYTE
	incf	FSR,f
	decfsz	PSZ,f
	goto	hz2
hz3:	RETURN

;*************************************************
DEC_KAR:	;DEC.szám - karakterré
		;DIGIT0---> DIGIT15
	movf	DIGIT0,W
	ADDLW	0x30
	MOVWF	DIGIT0

	movf	DIGIT11,W
	ADDLW	0x30
	MOVWF	DIGIT11
	movf	DIGIT12,W
	ADDLW	0x30
	MOVWF	DIGIT12
	movf	DIGIT13,W
	ADDLW	0x30
	MOVWF	DIGIT13
	movf	DIGIT14,W
	ADDLW	0x30
	MOVWF	DIGIT14
	movf	DIGIT15,W
	ADDLW	0x30
	MOVWF	DIGIT15
DEC_KAR_10:
	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
Plusz:	movlw	'+'
	movwf	DIGIT2
	RETURN
;*************************************************
KAR_DEC:	;Karakter DEC. számmá
		;DIGIT2 - előjel, DIGIT8 - tizedespont
		;DIGIT3-11 --> DIGIT3-10
	clrf	DIGIT1	;binárissá alakítás miatt kell (dec2dbin)
	movlw	0x30
	subwf	DIGIT3,f
	subwf	DIGIT4,f
	subwf	DIGIT5,f
	subwf	DIGIT6,f
	subwf	DIGIT7,f
	subwf	DIGIT9,W
	movwf	DIGIT8
	movlw	0x30
	subwf	DIGIT10,W
	movwf	DIGIT9
	movlw	0x30
	subwf	DIGIT11,W
	movwf	DIGIT10
	clrf	DIGIT11
		
	clrf	DSIGN
	movlw	'-'
	xorwf	DIGIT2,W
	btfss	STATUS,Z
	goto	kar_pos
kar_neg:
	clrf	DIGIT2
	bsf	DSIGN,0
	return
kar_pos:
	clrf	DIGIT2
	bcf	DSIGN,0
	RETURN

;*************************************************	
vár_5u: 	; 5us
	movlw	(d'5'*FOSC/(4*d'1000000'*3))	;0x7	;
	movwf	d1
	goto	vár_u_0
vár_10u:	; 10us
	movlw	(d'10'*FOSC/(4*d'1000000'*3))	;0x10	;
	movwf	d1
	goto	vár_u_0
vár_100u:	; 100us
	movlw	(d'100'*FOSC/(4*d'1000000'*3))	;0xA5	;(0x21-4MHz)
	movwf	d1
vár_u_0:	;4 cycles (including call)
	decfsz	d1, f
	goto	vár_u_0                  
	RETURN

vár_1:		; 1 msec
	movlw	(d'1'*FOSC/(4*d'1000'*5))	;0xE8
	movwf	d1
	movlw	(1+d'1'*FOSC/(4*d'1000'*5*0xFF))	;0x4
	movwf	d2
	goto	vár_0
vár_100:	; 100 msec
	call	vár_50
	call	vár_50
	return
;vár_50:		; 50 msec
;	movlw	0x3E	;0x1F
;	movwf	d1
;	movlw	0xc3
;	movwf	d2
vár_50:		; 50 msec
	movlw	(d'50'*FOSC/(4*d'1000'*5))
	movwf	d1
	movlw	(d'50'*FOSC/(4*d'1000'*5*0xFF))
	movwf	d2
vár_0:
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	vár_0	;2 cycles
	goto	$+1
	nop		;4 cycles (including call)
	RETURN
vár_1sec:
	movlw	d'10'
	movwf	d3
	call	vár_100
	decfsz	d3,f
	goto	$-2
	return

;*************************************************

;*************************************************

KAR_REGA:	;beírt szám átalakítása (DSZ-től-->REGA)
		;5.3-as formátumot kezel (használja:DIGIT0-11)
		;46,5 - 108.5 usec <--8MHz

	clrf	TEMP1
	clrf	TEMP1+1
	clrf	TEMP1+2
	clrf	TEMP1+3
	clrf	TEMP1+4
	clrf	TEMP1+5
	clrf	TEMP1+6
	clrf	TEMP1+7
	clrf	TEMP1+8
	clrf	DSIGN
	clrf	PSZ	

	movf	FSR,W 
	movwf	KSZ	;mutató/"számjegy" szám1áló
loop3:	btfsc	d1,1	;Rusart feldolgozásból?
	bsf	STATUS,IRP	;FSR bank 2(-3)-re mutasson!
	movf	INDF,W
	banksel	TEMP
	movwf	TEMP
	andlw	b'00110000'
	sublw	b'00110000'	
	btfsc	STATUS,Z
	goto	szám
	movf	TEMP,W
	xorlw	'-'
	btfsc	STATUS,Z
	goto	negatív
	movf	TEMP,W
	xorlw	'+'
	btfsc	STATUS,Z
	goto	pozitív
	movf	TEMP,W
	iorlw	b'00000010'
	sublw	'.'
	btfsc	STATUS,Z
	goto	tvessző
	goto	nemszám	;vége a feldolgozásnak
	
szám:			;egészek
	movf	TEMP1+1,W
	movwf	TEMP1
	movf	TEMP1+2,W
	movwf	TEMP1+1
	movf	TEMP1+3,W
	movwf	TEMP1+2
	movf	TEMP1+4,W
	movwf	TEMP1+3

	movlw	0x30
	subwf	TEMP,W
	movwf	TEMP1+4
	incf	FSR,f
	goto	loop3
	
tvessző:
	incf	KSZ,f
	incf	FSR,f		;tizedesek
	movf	INDF,W
	movwf	TEMP
	andlw	b'00110000'
	sublw	b'00110000'	
	btfss	STATUS,Z
	goto	nemszám
	movlw	0x30
	subwf	TEMP,W
	movwf	TEMP1+5
	incf	PSZ,f	;tizedes számláló
	incf	FSR,f
	movf	INDF,W
	movwf	TEMP
	andlw	b'00110000'
	sublw	b'00110000'	
	btfss	STATUS,Z
	goto	nemszám
	movlw	0x30
	subwf	TEMP,W
	movwf	TEMP1+6
	incf	PSZ,f	;tizedes számláló
	incf	FSR,f
	movf	INDF,W
	movwf	TEMP
	andlw	b'00110000'
	sublw	b'00110000'	
	btfss	STATUS,Z
	goto	nemszám
	movlw	0x30
	subwf	TEMP,W
	movwf	TEMP1+7
	incf	PSZ,f	;tizedes számláló
	incf	FSR,f
	goto	nemszám

negatív:
	nop
	movlw	1
	movwf	DSIGN	;=1 ha negatív
pozitív:
	incf	KSZ,f
	incf	FSR,f
	goto	loop3

nemszám:
	nop
	nop	;FSR a köv. beolvasandóra mutat
	movf	FSR,W
	movwf	DSZ
	movf	PSZ,W
	addwf	KSZ,W
	subwf	FSR,W
	movwf	KSZ
	sublw	5
	btfss	STATUS,C
	goto	hiba	;8 számjegynél több!
v:	clrf	DIGIT0
	clrf	DIGIT1
	clrf	DIGIT2
	movf	TEMP1,W
	movwf	DIGIT3
	movf	TEMP1+1,W
	movwf	DIGIT4
	movf	TEMP1+2,W
	movwf	DIGIT5
	movf	TEMP1+3,W
	movwf	DIGIT6
	movf	TEMP1+4,W
	movwf	DIGIT7
	movf	TEMP1+5,W
	movwf	DIGIT8
	movf	TEMP1+6,W
	movwf	DIGIT9
	movf	TEMP1+7,W
	movwf	DIGIT10
	movf	TEMP1+8,W
	movwf	DIGIT11
	movlw	d'10'
	bcf	STATUS,IRP	;FSR Bank0-ra mutasson!
	pagesel	dec2bin
	call	dec2bin	;DIGIT2előjel 3-10számok --> REGA0-3 és DSIGN
	pagesel	KAR_REGA
	nop	
	btfss	DSIGN,1	;negatív!
	return
	comf	REGA0,f
	comf	REGA1,f
	comf	REGA2,f
	comf	REGA3,f
	return
hiba:
;	pagesel	RESET
;	call	RESET
	return

;***************************************
MPY8X8:	;REGA0*W=REGA1;REGA0
	clrf REGA1
	clrf count
	bsf count,3
	rrf REGA0,F
LOOP8x8:
;	SKPNC
	btfsc	STATUS,C
	addwf REGA1,F
	
	rrf REGA1,F
	rrf REGA0,F

	decfsz count,f
	goto LOOP8x8
	return

oszt1000:
	banksel	REGB0
	clrf	REGB3
	clrf	REGB2
	movlw	0x3
	movwf	REGB1
	movlw	0xE8
	movwf	REGB0
	banksel	REGA0
	call	divide
	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->regA-ba
;

;*************************************************

     ;*** 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
      	
      ;Set all digits to 0
      ;Used by bin2dec


      ;*** 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


;belső rutinok - matekhez

clrdig:	clrf	DSIGN
      	clrf	DIGIT1
      	clrf	DIGIT2
      	clrf	DIGIT3
      	clrf	DIGIT4
      	clrf	DIGIT5
      	clrf	DIGIT6
      	clrf	DIGIT7
      	clrf	DIGIT8
      	clrf	DIGIT9
      	clrf	DIGIT10
      	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

      ;*** 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
	banksel	REGB0
      	xorwf	REGB3,w
	banksel	REGA0
      	movwf	MTEMP

      	call	addba		;Add REGB to REGA

      	clrc			;Check signs
	banksel	REGB0
      	movf	REGB3,w		;If signs are same
	banksel	REGA0
      	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
	banksel	REGC0      	
      	rlf	REGC3,w		;Test MSB of multiplicand
	banksel	REGA0
      	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
	banksel	REGB0
     	movf	REGB0,w		;Trap division by zero
      	iorwf	REGB1,w
      	iorwf	REGB2,w
      	iorwf	REGB3,w
      	sublw	0
	banksel	REGA0
      	skpc
      	call	absa		;Make dividend (REGA) positive
      	skpc
      	call	absb		;Make divisor (REGB) positive
      	skpnc
      	return			;Overflow

	banksel	REGC0
      	clrf	REGC0		;Clear remainder
      	clrf	REGC1
      	clrf	REGC2
      	clrf	REGC3
	banksel	REGA0
      	call	slac		;Purge sign bit

      	movlw	D'31'		;Loop counter
      	movwf	MCOUNT

dvloop:	call	slac		;Shift dividend (REGA) msb into remainder (REGC)
	banksel	REGB0
      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
	banksel	REGA0
      	skpz
      	goto	dtstgt
	banksel	REGB0
      	movf	REGB2,w
      	subwf	REGC2,w
	banksel	REGA0
      	skpz
      	goto	dtstgt
	banksel	REGB0
      	movf	REGB1,w
      	subwf	REGC1,w
	banksel	REGA0
      	skpz
      	goto	dtstgt
	banksel	REGB0
      	movf	REGB0,w
      	subwf	REGC0,w
	banksel	REGA0
dtstgt:	skpc			;Carry set if remainder >= divisor
      	goto	dremlt
	banksel	REGB0
      	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
 	banksel	REGA0
      	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
	banksel	REGB0
      	movf	REGB3,w		;Test if remainder (REGC) >= divisor (REGB)
      	subwf	REGC3,w
	banksel	REGA0
      	skpz
      	goto	rtstgt
	banksel	REGB0
      	movf	REGB2,w
      	subwf	REGC2,w
	banksel	REGA0
      	skpz
      	goto	dtstgt
	banksel	REGB0
      	movf	REGB1,w
      	subwf	REGC1,w
	banksel	REGA0
      	skpz
      	goto	rtstgt
	banksel	REGB0
      	movf	REGB0,w
      	subwf	REGC0,w
	banksel	REGA0
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:
	banksel	REGC0
	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:
	banksel	REGA0
	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


      ;UTILITY ROUTINES


      ;Add REGB to REGA (Unsigned)
      ;Used by add, multiply,

addba:
	banksel	REGB0
	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
	banksel	REGA0
      	return


      ;Move REGA to REGC
      ;Used by multiply, sqrt

movac:
	banksel	REGC0
	movf	REGA0,w
      	movwf	REGC0
      	movf	REGA1,w
      	movwf	REGC1
      	movf	REGA2,w
      	movwf	REGC2
      	movf	REGA3,w
      	movwf	REGC3
	banksel	REGA0
      	return


      ;Clear REGB and REGA
      ;Used by sqrt

clrba:
	banksel	REGB0
	clrf	REGB0
      	clrf	REGB1
      	clrf	REGB2
      	clrf	REGB3

      ;Clear REGA
      ;Used by multiply, sqrt

clra:
	banksel	REGA0
	clrf	REGA0
      	clrf	REGA1
      	clrf	REGA2
      	clrf	REGA3
      	return


      ;Check sign of REGB and convert negative to positive
      ;Used by multiply, divide

absb:
	banksel	REGB0
	rlf	REGB3,w
	banksel	REGA0
      	skpc
      	return			;Positive

      ;Negate REGB
      ;Used by absb, subtract, multiply, divide

negateb:
	banksel	REGB0
	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:
 	banksel	REGA0
	incf	MTEMP,f		;flip sign flag
	banksel	REGB0
      	addwf	REGB3,w		;Return carry set if -2147483648
	banksel	REGA0
      	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:
	banksel	REGC0
	rlf	REGC0,f
      	rlf	REGC1,f
      	rlf	REGC2,f
      	rlf	REGC3,f
	banksel	REGA0
      	return



;******************************************
	end

