;-------------------------------------------------------------------------;
;
;		Project:	dds synthetizer with lcd 2x16 char and free USART port
;    	Filename:	adlcd4.asm
;    	Date:		2012/03/04                             
;    	Author:		Giuseppe Aquilani
;    	Web:		http://www.ik0jre.net/
;       email:		ik0jre "at" ik0jre.net - giuseppe.aquilani "at" virgilio.it
;
;		History:	0.0 2012/03/04 start develop 
;					0.1	2012/08/10	add middle button ad fix a frx bug
;		Description:
;		This software is written for PIC16F628 but can modify for other PIC 
;		with small changes.
;-----------------------------------------------------------------------;
;		Processor:	16F628A
;		Pin used:	
;			*** LCD display in 4 bit mode ***
;			RA0-RA3	:	D4-D7 LCD Lines
;			RA6 RA7 :	RS E - LCD Lines (R/W to GND, write everytime)
;			RB6-RB7 :	input for switch control
;
;		Schema:	 http://www.ik0jre.net web site 
;		NOTE:
;-------------------------------------------------------------------------;
;		COPYRIGHT
;		This software is free. You can freely use at only condition 
;		write the author's name IK0JRE or/and Giuseppe Aquilani
;		on source code and schema description
;-------------------------------------------------------------------------;
;#define PIC16F628 1
;-------------------------------------------------------------------------;
;		PROGRAM 
;-------------------------------------------------------------------------;
       	PROCESSOR       16F628A
        INCLUDE         <P16F628A.INC>
		; __CONFIG		_CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC&_BODEN_OFF&_LVP_OFF
		__CONFIG		0x3F18	; osc int I/O RA6,RA7, PUT on,MCRLE disable
		RADIX 			DEC
        ERRORLEVEL      -302	; Register in operand not in bank 0.
		ERRORLEVEL 		-207 	; Found label after column 1.
;-------------------------------------------------------------------------;
;		Definitions and constants
;-------------------------------------------------------------------------;

;-------------------------------------------------------------------------;
;		LCD Data and port used from project
;-------------------------------------------------------------------------;	
;	LCD data ports D4 - D7 == RA0-RA3 
;	LCD	CONTROL	EN = RA7, RS = RA6, R/W = GND
;	CONTROL BUTTON use:
;	RB6 for menu exit
;	RB7	for navigate and select/change value
#define LCDPORT 	PORTA
#define BTNPORT		PORTB
#define LCDTRIS 	TRISA
#define BTNTRIS		TRISB


#define	LCD_RS     LCDPORT,0x06	; Register Select
#define	LCD_EN     LCDPORT,0x07	; Enable Output / "CLK"
#define MAXLCDCHAR	8
;-------------------------------------------------------------------------;
;		General defines
;	three buttons are used
;	btnm:	for function
;	btn1:	up, slow,fast, (save)
;	btn2:	doen, slow,fast, (change up/down mode)
;-------------------------------------------------------------------------;
#define BTINPUTM		LCDPORT,4		; 0 down 1 up
#define BTINPUT1		BTNPORT,6		; 0 down 1 up
#define BTINPUT2		BTNPORT,7		; 0 down 1 up
#define QSTIME			250 ;50; 100 ;250		; almost Quarter of second in mS at 4 MHz
#define BTNDLY			50
#define AD9850TWLEN	 5 ; how many tuning words used

#define MAXNSTEP	0x08 ; how 	many steps need for frequency set
;-------------------------------------------------------------------------;
; 	for standard number use a table at TAB_DISP_A table
;	but for special character status use a defines
;	NOTE: the following defines are used for status
;-------------------------------------------------------------------------;
; 	My file registers
; pic16f84  start from bank0 0x0c 
; pic16f628 start from bank0 0x20
;#ifdef PIC16F628 
	#define RAMADDR 0x20
;#else
;	#define RAMADDR 0x0C
;#endif
;-------------------------------------------------------------------------;
	cblock RAMADDR
DIGFREQ:		8	; in nibble for digit use 2 digits for MHz, 6 digits for Hz, 1 digit for dot
AD9850TWORDS:	AD9850TWLEN	;ad9850 tuning words, see ad9850 section
LSMENUVAR:		1 	; can reused it in every function for local loop
VREGX:			1
VAPPSTART:		1	; global status	- start address for for index memory
;RegToRead:		3	; var set next read from eeprom
LoopCount:		1	; byte for local loopcount
DELAYMSC:		3	; 0 = 255, 1 = 4 (4x255 = 1mS), 2= nxmS
LCDBUFF:		1	; temp var for trasfer data to LCD
LCDTEMP:		1	; temp var for swap nibble in lcd command
TLCDReg:		2	; var for settings line and col.
VStack:			4	; Virtual stack or temporary local var
RegIDX:			1	; register index for a FSR use
IrqCount:		1	; irq var inc every interrupt if enable 0x40
RW_TEMP: 		1	; register for WREG backup on IRQ routine
RSTATUS_TEMP:	1	; register for FREG backup on IRQ routine
INTCON_TEMP:	1	;  register for INTCON backup on write/read eeprom routine
;LCDLINESBUFF:	MAXLCDCHAR	;  buffer for line to print 
TWCOUNT:		1	;used for loop wordcount
DIGVAL:			1	; temp var for dig cal in tw
NSTEP:			1	; used for identify step increment
MNSTEP:			1	; temporary vars in incfreq routine
NSPOS:			1	; var for frq step indicator LCD position
LCDIDX:			1	;  
TBTNCNT:		1	;  
	endc 
;	todo at 25032012
;	fill line - fill space char from pos to end line
;-------------------------------------------------------------------------;
; 				Macro 
;-------------------------------------------------------------------------;
bank0	macro		
		bcf	STATUS,RP0 
		bcf STATUS,RP1;bank 0 select
	endm

bank1	macro		
		bsf	STATUS,RP0 ;bank 1 select
		bcf STATUS,RP1
	endm
;-------------------------------------------------------------------------;
; 				EEPROM DATA
;-------------------------------------------------------------------------;
	ORG H'2100'
;		nmem 			  lastm |--------frq--------|  
;								Hz 	-------------  MHz
;							    D0D1  D2D3  D4D5  D6D7
;	DE  0x00, 0x00, 0x00, 0x00, 0x80, 0x91, 0x00, 0x00
	DE  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ;10.000 MHz
;	DE  0x00, 0x3E, 0x38, 0xFE, 0x05, 0x10   		
#define LASTFRQM 0x04		;addr of last frq settings
;-------------------------------------------------------------------------;
	org 	0x00		;start routine on reset			
	goto 	InitMain
	org		0x04		;reset vector
	goto	MAIN ;IrqVect

;org 0x50
;-------------------------------------------------------------------------;
InitMain
	call SettingsPorts	
	bank0
;register to read
	clrf	IrqCount
	call 	LCD_INIT
	call	PrintIntro

	clrf	NSTEP
;	movlw	MAXNSTEP
;	movwf	NSTEP
;	movlw 	0x03
;	movwf 	VBtn1C+0	;count down for sync button down in MonitorRegs
;	movwf 	VBtn1C+1
;	movlw	1
;	movwf	LCDLINESBUFF+0

;	movlw	LCDLINESBUFF+0
;	movwf	FSR
;	movlw 	MAXLCDCHAR
;	addwf	FSR,F
;	movwf	LSMENUVAR	;for decrement loop
;	decf	FSR,F 		;fsr points to lcdbuff+7
	

	clrf	DIGFREQ+0
	clrf	DIGFREQ+1
	clrf	DIGFREQ+2
	clrf	DIGFREQ+3
	clrf	DIGFREQ+4
	clrf	DIGFREQ+5
	clrf	DIGFREQ+6
	clrf	DIGFREQ+7
	
	;movlw	0x01
	;movwf	DIGFREQ+7


	clrf 	VStack+0
	clrf 	VStack+1
	clrf	RegIDX

	clrf	TBTNCNT	;var for deal middle button

	call	ReadEData
;;;;;;;;;;
	call	ADC9850BuffClear
	call 	DelayHS
;;;;;;;;;;
	call	AD9850_WR_Serial
MAIN
	bank0 
 	;test button
	btfss	BTINPUTM	;skip si up
	call	BtnMDown
	btfss	BTINPUT1	;skip si up
	call	Btn1Down
	btfss	BTINPUT2	;skip si up
	call 	Btn2Down
	call	PrintStatus
	call	PrintFrq
	NOP
	NOP
	NOP
;	NOP
;	NOP

	goto 	MAIN			;start main loop again
;-------------------------------------------------------------------------;
;	Interrupt routine
;-------------------------------------------------------------------------;
IrqVect
	bank0
	movwf	RW_TEMP			; saving Wreg
	swapf	STATUS,W 		; saving STATUS REG in 2 steps
	movwf	RSTATUS_TEMP 	; lower and hi nibble are swapped 

	incf	IrqCount,F
	movlw	0xF8
	andwf	INTCON,F

	swapf 	RSTATUS_TEMP,W
	movwf	STATUS			;restore status reg
	swapf	RW_TEMP,F
	swapf	RW_TEMP,W		;restore wreg
	retfie
;-------------------------------------------------------------------------;
; LCD display numbers table
;-------------------------------------------------------------------------;
TAB_DISP_LCD
	andlw 0x0F			; mask value over 0x11 	
	addwf	PCL,F		; increment PCL register
 	retlw	'0' 	;0
	retlw	'1' 	;1				
	retlw 	'2' 	;2	
	retlw	'3' 	;3	
	retlw	'4' 	;4	
	retlw	'5' 	;5	
	retlw	'6' 	;6	
	retlw	'7' 	;7
	retlw	'8' 	;8
	retlw	'9' 	;9
	retlw	'A' 	;10
	retlw	'B' 	;11
	retlw	'C' 	;12
	retlw	'D' 	;13
	retlw	'E' 	;14
	retlw	'F' 	;15
;-------------------------------------------------------------------------;
; LCD position for step indicator
;-------------------------------------------------------------------------;
TAB_BIT_STAT
	andlw	0x07
	addwf	PCL,F	; increment PCL register
 	retlw	0x0F 	;0
	retlw	0x0E	;1				
	retlw 	0x0D	;2	
	retlw	0x0C 	;3	
	retlw	0x0B 	;4	
	retlw	0x0A 	;5	
	retlw	0x08 	;6
	retlw	0x07 	;7
;-------------------------------------------------------------------------;
; PrintFrq
; read ascii value from LFREQ vars and print these in second lcd line
;-------------------------------------------------------------------------;
PrintFrq
;;;debug
;;   call PrintTW

;;   call DelayS
;;;;;;;
; frq lines should be like:
; "MHz    10.000000 "
	movlw 	0x10
	call 	SetLCDPos 
	movlw 	'M'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw 	' '
	call 	LCDdata
	movlw 	' '
	call 	LCDdata
	movlw 	' '
	call 	LCDdata
	movlw 	' '
	call 	LCDdata

	movf	DIGFREQ+7,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+6,W
	call	TAB_DISP_LCD
	call 	LCDdata
	
	movlw 	'.'
	call 	LCDdata

	movf	DIGFREQ+5,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+4,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+3,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+2,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+1,W
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	DIGFREQ+0,W
	call	TAB_DISP_LCD
	call 	LCDdata

;debug 
; call DelayS
; call DelayS
; call DelayS
;;;;;
	return
;-------------------------------------------------------------------------;
; PrintStatus
; print in first LCD line current step set and other temporary info
;-------------------------------------------------------------------------;
PrintStatus
; Status line should be like:
; "Step=10MHz      "

	movlw 	0x00
	call 	SetLCDPos 
;	movlw 	'S'
;	call 	LCDdata
;	movlw 	'='
;	call 	LCDdata


	movf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P1Hz

	movlw	0x01
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P10Hz

	movlw	0x02
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P100Hz

	movlw	0x03
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P1KHz

	movlw	0x04
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P10KHz

	movlw	0x05
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P100KHz

	movlw	0x06
	subwf	NSTEP,W
	btfsc	STATUS,Z
	goto 	P1MHz

P10MHz
	movlw 	'1'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'M'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0B
	goto	PCommon
P1MHz
	movlw 	'1'
	call 	LCDdata
	movlw 	'M'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0C
	goto	PCommon
P100KHz
	movlw 	'1'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'K'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0A
	goto	PCommon
P10KHz
	movlw 	'1'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'K'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0B
	goto	PCommon
P1KHz
	movlw 	'1'
	call 	LCDdata
	movlw 	'K'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0C
	goto	PCommon
P100Hz
	movlw 	'1'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0B
	goto	PCommon
P10Hz
	movlw 	'1'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0C
	goto	PCommon
P1Hz
	movlw 	'1'
	call 	LCDdata
	movlw 	'H'
	call 	LCDdata
	movlw 	'z'
	call 	LCDdata
	movlw	0x0D

PCommon		;W reg have got how many chars remains
	movwf	LoopCount
	movf	NSTEP,W
	call	TAB_BIT_STAT
	movwf	NSPOS
	call 	SetLCDPos
	movlw	0x00	;print custom char create with CustomCH routine
	call 	LCDdata

	movlw	0x0F
	movwf	LCDIDX

PCLoop		;print spaces loop
	movf	NSPOS,W
	subwf	LCDIDX,W
	btfsc	STATUS,Z
	goto 	PSkip


	movf	LCDIDX,W
	call 	SetLCDPos
	movlw	' '
	call 	LCDdata

PSkip
    decf	LCDIDX,F
	decfsz	LoopCount
	goto	PCLoop

	return
;-------------------------------------------------------------------------;
;	CustomCH
;	Create a custom char in LCD cgram 0x00 address 
;-------------------------------------------------------------------------;
CustomCH
	movlw	0x40	;set cgram address for first custom char
	call	LCDCmd
	movlw	0x0A
	call 	LCDdata
	movlw	0x0A
	call 	LCDdata
	movlw	0x0A
	call 	LCDdata
	movlw	0x0A
	call 	LCDdata
	movlw	0x1B
	call 	LCDdata
	movlw	0x0A
	call 	LCDdata
	movlw	0x04
	call 	LCDdata


;	movlw	0x48
;	call	LCDCmd
;
;	movlw	0x04
;	call 	LCDdata
;	movlw	0x0E
;	call 	LCDdata
;	movlw	0x15
;	call 	LCDdata
;	movlw	0x04
;	call 	LCDdata
;	movlw	0x04
;	call 	LCDdata
;	movlw	0x04
;	call 	LCDdata
;	movlw	0x04
;	call 	LCDdata

	return
;-------------------------------------------------------------------------;
; PrintTW
; read ascii value from LFREQ vars and print these in second lcd line
; AD9850TWORDS+0,F
; only for debug
;-------------------------------------------------------------------------;
PrintTW
	movlw 	0x10
	call 	SetLCDPos 
	movlw 	'T'
	call 	LCDdata
	movlw 	'W'
	call 	LCDdata
	movlw 	' '
	call 	LCDdata
	movlw 	'='
	call 	LCDdata

	movlw 	' '
	call 	LCDdata

	swapf	AD9850TWORDS+3,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	AD9850TWORDS+3,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata
	
	movlw 	' '
	call 	LCDdata

	swapf	AD9850TWORDS+2,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	AD9850TWORDS+2,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	movlw 	' '
	call 	LCDdata

	swapf	AD9850TWORDS+1,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	AD9850TWORDS+1,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata
	
	movlw 	' '
	call 	LCDdata

	swapf	AD9850TWORDS+0,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	movf	AD9850TWORDS+0,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata

	return
;-------------------------------------------------------------------------;
; Settings Ports
;-------------------------------------------------------------------------;
SettingsPorts
    ;general setting
	bank0
	movlw 	0x07
	movwf 	CMCON			;disable comparator
	movlw 	0
	movwf 	LCDPORT
	movwf 	BTNPORT
	bank1
	movlw 	0
	movwf 	LCDTRIS			; clear TRISA register
	movwf 	BTNTRIS			; clear TRISB register
  	clrf	OPTION_REG	
  	bsf 	OPTION_REG,7 	; enable pull'up

	bsf 	LCDTRIS,4		;enable RB4 button
	bsf 	BTNTRIS,6		;enable RA6 button
	bsf 	BTNTRIS,7		;enable RA7 button

	bank1
	movlw 	0x08
	iorwf	PCON,F			;sure intosc is set to 4MHz

	bank0
	call	DelayHS

	call	AD9850_Init
	call	DelayHS

	call	AD9850_Reset_Serial
	call	DelayHS

	return
;-------------------------------------------------------------------------;
; 	
;-------------------------------------------------------------------------;
ADC9850BuffClear
	bank0
	movlw	AD9850TWORDS+0
	movwf	FSR
	movlw 	AD9850TWLEN
	addwf	FSR,F
	movwf	LSMENUVAR	;for decrement loop
	decf	FSR,F 		;fsr points to lcdbuff+7

adbuffclear
	clrf	INDF
	decf	FSR,F
	decfsz 	LSMENUVAR,F
	goto 	adbuffclear
;	clear end
	call	DelayHS
	call	DelayHS

;	call	AD9850_WR_Serial
	return
;-------------------------------------------------------------------------;
; 	DecFreq1
;	need : nothing
;  	verify max freq 45 mhz
; 	call CalcADTW for calc tuning words
;	call AD9850_WR_Serial for update frequency
;-------------------------------------------------------------------------;
DecFreq1
	movlw	DIGFREQ+0
	addwf	NSTEP,W
	movwf	FSR
decloop1
	movlw	0x07		;is 10Mhz dig ?
	subwf	NSTEP,W		
	btfss	STATUS,Z	;verify min val in first digit
    goto	stdec1

	movf	INDF,W		;user has set 0 x 10MHz ?
	btfss	STATUS,Z
	goto	stdec1		; no dec 
	movlw	0x04		; yes set 4
	movwf	INDF		
	goto	updexit1 		

stdec1
	movf	INDF,W
	btfss	STATUS,Z 		;is min dig count ?
	goto	decdig1			; no dec normally
	movlw	0x09			; yes set max value
	movwf	INDF			
	goto	updexit1

decdig1
	decf	INDF,F			; dec digit

	goto	updexit1
;-------------------------------------------------------------------------;
; 	IncFreq
;	need : nothing
;  	verify max freq 45 mhz
; 	call CalcADTW for calc tuning words
;	call AD9850_WR_Serial for update frequency
;-------------------------------------------------------------------------;
IncFreq1
	movlw	DIGFREQ+0
	addwf	NSTEP,W
	movwf	FSR

incloop1
	movlw	0x07		;is 10Mhz dig ?
	subwf	NSTEP,W		
	btfss	STATUS,Z	;verify max val in first digit
    goto	stdinc1

	movlw	0x04		;max freq 49.999999
	subwf	INDF,W		;user has set 4 x 10MHz ?
	btfss	STATUS,Z
	goto	stdinc1		; no inc 
	clrf	INDF		; yes, clear INDF and exit
	goto	updexit1 		

stdinc1
	movlw	0x09
	subwf	INDF,W
	btfss	STATUS,Z 		;is max dig count ?
	goto	incdig
	clrf	INDF			;here  must inc nstep+1 or other step
	goto	updexit1
incdig1
	incf	INDF,F
updexit1
	call	CalcADTW			;settings tuning words vars
	call	AD9850_WR_Serial	;send tuning words to AD9850
	return
;-------------------------------------------------------------------------;
; 	DecFreq
;	need : nothing
;  	verify max freq 45 mhz
; 	call CalcADTW for calc tuning words
;	call AD9850_WR_Serial for update frequency
;-------------------------------------------------------------------------;
DecFreq
	movf	NSTEP,W
	movwf 	MNSTEP

decmainloop
	movlw	DIGFREQ+0
	addwf	MNSTEP,W
	movwf	FSR

decloop
	movlw	0x07		;is 10Mhz dig ?
	subwf	MNSTEP,W		
	btfss	STATUS,Z	;verify min val in first digit
    goto	stdec

	movf	INDF,W		;user has set 0 x 10MHz ?
	btfss	STATUS,Z
	goto	stdec		; no dec 
	movlw	0x04		; yes set 4
	movwf	INDF		
	goto	updexit 		

stdec
	movf	INDF,W
	btfss	STATUS,Z 		;is min dig count ?
	goto	decdig			; no dec normally

	movlw	0x09			; yes set max value
	movwf	INDF			
    incf 	MNSTEP,F
 	goto 	decmainloop 
	;goto	updexit

decdig
	decf	INDF,F			; dec digit

	goto	updexit
;-------------------------------------------------------------------------;
; 	IncFreq
;	need : nothing
;  	verify max freq 45 mhz
; 	call CalcADTW for calc tuning words
;	call AD9850_WR_Serial for update frequency
;-------------------------------------------------------------------------;
IncFreq
	movf	NSTEP,W
	movwf 	MNSTEP

incmainloop
	movlw	DIGFREQ+0
	addwf	MNSTEP,W ;NSTEP,W
	movwf	FSR

incloop
	movlw	0x07		;is 10Mhz dig ?
	subwf	MNSTEP,W		
	btfss	STATUS,Z	;verify max val in first digit
    goto	stdinc

	movlw	0x04		;max freq 49.999999
	subwf	INDF,W		;user has set 4 x 10MHz ?
	btfss	STATUS,Z
	goto	stdinc		; no inc 
	clrf	INDF		; yes, clear INDF and exit
	goto	updexit 		

stdinc
	movlw	0x09
	subwf	INDF,W
	btfss	STATUS,Z 		;is max dig count ?
	goto	incdig
    ;is max digit inc next digit
	clrf	INDF			;here  must inc nstep+1 or other step
	incf	MNSTEP,F
	goto 	incmainloop
;	goto	updexit
incdig
	incf	INDF,F


updexit
	call	CalcADTW			;settings tuning words vars
	call	AD9850_WR_Serial	;send tuning words to AD9850
	return
;-------------------------------------------------------------------------;
; 	BtnMDown
;	need : nothing
;-------------------------------------------------------------------------;
BtnMDown


;	;anti bounce push time under BTNDLY are ignored
	incf	TBTNCNT,F

;	call 	DelayQS

	btfss	BTINPUT1
	goto 	Btn1F	

	btfss	BTINPUT2
	goto 	Btn2F	

;	call 	DelayQS
	btfsc	BTINPUTM
	return	

Longmpress
	movlw	255
    subwf	TBTNCNT,W
	btfss	STATUS,Z
	return

BtnMMenu

	call	PrintMenu
	clrf	TBTNCNT
	return

Btn1F
	clrf	TBTNCNT
	call	WriteEData
	call 	PrintSave
	btfss	BTINPUT1
	goto 	$-1 
	return

Btn2F
	clrf	TBTNCNT
	incf	NSTEP,F
	movlw	MAXNSTEP			;max nstep index
	subwf	NSTEP,W
	btfsc	STATUS,Z		;if max nstep index
	clrf	NSTEP			;nstep start again from 0

	call	PrintStatus

	call 	DelayQS
 	btfss	BTINPUT2
	goto 	Btn2F		

	return

;-------------------------------------------------------------------------;
; 	Btn1Down
;	need : nothing
;-------------------------------------------------------------------------;
Btn1Down
	;anti bounce push time under BTNDLY are ignored
;;	movlw	BTNDLY
;;	call 	DelayMS
;	btfsc	BTINPUT1
;	return

;;	movlw	BTNDLY
;;	call 	DelayMS
;	btfsc	BTINPUT1
;	goto 	Slowb1press	

;	call 	DelayQS
;	btfsc	BTINPUT1
;	goto 	Slowb1press	

;Long1press
;	call 	DelayHS
;	btfsc	BTINPUT1
;	goto 	Slowb1press	
;	call 	DelayHS
;	btfsc	BTINPUT1
;	goto 	Slowb1press	

;;;;start long push routine
;;	call	PrintNstep
;;	call	PrintStatus
;;	call	PrintTW
;	call	WriteEData
;	call 	PrintSave
;	movlw	BTNDLY
;	call 	DelayMS
;	btfss	BTINPUT1
;	goto 	$-1 

;	return
;Slowb1press	
	btfss	BTINPUTM
	goto 	BtnMDown

	call 	IncFreq			
	return

;-------------------------------------------------------------------------;
; 	Btn2Down
;	need : nothing
;-------------------------------------------------------------------------;
Btn2Down
	;anti bounce push time under BTNDLY are ignored
;;	movlw	BTNDLY
;;	call 	DelayMS
;	btfsc	BTINPUT2
;	return

;;	movlw	BTNDLY
;;	call 	DelayMS
;	btfsc	BTINPUT2
;	goto 	Slowb2press	

;	call 	DelayQS
;	btfsc	BTINPUT2
;	goto 	Slowb2press	

; da qui in poi c'e' la pressione lunga
;Long2press

;	call 	DelayHS
;	btfsc	BTINPUT2
;	goto 	Slowb2press	
;	call 	DelayHS
;	btfsc	BTINPUT2
;	goto 	Slowb2press	

;	;;;start long push routine
;	incf	NSTEP,F
;	movlw	MAXNSTEP			;max nstep index
;	subwf	NSTEP,W
;	btfsc	STATUS,Z		;if max nstep index
;	clrf	NSTEP			;nstep start again from 0

;	call	PrintStatus
;	call 	DelayHS
;	btfss	BTINPUT2
;	goto 	Long2press

;	return
Slowb2press	
	btfss	BTINPUTM
	goto 	BtnMDown


	call 	DecFreq	    
	return
;-------------------------------------------------------------------------;
; 	PrintNumX
;	need :
;	VStack+0 = cursor position to print
;	VStack+1 = value number to print
;-------------------------------------------------------------------------;
PrintNumX
	movf	VStack+0,W		; start position for display
	call 	SetLCDPos 
	swapf 	VStack+1,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata
	movf 	VStack+1,W
	andlw	0x0F
	call	TAB_DISP_LCD
	call 	LCDdata
	movlw 	0x15			; start position for display
	call 	SetLCDPos 	
	return
;-------------------------------------------------------------------------;
; 	PrintRegX
;	need :
;	VStack+0 = cursor start position
;	VStack+1 = 8 bit register's address (pointer) to read an print
;-------------------------------------------------------------------------;
PrintRegX
	bank0
	movf 	VStack+1,W	;register address
	movwf	FSR
	movf	INDF,W
	movwf	VREGX
	movf	VStack+0,W	
	call 	SetLCDPos 
	movlw	0x08
	movwf	LSMENUVAR
prxloop
  	btfsc 	VREGX,7
	goto  	$+3
	movlw 	'0'
	goto  	$+2 ; call lcddata
	movlw 	'1'
	call 	LCDdata
    rlf 	VREGX,F
	decfsz 	LSMENUVAR,F
	goto 	prxloop
	return
;-------------------------------------------------------------------------;
; PrintMenu
;-------------------------------------------------------------------------;
PrintMenu
	call 	LCDClear
	movlw 	0x06
	call 	SetLCDPos 
	movlw 	'M'
	call 	LCDdata
	movlw 	'e'
	call 	LCDdata
	movlw 	'n'
	call 	LCDdata
	movlw 	'u'
	call 	LCDdata
	call 	DelayS
	call 	LCDClear
	return
;-------------------------------------------------------------------------;
; PrintSave
;-------------------------------------------------------------------------;
PrintSave
	call 	LCDClear
	movlw 	0x06
	call 	SetLCDPos 
	movlw 	'S'
	call 	LCDdata
	movlw 	'a'
	call 	LCDdata
	movlw 	'v'
	call 	LCDdata
	movlw 	'e'
	call 	LCDdata
	call 	DelayS
	call 	LCDClear
	return
;-------------------------------------------------------------------------;
; PrintVars	(used only in debug manual breakpoint)
;	need :
;	VStack+0 = Pointer to Var 1
;	VStack+1 = Pointer to Var 2
;	use VStack+3 as bck local vars for call PrintRegX
;-------------------------------------------------------------------------;
PrintVars
	movf 	VStack+0,W	;bck for call PrintRegX
	movwf	VStack+3	;unused from PrintRegX

	call 	LCDClear
;print first line and reg
	movlw 	0
	call 	SetLCDPos 
	movlw 	'V'
	call 	LCDdata
	movlw 	'0'
	call 	LCDdata
	movlw 	'='
	call 	LCDdata
	movlw 	' '
	call 	LCDdata

	movf 	VStack+0,W
	movwf	VStack+1
	movlw	0x03		;lcd position
	movwf 	VStack+0
	call	PrintRegX
;print second line and reg
	movlw 0x10
	call SetLCDPos 
	movlw 'V'
	call LCDdata
	movlw '1'
	call LCDdata
	movlw '='
	call LCDdata
	movlw ' '
	call LCDdata

	movlw 	0x13
	movwf	VStack+0
	movf	VStack+3,W
	movwf	VStack+1	
	call	PrintRegX

    call DelayS

	btfsc BTINPUT1	 
	goto $-1

	call 	LCDClear
	return
;-------------------------------------------------------------------------;
; Save Data in eeprom
; read global variables and stores in eeprom  
; DIGFREQ
; LASTFRQM	literal address
; VStack+3 as temporary var for counting loop
;-------------------------------------------------------------------------;
WriteEData
; *** right sequence should be: ***;
; backup interrupt status		
; disable interrupt
; restore interrupt status
; difference in eedata ed in eeadr pic16f84 bank0 for pic16f628 in bank1

	swapf 	INTCON,W
	movwf	INTCON_TEMP

	bcf 	INTCON,GIE		;disable interrupt for write data eeprom
	btfsc 	INTCON,GIE
	goto 	$-2				; and wait while interrupt is enable

	bank0
	clrf	VStack+0	
	clrf	VStack+3

	movlw	0x04
	movwf	VStack+3		; loop for total frequency vars

	movlw	DIGFREQ+0		;first array vars address to read
	movwf	FSR				;now memory indf to read

	movlw	LASTFRQM		;start eeprom memory address to write
	bank1
	movwf 	EEADR			;address to read/write VStack+3
wedloop
	bank0
	movf	INDF,W			;DIGFREQ+X address
	movwf	VStack+0		;because digita are 8 and eeprom address are 4
	swapf	VStack+0,F		;need to combine 2 vars in 1 byte
							;first var of pair are HIGH nibble
	incf	FSR,F			;ready to read next var
	
	movf	INDF,W			;DIGFREQ+X+1 address
	addwf	VStack+0,F		;second var of pair are LOW nibble

	movf	VStack+0,W		;now can write the pair to eeprom address 

	bank1
	movwf 	EEDATA 			; trasfer data to write
	bsf 	EECON1,WREN		; enable write
	;start write sequence
	movlw	0x55
	movwf 	EECON2
	movlw	0xaa
	movwf	EECON2
	bsf		EECON1,WR 	;write
	nop
	call 	DelayQS

	bank0
	decfsz	VStack+3,F		;wrote all 4 bytes ?
	goto 	$+2				;no loop again
	goto 	WEEnd			;yes end

	bank0
	incf	FSR,F
	bank1
	incf	EEADR,F
	goto	wedloop	

WEEnd
	swapf 	INTCON_TEMP,W 
	movwf	INTCON



;TODO verify data next single by write 
	return
;-------------------------------------------------------------------------;
; ReadEData in eeprom
; read eeprom and stores in global variables
; VAPPSTART,VStack+3,RegToRead 0-2,VSub+0,VSub+1,VAddSubOp
; need vars are in the same memory block from VAPPSTART to VAddSubOp
;-------------------------------------------------------------------------;
ReadEData
;	clrf	VStack+3	; loop counter and delta address pointer
   ; load data from eeprom

	bank0
	clrf	VStack+0	
	clrf	VStack+3

	movlw	0x04
	movwf	VStack+3		; loop for total frequency vars

	movlw	DIGFREQ+0		;first array vars address to read
	movwf	FSR				;now memory indf to read

	movlw	LASTFRQM		;start eeprom memory address to write
	bank1
	movwf 	EEADR			;address to read/write VStack+3
redloop
;;;;;;;;;
	bank1
 	bsf 	EECON1,RD	; eeprom read
	movf 	EEDATA,W	; W = EEDATA
;;;;;;;;;;;
	bank0
	movwf	VStack+0		;because digita are 8 and eeprom address are 4
	andlw	0xF0
	movwf	INDF			;DIGFREQ+X address
	swapf	INDF,F

	incf	FSR,F			;ready to read next var

	movf	VStack+0,W		;need to combine 2 vars in 1 byte
	andlw	0x0F						;first var of pair are HIGH nibble
	movwf	INDF			;DIGFREQ+X+1 address

;;;;;;;;;;;
	nop
	call 	DelayQS

	bank0
	decfsz	VStack+3,F		;wrote all 4 bytes ?
	goto 	$+2				;no loop again
	return		;goto 	REEnd			;yes end

	bank0
	incf	FSR,F
	bank1
	incf	EEADR,F
	goto	redloop	

;REEnd

	return
;-------------------------------------------------------------------------;
; Late's function for 4MHz about 1mS x W
; late are in TCy time (at 4MHz TCy = 1uS) = (((4 x 255) + 1) x (W + 1))+4
;-------------------------------------------------------------------------;
DelayMS			
;		movwf   DELAYMSC+2		;1
;		movlw	0x04
		movwf   DELAYMSC+1		;1
        clrf    DELAYMSC+0		;1
DelayMSLoop
		nop
		nop						;1		
		decfsz  DELAYMSC+0,F	;1 +	
		goto    DelayMSLoop		;2
		decfsz  DELAYMSC+1,F	;1 + 2	
		goto    DelayMSLoop		;2
;		decfsz  DELAYMSC+2,F	;1 + 2	
;		goto    DelayMSLoop		;2


		return					;2
;-------------------------------------------------------------------------;
; Late 1 Second function (about  at 4 MHz)
;-------------------------------------------------------------------------;
DelayS
		movlw QSTIME
		call DelayMS	
		movlw QSTIME
		call DelayMS	
DelayHS
		movlw QSTIME
		call DelayMS	
DelayQS
		movlw QSTIME
		call DelayMS	
        return
;-------------------------------------------------------------------------;
;	PrintIntro
;-------------------------------------------------------------------------;
PrintIntro
	movlw 	0
	call 	SetLCDPos 

	movlw 'I'
	call LCDdata
	movlw 'K'
	call LCDdata
	movlw '0'
	call LCDdata
	movlw 'J'
	call LCDdata
	movlw 'R'
	call LCDdata
	movlw 'E'
	call LCDdata

	call 	DelayHS	

	movlw 	0x10	;line 1 c 1
	call 	SetLCDPos 

	movlw 'W'
	call LCDdata
	movlw 'W'
	call LCDdata
	movlw 'W'
	call LCDdata
	movlw '.'
	call LCDdata
	movlw 'I'
	call LCDdata
	movlw 'K'
	call LCDdata
	movlw '0'
	call LCDdata
	movlw 'J'
	call LCDdata
	movlw 'R'
	call LCDdata
	movlw 'E'
	call LCDdata
	movlw '.'
	call LCDdata
	movlw 'N'
	call LCDdata
	movlw 'E'
	call LCDdata
	movlw 'T'
	call LCDdata
; print waiting effect
	movlw 	0x06	;line 0 ch 8
	call 	SetLCDPos 
	movlw 	0x0A
	movwf 	LSMENUVAR
loadcycle
	movlw '.'
	call 	LCDdata

	call 	DelayQS		
	decfsz 	LSMENUVAR,F
	goto 	loadcycle
	call 	DelayS	
	return
;-------------------------------------------------------------------------;
;	start LCD routine block
;-------------------------------------------------------------------------;
LCD_INIT
	call 	DelayHS	
	bank0
	bcf		LCD_EN			; clear LCD clock line
;	bcf		LCD_RW			; set write direction
	bcf		LCD_RS			; clear command/data line

 	movlw	11110000b	
	andwf	LCDPORT,f			; clear only data lines

	movlw	0x02   
	call 	DelayMS
	;call 	DelayQS
	; LCD INITIALIZATION 

	movlw	00000011b			; send 3 on [DB7:DB4] and RS = 0
	call	LCDSend 
;;	call  	LCDSync		
	call  	LCDSync		
	call  	LCDSync		

	movlw	0x02   
	call 	DelayMS
	;call 	DelayQS

	; enable 4 bit mode
	movlw	00000010b			; send 2 [DB7:DB4]
	call 	LCDSend
;;	call 	LCDSync	

	movlw	0x02   
	call 	DelayMS
;	call 	DelayQS

	; settings display
	movlw 	00101000b		;command 0x28 - 4 bit, 2 lines, 5x7 dots
	call 	LCDCmd
;	movlw 00001100b			;command 0x12 - display on, cursor off, blinking off
;	call 	LCDCmd
	;optional
	movlw 	00000110b		; send 0x06 move cursor right
	call	LCDCmd
	movlw 	00001100b		; send 0x0C turn on display
	call	LCDCmd

	movlw	0x02   
	call 	DelayMS
;	call 	DelayQS

	call 	LCDClear

	movlw	0x02   
	call 	DelayMS

	call	CustomCH 	; create custom chars
;	call 	DelayQS

;	call 	LCDClear
;	return
;-------------------------------------------------------------------------;
;	LCDClear
;-------------------------------------------------------------------------;
LCDClear
	movlw 	0x01 		; clear display
;	call 	LCDCmd
LCDCmd	
	bank0	
	bcf		LCD_RS		; select command registers
	goto	LCDWrite
LCDdata					; transmit data to LCD	
	bsf		LCD_RS		; select data registers
LCDWrite	
;	bcf		LCD_RW
	movwf	LCDTEMP		; save data to var
	swapf	LCDTEMP,W	; swap hi- and lo-nibble, store in w
	call    LCDSend		; send hi-nibble
;;	call	LCDSync
    movf	LCDTEMP,W	; send lo-nibble	
	call 	LCDSend		; include lcdsync
;;	call	LCDSync
	movlw	11110000b   ; reset LCD controls
	andwf	LCDPORT,F	    ; clear data lines only ?
	bcf		LCD_RS		; set data register
	;bcf	LCD_RW		; reset to write direction
	return
;-------------------------------------------------------------------------;
LCDSend
		movwf	LCDBUFF		; save command/data
		movlw	11110000b	; mask for bit needed
		andwf	LCDPORT,F		; clear data lines only
		movf 	LCDBUFF,W
		andlw	00001111b	; mask for bit needed
		iorwf	LCDPORT,f		; put to LCD data lines
;;	return no need 
;-------------------------------------------------------------------------;
LCDSync
		movlw 	0x02
		call 	DelayMS

		bsf     LCD_EN
		nop
		nop
		bcf     LCD_EN
		return
;-------------------------------------------------------------------------;
SetLCDPos       
		bank0
		movwf   TLCDReg+0	; Set cursor position on LCD
		movlw   0x80		; W = D7-D4 row, D3-D0 col
		movwf   TLCDReg+1	; 00h=line 0 - 10h=line 1
        movf    TLCDReg+0,W
        andlw   0x0F
        iorwf   TLCDReg+1,F
        btfsc   TLCDReg+0,4
        bsf     TLCDReg+1,6
        movf    TLCDReg+1,W
        call    LCDCmd
        return
;-------------------------------------------------------------------------;
; end LCD routine BLOCK
;-------------------------------------------------------------------------;
;-------------------------------------------------------------------------;
; AD9850 Section
;-------------------------------------------------------------------------;
#define AD9850PORT	PORTB
#define AD9850TRIS	TRISB
#define RSET     5 ; RB5
#define FQUP     4 ; RB4
#define CLK      0 ; RB0
#define BITDATA  3 ; RB3
;void AD9850_Init();
;void AD9850_Reset_Serial();
;void AD9850_WR_Serial(unsigned char w0,long frequence);
;-------------------------------------------------------------------------;
; 	Init AD9850
;-------------------------------------------------------------------------;
AD9850_Init
	bcf	AD9850PORT,RSET
	bcf	AD9850PORT,FQUP
	bcf	AD9850PORT,CLK
	bcf	AD9850PORT,BITDATA
	return
;-------------------------------------------------------------------------;
; 	Reset AD9850 serial lines
;-------------------------------------------------------------------------;
AD9850_Reset_Serial
	bcf	AD9850PORT,CLK
	bcf	AD9850PORT,FQUP

	bcf	AD9850PORT,RSET
	bsf	AD9850PORT,RSET
	bcf	AD9850PORT,RSET

	bcf	AD9850PORT,CLK
	bsf	AD9850PORT,CLK
	bcf	AD9850PORT,CLK

	bcf	AD9850PORT,FQUP
	bsf	AD9850PORT,FQUP
	bcf	AD9850PORT,FQUP

	return
;-------------------------------------------------------------------------;
;
;-------------------------------------------------------------------------;
FillTW
	clrf	AD9850TWORDS+0
	clrf	AD9850TWORDS+1
	clrf	AD9850TWORDS+2
	clrf	AD9850TWORDS+3
	
	return
;-------------------------------------------------------------------------;
incb1
    movlw   0x01 
	bcf		STATUS,C
	addwf   AD9850TWORDS+1,F
;   	incf	AD9850TWORDS+1,F ; incf don't use carry flag
	btfss	STATUS,C			;is carry bit ? 
	return
incb2
	movlw   0x01 
	bcf		STATUS,C
   	;incf	AD9850TWORDS+2,F ;incf don't use carry flag
	addwf	AD9850TWORDS+2,F
	btfss	STATUS,C			;is carry bit ?
	return
incb3
   	incf	AD9850TWORDS+3,F
	return
;-------------------------------------------------------------------------;
; 	CalcADTW
;	need : DIGFREQ MAXNSTEP valid data
;	print what is in LCDLINESBUFF (LCDMAXCHAR must be long equal than)
;	10 Mhz = 14 7A E1 47+1 	343597383,68
;	 1 Mhz = 02 0C 49 BA	34359738,368
;  100 Khz =    34 6D C5+1	3435973,8368
;	10 Khz =    05 3E 2D	343597,38368
;	 1 Khz =	   86 37+1	34359,738368
;	100 Hz =	   0D 6B+1	3435,9738368
;	 10 Hz =	   01 57+1	343,59738368
;	  1 Hz = 	      22	34,359738368
;-------------------------------------------------------------------------;
CalcADTW
	bank0
;	movlw	MAXNSTEP	
;twmainlooop

;------------------
;	10 Mhz = 14 7A E1 47+1 	343597383,68
;------------------
add10mhz
 	movf	DIGFREQ+7,W
	btfsc	STATUS,Z
	goto	zeroval
	movwf	DIGVAL ;number of add we must be
; first insert	
	movlw	0x48
	movwf	AD9850TWORDS+0
	movlw	0xE1
	movwf	AD9850TWORDS+1
	movlw	0x7A
	movwf	AD9850TWORDS+2
	movlw	0x14
	movwf	AD9850TWORDS+3
multp10m
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add1mhz ;return

	bcf		STATUS,C
	movlw	0x48			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1 ;	goto	incb1
addb1
	bcf		STATUS,C
	movlw	0xE1			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
addb2
	bcf		STATUS,C
	movlw	0x7A		
	addwf	AD9850TWORDS+2,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb3
addb3
	movlw	0x14
	addwf	AD9850TWORDS+3,F
	goto	multp10m

zeroval
	call	FillTW
;------------------
;	 1 Mhz = 02 0C 49 BA	34359738,368
;------------------
;  next digit calc
add1mhz
	movf	DIGFREQ+6,W
	btfsc	STATUS,Z
	goto	add100khz

	movwf	DIGVAL
	incf	DIGVAL,F
multp1m
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add100khz
	
	bcf		STATUS,C
	movlw	0xBA			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add1mb1
	bcf		STATUS,C
	movlw	0x49			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
add1mb2
	bcf		STATUS,C
	movlw	0x0C		
	addwf	AD9850TWORDS+2,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb3
add1mb3
	movlw	0x02
	addwf	AD9850TWORDS+3,F
	goto	multp1m
;------------------
;  100 Khz =    34 6D C5+1	3435973,8368
;------------------
add100khz
	movf	DIGFREQ+5,W
	btfsc	STATUS,Z
	goto	add10khz

	movwf	DIGVAL
	incf	DIGVAL,F
multp100k
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add10khz

	bcf		STATUS,C
	movlw	0xC6			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add100kb1
	bcf		STATUS,C
	movlw	0x6D			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
add100kb2
	bcf		STATUS,C
	movlw	0x34		
	addwf	AD9850TWORDS+2,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb3
	goto	multp100k
;------------------
;	10 Khz =    05 3E 2D	343597,38368
;------------------
add10khz
	movf	DIGFREQ+4,W
	btfsc	STATUS,Z
	goto	add1khz

	movwf	DIGVAL
	incf	DIGVAL,F
multp10k
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add1khz

	bcf		STATUS,C
	movlw	0x2D			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add10kb1
	bcf		STATUS,C
	movlw	0x3E			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
add10kb2
	bcf		STATUS,C
	movlw	0x05		
	addwf	AD9850TWORDS+2,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb3
	goto	multp10k
;------------------
;	 1 Khz =	   86 37+1	34359,738368
;------------------
add1khz
	movf	DIGFREQ+3,W
	btfsc	STATUS,Z
	goto	add100h

	movwf	DIGVAL
	incf	DIGVAL,F
multp1k
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add100h

	bcf		STATUS,C
	movlw	0x38			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add1kb1
	bcf		STATUS,C
	movlw	0x86			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
	goto	multp1k
;------------------
;	100 Hz =	   0D 6B+1	3435,9738368
;------------------
add100h
	movf	DIGFREQ+2,W
	btfsc	STATUS,Z
	goto	add10hz

	movwf	DIGVAL
	incf	DIGVAL,F
multp100h
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add10hz

	bcf		STATUS,C
	movlw	0x6C			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add100hb1
	bcf		STATUS,C
	movlw	0x0D			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb2
	goto	multp100h
;------------------
;	 10 Hz =	   01 57+1	343,59738368
;------------------
add10hz
	movf	DIGFREQ+1,W
	btfsc	STATUS,Z
	goto	add1hz

	movwf	DIGVAL
	incf	DIGVAL,F
multp10h
	decf	DIGVAL,F
	btfsc	STATUS,Z
	goto	add1hz

	bcf		STATUS,C
	movlw	0x58			
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
add10hb1
	bcf		STATUS,C
	movlw	0x01			
	addwf	AD9850TWORDS+1,F
	btfsc	STATUS,C
	call	incb2			;is carry bit ?
	goto	multp10h
;------------------
;	  1 Hz = 	      22	34,359738368
;------------------
add1hz
	movf	DIGFREQ+0,W
	btfsc	STATUS,Z
	return

	movwf	DIGVAL
	incf	DIGVAL,F
multp1h
	decf	DIGVAL,F
	btfsc	STATUS,Z
	return

	bcf		STATUS,C
	movlw	0x22		
	addwf	AD9850TWORDS+0,F
	btfsc	STATUS,C			;is carry bit ?
	call	incb1
	goto	multp1h

	return
;-------------------------------------------------------------------------;
; 	Send AD9850 5 tuning words
;	send ascending order 0-1-2-3-4
; 	word 4 has phase and control informations 
; 	fout=(tw x clkin)/2^32
;	2^32=4294967295
; tw= 34,359738368*HZ (clk 125MHz)
;-------------------------------------------------------------------------;
AD9850_WR_Serial

call 	CalcADTW
;;print word 1 for debug
;	bank0
;	movlw 	AD9850TWORDS+0
;	;register address
;	movwf	FSR					;load addr base
;	movf	INDF,W				;load value
;	movwf	VREGX				;copy value
;	movlw	0x10				;set lcd position
;	call 	SetLCDPos 
;	movlw	0x08				;bit count
;	movwf	LSMENUVAR
;prxloopad
;  	btfsc 	VREGX,7
;	goto  	$+3
;	movlw 	'0'
;	goto  	$+2 ; call lcddata
;	movlw 	'1'
;	call 	LCDdata
;    rlf 	VREGX,F
;	decfsz 	LSMENUVAR,F
;	goto 	prxloopad

;;;;;;;; start tested block
 ;;make word 0
;AD9850MKW0
;	bank0
;	movlw 	AD9850TWORDS+0	;register address
;	movwf	FSR					;load addr base
;	movf	INDF,W				;load value
;	movwf	VREGX				;copy value
;	movlw	0x08				;bit count
;	movwf	LSMENUVAR
;mk0loop
;  	btfsc 	VREGX,0
;	goto  	$+4					;not 0 goto 1
;	bcf		AD9850PORT,BITDATA	;	movlw 	'0'
;	call	AD9850clkp
;	goto  	$+3				; continue
;	bsf		AD9850PORT,BITDATA	;movlw 	'1'
;	call	AD9850clkp	
 ;   rrf 	VREGX,F
;	decfsz 	LSMENUVAR,F
;	goto 	mk0loop

;;;;;;;; end tested block
AD9850MKWALL
	bank0
	movlw	AD9850TWLEN		;load word units to send
	movwf	TWCOUNT			;store in TWCOUNT
	movlw 	AD9850TWORDS+0	;register address
	movwf	FSR					;load addr base
twloop
	movf	INDF,W				;load value
	movwf	VREGX				;copy value
	movlw	0x08				;bit count
	movwf	LSMENUVAR
mkallloop
  	btfsc 	VREGX,0
	goto  	$+4					;not 0 goto 1
	bcf		AD9850PORT,BITDATA	;	movlw 	'0'
	call	AD9850clkp
	goto  	$+3				; continue
	bsf		AD9850PORT,BITDATA	;movlw 	'1'
	call	AD9850clkp	
    rrf 	VREGX,F
	decfsz 	LSMENUVAR,F
	goto 	mkallloop
	incf	FSR,F			;next word location address
	decfsz	TWCOUNT,F
	goto	twloop

;;update frq
	bsf	AD9850PORT,FQUP
	bcf	AD9850PORT,FQUP

	return

AD9850clkp
	bsf	AD9850PORT,CLK
	bcf	AD9850PORT,CLK
	return
;-------------------------------------------------------------------------;
; END AD9850 Section
;-------------------------------------------------------------------------;

	END

