;********************************************************************************
;
;	Original program by Richard Hosking (e-mail  -  ???) using pic16c57
;	Modify by LZ4ZD Zlatan Dimitrov (lz4zd@qsl.net) using pic16f84
;
;	This program drive mc145170 Motorola PLL Serial Synthesizer
;	from 87.6-108.0 (FM Broadcast Band) in 100kHz steps
;
;	Freq is selected with DIP switch conected to RB0:RB7 (with pull-up resistors to Vdd)
;	MCLR (reset) shift selected freq in synthesizer
;	ENB  is RA0
;	CLK  is RA1
;	DATA is RA2
;
;	4MHz Xtal
;
	LIST 	p=16f84, n = 66
	include "p16f84.inc"
	__FUSES _XT_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF

carry			equ     0	; Carry bit in status register

temp			equ     8	; Register for temporary data
temp_1			equ     9


divider_hi		equ     0E	; Address of current synth data 
divider_lo		equ     0F	; N divider

tx_hi			equ     12	; Address of tx freq data 
tx_lo			equ     13	; N counter

synth_enable		equ     0	; Synthesizer enable bit port A
synth_clock		equ     1	; Synthesizer data clock bit port A
synth_data		equ     2	; Synthesizer data bit port A

configure		equ     64	; Configuration setup for synth
	; Bit 7    0 Polarity unchanged
	; Bit 6    1 Differential phase det
	; Bit 5    1 Lock detect enable
	; Bits 432 001 Ref out enable divide by 1 
	; Bit 1    0 Fv disable
	; Bit 0    0 Fr disable

counter			equ	20	;wait counter

;********************************************************************
start
;
;********************************************************************
;
; Routine to initialize ports 
;
;********************************************************************

	clrf 	PortA
	clrf	PortB
	bsf	Status,RP0
	movlw	0x00			;Define PortA as output
	movwf	TrisA

	movlw	0xff			;Define PortB as input
	movwf	TrisB

	bcf	Status,RP0

	bcf     portA,synth_clock	; Clock low initially
	bsf     portA,synth_enable	; Enable high initially
	nop
	nop
	bcf     portA,synth_enable	; and then low to allow data to synth
	movlw   configure		; Configuration word for synth
	movwf   temp
	movlw   08			; 8 bits
	movwf   temp_1

loop_configure
	rlf     temp,f
	btfsc   status,carry		; Write bit to port A
	bsf     portA,synth_data
	btfss   status,carry
	bcf     portA,synth_data
	bsf     portA,synth_clock	; Clock data
	bcf     portA,synth_clock
	decfsz  temp_1

	goto	loop_configure		; 

	bsf     portA,synth_enable	; Latch data to synth

;*******************************************************************************
;
; Programing Register R
;

        movlw   07			; first 7 bits low of 15 bits
        movwf   temp			; Reference divide by 40 (028h)
        bcf     portA,synth_enable
loop_2					; to give 100 KHz steps from 4 MHz clock
        bcf     portA,synth_data	; Data low
        bsf     portA,synth_clock	; Clock data into synthesizer
        bcf     portA,synth_clock
        decfsz  temp
        goto    loop_2

        bcf     portA,synth_data	; Data=0
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock

        bsf     portA,synth_data	; Data=1
        bsf     portA,synth_clock	; 1
        bcf     portA,synth_clock	;
        bcf     portA,synth_data	; Data=0
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock
        bsf     portA,synth_data	; Data=1
        bsf     portA,synth_clock	; 1
        bcf     portA,synth_clock
        bcf     portA,synth_data	; Data=0
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock
        bsf     portA,synth_clock	; 0
        bcf     portA,synth_clock

        bsf     portA,synth_enable	; Data to R reg 

;***************************************************************************
;
; Reading DIP Switch
;
;***************************************************************************

	movlw	0x6C
	movwf	tx_lo
	movlw	0x03
	movwf	tx_hi

        movf    PortB,w
	addwf	tx_lo,f
	btfsc   status,carry
	incf	tx_hi,f

	call	synthesizer

	sleep

;***************************************************************************
;
; Synthesizer routine
; Writes 17 bits of data to the A and M dividers
; to update the synthesizer
; A data 7 bits, MSB first followed by M data 10 bits MSB first
;
synthesizer

;

        movf    tx_hi,w			; tx_rx bit high = transmit
        movwf   divider_hi
;
        movf    tx_lo,w
        movwf   divider_lo
;
        movlw   08			; Count for software loop
        movwf   temp			; 16 bits to update synth divider
        bcf     portA,synth_clock	; Clock must be low initially
        bcf     portA,synth_enable	; Enable must be low to load data
;
loop_hi
        rlf     divider_hi		; Move bit from divider data into carry
        btfsc   status,carry		; and then to synthesizer
        bsf     portA,synth_data
        btfss   status,carry
        bcf     portA,synth_data
        bsf     portA,synth_clock	; Clock data to synthesizer on pos transition
        bcf     portA,synth_clock	; and reset for next bit
        decfsz  temp			; next bit
        goto    loop_hi
;
        movlw   08			; count for lo byte
        movwf   temp
loop_lo
        rlf     divider_lo		; Same for M byte
        btfsc   status,carry
        bsf     portA,synth_data
        btfss   status,carry
        bcf     portA,synth_data
        bsf     portA,synth_clock
        bcf     portA,synth_clock
        decfsz  temp
        goto    loop_lo
;
        bsf     portA,synth_enable	; Enable bit low to restart synthesizer
        retlw   0			; Return


;***************************************************************************
;
; Wait 
;
wait

	movlw	0xff
	movwf	counter
kill	decfsz	counter
	goto	kill
	return

	end
;************************
;
; COOL ;-)
;
;************************