
 List p=16F877A
 #include <p16F877A.inc>
 #include <ComDef.inc>
;------------------------------------------------------
; Control bits
;------------------------------------------------------

__CONFIG _CP_OFF & _WDT_OFF & _HS_OSC

;------------------------------------------------------
; Decliation
;------------------------------------------------------
	CNT1		EQU		20H			; Timer 100uS
	CNT2		EQU		21H			;
	CNT3		EQU		22H			;
	CNT4		EQU		23H			;
	CNT5		EQU		24H			;
	CNT6		EQU		25H			;
	DP_DATA		EQU		26H			; LCD Data
	LOOP_P1 	EQU		27H			; Loop Counter1
	LOOP_P2		EQU		28H			; Loop Counter2
	Page_Ad 	EQU		29H			; Page Address
	Line		EQU		2AH			; Line Address
	LCD_CHR 	EQU		2BH			; Writting character data
	LOOP_P3		EQU		2CH			; Loop Counter (For Large dedit display)
	LOOP_P4		EQU		2DH			; Loop Counter (For LArge degit display)
	D_POS1		EQU		2EH			; LArge Degit Position 1 Data
	D_POS2		EQU		2FH			; LArge Degit Position 2 Data
	D_POS3		EQU		30H			; LArge Degit Position 3 Data
	D_POS4		EQU		31H			; LArge Degit Position 4 Data
	D_POS5		EQU		32H			; LArge Degit Position 5 Data
	D_POS6		EQU		33H			; LArge Degit Position 6 Data
	D_POS7		EQU		34H			; LArge Degit Position 7 Data
	D_POS8		EQU		35H			; LArge Degit Position 8 Data
	PCLSTR		EQU		36H			; PCLATH Store area
	OFFSET1		EQU		37H			; Large Offset by character defference (Low)
	OFFSET2 	EQU		38H			; Large Offset by Character defference (High)
	OFFSET3 	EQU		39H			; Small Offset by Character defference  

	BIN_L		EQU		3AH			; Frequency Binary Data Low byte (Work Area)
	BIN_H		EQU		3BH			; Frequency Binary Data High byte (Work Area)
	R0			EQU		3CH			; BCD DATA
	R1			EQU		3DH			; BCD DATA
	R2			EQU		3EH			; BCD DATA
	Count		EQU		3FH			; Count Work area
	Temp1		EQU		40H			; Workarea

	WTEMP		EQU		41H			; W reg to Store during interrupt
	STTEMP  	EQU		42H			; STATUS reg to store
	PULSEUP 	EQU		43H			; Encoder pulse multipiyer for up
	PULSEDW 	EQU		44H			; Encoder pulse multiplyer for down
	INC_MX		EQU		45H			; Frequency, Upper side limit flag
	DEC_MX		EQU		46H			; Frequency, Lower side limit flag
	BIN_L2  	EQU		47H			; Frequency Binary Data Low byte (Store Area)
	BIN_H2  	EQU		48H			; Frequency Binary Data High byte (Store Area)

	DDS2_CT		EQU		49H			; 2nd DDS loop counter
	DDS2_DT_L	EQU		4AH			; 2nd DDS Data Low byte
	DDS2_DT_H	EQU		4BH			; 2nd DDS Data High byte
	DDS2_2W_L	EQU		4CH			; 2nd DDS Lower data Low byte
	DDS2_2W_H	EQU		4DH			; 2nd DDS Lower data high byte

	Mode 		EQU		4EH			; Mode status (01=CW, 02=SSB, 03=AM)

	KEYDATA		EQU		4FH			; Keyboard data
	KEY_ACK		EQU		50H			; Keyboad data acknowledge
	
	KEYER_SP	EQU		51H			; KeySpeed workarea
	CN_ST		EQU		52H			; ADC KeySpeed Store area
	TX_RX		EQU		53H			; TX=01H, RX=02H
	SPITX_DT	EQU		54H			; SPI TX data area
	SPIRX		EQU		55H			; SPI RX data
	SPITX_AD	EQU		56H			; SPI TX Address pointer

	ENC_PLS		EQU		57H			; Encorder "UP" or "Down"
	SPI_TIMEOUT EQU		58H			; SPI communication timeout loop counter
	ENC_COND	EQU		59H			; ENC Condition store 
	STEP_RATE	EQU		5AH			; Step rate (21H=1KHz, 22H=100Hz)
	CNT8		EQU		5BH			; 100uS
	BUZZER_VL	EQU		5CH			; Compare previos key data to current one
	VFO_SEL		EQU		5DH			; VFO Chennel data
	TRS_SEL		EQU		5EH			; Transmitting=01H, Receive=02H
	MEM_SEL		EQU		5FH			; Memory channel select

	DOT_PRESS	EQU		60H			; Keyer "DOT" press flag
	LINE_PRESS	EQU		61H			; Keyer "LINE" press flag

	EE_ADDR		EQU		110H		; EEPROM Write address
	EE_DATA		EQU		111H		; EEPROM Write data
;-----------------------------------------------------------------------------
;Macros to select the register bank
; Many bank changes can be optimized when only one STATUS bit changes

BANK0		MACRO			;macro to select data RAM bank 0
		bcf	STATUS,RP0
		bcf	STATUS,RP1
		ENDM

BANK1		MACRO			;macro to select data RAM bank 1
		bsf	STATUS,RP0
		bcf	STATUS,RP1
		ENDM

BANK2		MACRO			;macro to select data RAM bank 2
		bcf	STATUS,RP0
		bsf	STATUS,RP1
		ENDM

BANK3		MACRO			;macro to select data RAM bank 3
		bsf	STATUS,RP0
		bsf	STATUS,RP1
		ENDM

;----------------------------------------------------------------------------	
       ORG 0H
		Goto   	Main
;----------------- Main Routine ----------------------------
Main
		CALL	PORTINI			; Initialize for the ports
		CALL	SPIINI			; SPI communication initialize
		CALL	BUZZER_CHK
	
		BCF		PORTD,4			; CW KEY OFF
		BCF		PORTB,3			; Side Tone OFF
		BSF		PORTD,2			; Mute ON
		BCF		PORTD,3			; Relay OFF
		BCF		PORTD,1			; Mode"AM" OFF
		BCF		PORTB,2			; TX Carrier OFF

		MOVLW	02H				; TX/RX=01H(RX)
		MOVWF	TX_RX			;
		MOVLW	00H				; Clear Encorder condition flag
		MOVWF	ENC_COND				

		MOVLW	0C8H
		MOVWF	BIN_L2
		MOVLW	00H
		MOVWF	BIN_H2

		MOVLW	H'3'			; Rotary Encoder pulse multi
		MOVWF	PULSEUP
		MOVWF	PULSEDW
		MOVLW	H'0'			; Max/Min Frequency flag clear
		MOVWF	INC_MX	
		MOVWF	DEC_MX

		MOVLW	80H				; DDS2 lower initila data set
		MOVWF	DDS2_2W_L
		MOVLW	77H				; DDS2	higher initial data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Local DDS accsess

;		MOVLW	02H				; Test "Mode"=SSB
;		MOVWF	Mode

		CALL	EEP_MODE		; Read Mode data from EEPROM

		MOVLW	22H				; Step rate initialize as 100Hz
		MOVWF	STEP_RATE				

		CALL    BinTOBCD		; Convert to BCD
		CALL	BCDtoASC		; BCD to ASCII
		
;		CALL	MEMCH_DSP		; Display ' MEMORY CH XX '

		BCF		PORTC,0			; Keyboard colunm clear
		BCF		PORTC,1			;
		BCF		PORTC,2			;
		BCF		PORTC,6			;
		BCF		PORTC,7			;

		MOVLW	00H				; Clear Keyboard data/ack
		MOVWF	KEY_ACK			;
		MOVWF	KEYDATA			;

		MOVLW	01H				; Keyer flag initilize
		MOVWF	DOT_PRESS		
		MOVWF	LINE_PRESS
		
		CALL	CHK_SP			; Keyer speed check
		CALL	TIME50M			; Delay 50mS
		BCF		PORTD,2			; Mute off

;		MOVLW	B'10010000'     ; RB0/INT
;       MOVWF	INTCON   
;		BSF		INTCON,GIE		; Enable Interrupt

		CALL	KB_EVENT
LOOP
		CALL	BUZZER_CHK
		CALL	ENC				; Encorder processing
		CALL    KEYB
		CALL	KB_EVENT		; If any key is pressed,the routine will act the change
		CALL	KEYER			; Elekey process
		CALL	PTT				; MIC PTT
		GOTO	LOOP

;-------------- Encoder processing ------------------
ENC
		BTFSS	ENC_COND,0		; Check Encoder condition
		GOTO	ENC50			; 
		BTFSC	PORTB,0			; Check PB0 is still "1".
		RETURN					; If PB0 is still "0", nothing change and return
		BCF		ENC_COND,0		; Clear encoder condtion flag
		RETURN					;	
ENC50
		BTFSS	PORTB,0			; Check PORT0 has risen ?
		RETURN					; No change is detected.and return
		BSF		ENC_COND,0		; Set Encoder condition flag set

      ; Check Whchi is the pulse ,"Up" or "Down" ?
ENC100
		CALL	TIME500U		; Wait 500uS
		BTFSS	PORTB,1			; Check PB1
		GOTO	ENC130			; If PB1=1 goto "Up" data (Int130)

ENC110  ; If "Down Pulse"
		DECFSZ	PULSEDW			; Decrement the multi and check 5 times continue
		Goto	ENC210			; If 5 times yet, Goto Int210
ENC120
		BSF		PORTA,1
		BCF		PORTA,1
		MOVLW	11H				; "Down" Command
		MOVWF	ENC_PLS			; 
		CALL	ENC_SPI			; SPI Communication	
		GOTO	ENC220			
ENC210	
		MOVLW	H'1'			
		MOVWF	PULSEUP			; Reset "Up" multi 
		GOTO	ENC230			; Goto	RETURN 

ENC130	; If "Up Pulse";
		DECFSZ	PULSEUP			; Increment the multi and check 5 times continue
		GOTO	ENC220			; If 5 times yet, Goto Int220
ENC140
		BSF		PORTA,0
		BCF		PORTA,0
		MOVLW	10H				; "Up" Command
		MOVWF	ENC_PLS			; 
		CALL	ENC_SPI			; SPI Communication	
		GOTO	ENC210
ENC220
		MOVLW	H'1'			
		MOVWF	PULSEDW			; Reset "Up" multi 
ENC230
	    RETURN

;--------------- Keyboard event prosessing ------------
KB_EVENT
		MOVF	KEY_ACK,W		; Check key ACK 
		SUBLW	01H				;
		BTFSS	STATUS,2		;
		RETURN					; There is no key input	

;   *****  VFO channel select *****
KB_VFO_00
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	01H				; Keydata is "1" as Check "VFO=A" ?
		BTFSS	STATUS,2
		GOTO	KB_VFO_10		;

		MOVLW	01H				; "VFO= A"
		MOVWF	VFO_SEL			; Store
		CALL	VFO_SPI			; Request SPI communication

		GOTO	KB_EVENT_END

KB_VFO_10
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	02H				; Keydata is "1" as Check "VFO=B" ?
		BTFSS	STATUS,2
		GOTO	KB_VFO_20		;

		MOVLW	02H				; "VFO= B"
		MOVWF	VFO_SEL			; Store
		CALL	VFO_SPI			; Request SPI communication

		GOTO	KB_EVENT_END

KB_VFO_20
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	03H				; Keydata is "1" as Check "VFO=A/B" ?
		BTFSS	STATUS,2
		GOTO	KB_MEM_10		;

		MOVLW	03H				; "VFO= A/B"
		MOVWF	VFO_SEL			; Store
		CALL	VFO_SPI			; Request SPI communication
		GOTO	KB_EVENT_END

;    *******  Memory channel select  *********

KB_MEM_10
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	05H				; Pressed "5" ?
		BTFSS	STATUS,2
		GOTO	KB_MEM_20		;

		MOVLW	05H				; "Memory data write"
		MOVWF	MEM_SEL			; Store
		CALL	MEM_SPI			; Request SPI communication
		GOTO	KB_EVENT_END

KB_MEM_20
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	06H				; Pressed "Up" ?
		BTFSS	STATUS,2
		GOTO	KB_MEM_30		;

		MOVLW	06H				; "Memory data write"
		MOVWF	MEM_SEL			; Store
		CALL	MEM_SPI			; Request SPI communication
		GOTO	KB_EVENT_END

KB_MEM_30
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	07H				; Pressed "Up" ?
		BTFSS	STATUS,2
		GOTO	KB_MODE_SEL		;

		MOVLW	07H				; "Memory data write"
		MOVWF	MEM_SEL			; Store
		CALL	MEM_SPI			; Request SPI communication
		GOTO	KB_EVENT_END

;    *******  Mode select ********
KB_MODE_SEL
	
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0AH				; Check pressed "SSB" Key
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_10		; Goto next item

		MOVLW	02H				; Mode="SSB"
		MOVWF	Mode			; Store
		CALL	MODE_SPI		; requests SPI communication

		BCF		PORTD,1			; Mode"AM" OFF
		BCF		PORTB,3			; SideTone OFF
		BCF		PORTB,2			; TX Carrier OFF

		MOVLW	80H				; DDS2 lower data set  5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	77H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Accsess DDS2
		GOTO	KB_EVENT_END

KB_EVENT_10
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0BH				; Check pressed "CW" Key
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_20		;

		MOVLW	01H				; Mode="CW"
		MOVWF	Mode			; Store
		CALL	MODE_SPI		; requests SPI communication

		BCF		PORTD,1			; Mode"AM" OFF
		BCF		PORTB,3			; SideTone OFF
		BSF		PORTB,2			; TX Carrier ON

		MOVLW	00H				; DDS2 lower data set 5.9977MHz
		MOVWF	DDS2_2W_L
		MOVLW	40H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Accsess DDS2

		GOTO	KB_EVENT_END
	
KB_EVENT_20
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0CH				; Check pressed "AM" Key
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_30		;

		MOVLW	03H				; Mode="AM"
		MOVWF	Mode			; Store
		CALL	MODE_SPI		; requests SPI communication

		BSF		PORTD,1			; Mode"AM" ON
		BCF		PORTB,3			; SideTone OFF
		BSF		PORTB,2			; TX Carrier ON

		MOVLW	00H				; DDS2 lower data set 5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	50H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_AM			; -455KHz for AM Mode
		GOTO	KB_EVENT_END

KB_EVENT_30
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0DH				; 
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_40		;

		MOVLW	21H				; Change to "1KHz"
		MOVWF	STEP_RATE		; Store data

		CALL	STEP_SPI		; requests SPI Communination
		GOTO	KB_EVENT_END

KB_EVENT_40
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0EH				; 
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_50		;

		MOVLW	22H				; Change to "100Hz"
		MOVWF	STEP_RATE		; Store data

		CALL	STEP_SPI		; requests SPI Communination
		GOTO	KB_EVENT_END
KB_EVENT_50
		MOVF	KEYDATA,W		; Fetch key data
		SUBLW	0FH				; 
		BTFSS	STATUS,2		;
		GOTO	KB_EVENT_60		;

		MOVLW	23H				; Change to "100Hz"
		MOVWF	STEP_RATE		; Store data

		CALL	STEP_SPI		; requests SPI Communination
		GOTO	KB_EVENT_END

KB_EVENT_60
		GOTO	KB_EVENT_90		; Iregular input
	
KB_EVENT_END
		CALL	BUZZER_CHK		; Buzzer on
KB_EVENT_70
		MOVLW	00H				; Key DATA/ACK Clear
		MOVWF	KEY_ACK
		MOVWF	KEYDATA
KB_EVENT_80
		MOVLW	4EH				; Set "Mode" address in RAM to EEPROM writing
		BANKSEL	EEADR
		MOVWF	EE_ADDR	
		BANKSEL	PIR1		
		MOVF	Mode,W			; Set "Mode" address in RAM to EEPROM writing
		BANKSEL	EEDATA
		MOVWF	EE_DATA
;		BSF		PCLATH,3		; Select Page 1
		CALL	EEP_WR
;		BCF		PCLATH,3		; Back to Page 0
		BANKSEL	PIR1

		RETURN

KB_EVENT_90
		MOVLW	00H				; Key DATA/ACK Clear
		MOVWF	KEY_ACK
		MOVWF	KEYDATA

		RETURN

;------- Check buzzer should activete ? ---------------------
BUZZER_CHK
		MOVF	KEYDATA,W		; 00?
		SUBLW	0FH				; Keydata <=0FH
		BTFSS	STATUS,0		; 
		GOTO	BUZZER_CHK_10

		MOVF	KEYDATA,W		; Compare data
		SUBWF	BUZZER_VL		
		BTFSC	STATUS,2
		GOTO	BUZZER_CHK_10

		CALL	BUZZER			; In case that data is defferent, buzzer on
	
BUZZER_CHK_10
		MOVF	KEYDATA,W		; If data is the same, it will be stored at BUZZER_VL
		MOVWF	BUZZER_VL
BUZZER_CHK_20
		RETURN

;------- SPI communication when Mode is changed --------
MODE_SPI
		MOVFW	Mode			; Fatch Mode data
		MOVWF	SPITX_DT		; Set Mode data
		MOVLW	50H				; Set "Mode" command
		MOVWF	SPITX_AD		;
		CALL	SPICOM			; Call SPI Communication
		MOVFW	KEY_ACK
		RETURN
;------- SPI Communication when encorder puls is generated ---
ENC_SPI
		CALL	SPIINI
		MOVFW	ENC_PLS			; Fatch encorder UP/DOWN
		MOVWF	SPITX_DT		; Set Mode data
		MOVLW	51H				; Set "FSR address" in DSP controller
		MOVWF	SPITX_AD		;
		BSF		PORTA,0			
		BCF		PORTA,0
		CALL	SPICOM			; CALL SPI Communication
		MOVFW	KEY_ACK
		RETURN
;-------- SPI Communication when Frequency step rate is changed ----
STEP_SPI
		MOVFW	STEP_RATE		; Fatch Step rate data
		MOVWF	SPITX_DT		; Set rate data
		MOVLW	52H				; Set "Step" command
		MOVWF	SPITX_AD		;
		CALL	SPICOM			; Call SPI communication
		MOVFW	KEY_ACK
		RETURN
;--------- SPI Communication when VFO channel data is changed ----
VFO_SPI
		MOVFW	VFO_SEL			; Fatch Key data
		MOVWF	SPITX_DT		; Set rate data
		MOVLW	53H				; Set "Step" command
		MOVWF	SPITX_AD		;
		CALL	SPICOM			; Call SPI communication
		MOVFW	KEY_ACK
		RETURN
;---------- Transmit/Receive flag is changed ----------
TRS_SPI
		MOVFW	TRS_SEL			; Fetch T/R data
		MOVWF	SPITX_DT		; Set rate data
		MOVLW	54H				; Set "Step" command
		MOVWF	SPITX_AD		;
		CALL	SPICOM			; Call SPI communication
		MOVFW	KEY_ACK
		RETURN
;---------- SPI Communication when key "WR","UP" or "DW" is pressed ----
MEM_SPI
		MOVFW	MEM_SEL			; Fetch T/R data
		MOVWF	SPITX_DT		; Set rate data
		MOVLW	55H				; Set "Step" command
		MOVWF	SPITX_AD		;
		CALL	SPICOM			; Call SPI communication
		MOVFW	KEY_ACK
		RETURN
;--------------- Keyboard sense -----------------------
KEYB
		BCF		PORTC,0			; ROW 0 Sensing ON
		CALL	TIME50U			; Wait 50uS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSC	STATUS,2		; goto Next row sensing
		GOTO	KEYB10
		CALL	TIME500U		; Wait 5mS
		MOVF	PORTB, W		; Key data read again
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSS	STATUS,2		; goto Next row sensing
		GOTO	KB_ENCODE_01	; Key boad is pressing surely thrn goto encode routine		
KEYB10
		BSF		PORTC,0			; ROW 0	Sensing OFF
		BCF		PORTC,1			; ROW 1 Sensing ON
		CALL	TIME50U			; Wait 50uS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSC	STATUS,2		; goto Next row sensing
		GOTO	KEYB20
		CALL	TIME500U		; Wait 5mS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSS	STATUS,2		; goto Next row sensing
		GOTO	KB_ENCODE_02	; Key boad is pressing surely thrn goto encode routine		
KEYB20	
		BSF		PORTC,1			; ROW 1 Sensing OFF	
		BCF		PORTC,2			; ROW 2 Sensing ON
		CALL	TIME50U			; Wait 50uS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSC	STATUS,2		; goto Next row sensing
		GOTO	KEYB30
		CALL	TIME500U		; Wait 5mS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSS	STATUS,2		; goto Next row sensing
		GOTO	KB_ENCODE_03	; Key boad is pressing surely thrn goto encode routine	
KEYB30
		BSF		PORTC,2			; ROW 2 Sensing OFF
		BCF		PORTC,6			; ROW 3 Sensing ON
		CALL	TIME50U			; Wait 50uS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSC	STATUS,2		; goto Next row sensing
		GOTO	KEYB50
		CALL	TIME500U		; Wait 5mS
		MOVF	PORTB, W		; Key data read
		IORLW	B'00001111'		; OR Bit 0-3
		SUBLW	B'11111111'		; Is there no input ?
		BTFSS	STATUS,2		; goto Next row sensing
		GOTO	KB_ENCODE_04	; Key boad is pressing surely thrn goto encode routine	
KEYB40
	;	BSF		PORTC,6			; ROW 3 Sensing OFF
	;	BCF		PORTC,7			; ROW 4 Sensing ON
	;	CALL	TIME50U			; Wait 50uS
	;	MOVF	PORTB, W		; Key data read
	;	IORLW	B'00001111'		; OR Bit 0-3
	;	SUBLW	B'11111111'		; Is there no input ?
	;	BTFSC	STATUS,2		; goto Next row sensing
	;	GOTO	KEYB50
	;	CALL	TIME500U		; Wait 5mS
	;	MOVF	PORTB, W		; Key data read
	;	IORLW	B'00001111'		; OR Bit 0-3
	;	SUBLW	B'11111111'		; Is there no input ?
	;	BTFSS	STATUS,2		; goto Next row sensing
	;	GOTO	KB_ENCODE_04	; Key boad is pressing surely thrn goto encode routine	
KEYB50
		BSF		PORTC,6
		RETURN
;-------- Keyboard degital filter (Wait 5mS)-----------
KB_ENCODE_01
		CALL	KB_BIT_ADDER	; Call bit check and add value
		MOVLW	0H				; If ROw 0 is pressed, add value 0 to KB data reg
		ADDWF	KEYDATA			;
		
		MOVLW	01H				; Set Keyboad "ACK"
		MOVWF	KEY_ACK	
		BSF		PORTC,0			; ROW 0 Sensing OFF	
	
		RETURN

KB_ENCODE_02
		CALL	KB_BIT_ADDER	; Call bit check and add value
		MOVLW	4H				; If ROw 1 is pressed, add value 4 to KB data reg
		ADDWF	KEYDATA			;
		
		MOVLW	01H				; Set Keyboad "ACK"
		MOVWF	KEY_ACK	
		BSF		PORTC,1			; ROW 1 Sensing OFF	
	
		RETURN

KB_ENCODE_03
		CALL	KB_BIT_ADDER	; Call bit check and add value
		MOVLW	8H				; If ROw 2 is pressed, add value 8 to KB data reg
		ADDWF	KEYDATA			;
		
		MOVLW	01H				; Set Keyboad "ACK"
		MOVWF	KEY_ACK	
		BSF		PORTC,2			; ROW 2 Sensing OFF
		
		RETURN

KB_ENCODE_04
		CALL	KB_BIT_ADDER	; Call bit check and add value
		MOVLW	0CH				; If ROw 3 is pressed, add value 0CH to KB data reg
		ADDWF	KEYDATA			;
		
		MOVLW	01H				; Set Keyboad "ACK"
		MOVWF	KEY_ACK	
		BSF		PORTC,6			; ROW 3 Sensing OFF	
	
		RETURN

KB_ENCODE_05
	;	BSF		PORTC,7			; ROW 4 Sensing OFF
	;	CALL	KB_BIT_ADDER	; Call bit check and add value
	;	MOVLW	10H				; If ROw 4 is pressed, add value 10H to KB data reg
	;	ADDWF	KEYDATA			;
		
		MOVLW	01H				; Set Keyboad "ACK"
		MOVWF	KEY_ACK			
		RETURN

;--------- Read keyboard column data --------------------
KB_BIT_ADDER
		MOVF	PORTB, W		; Key data read
		ANDLW	B'11110000'		; Claer Bit0-3
		SUBLW   B'11100000'		; Check Pressing 'COL 0' ?
		BTFSS	STATUS,2	
		GOTO	KB_BIT_ADDER_10
		MOVLW	0H				; If COL 0="L" then add value '0'
		ADDWF	KEYDATA			
		RETURN

KB_BIT_ADDER_10
		MOVF	PORTB, W		; Key data read
		ANDLW	B'11110000'		; Claer Bit0-3
		SUBLW   B'11010000'		; Check Pressing 'COL 1' ?
		BTFSS	STATUS,2	
		GOTO	KB_BIT_ADDER_20
		MOVLW	1H				; If COL 0="L" then add value '1'
		ADDWF	KEYDATA			
		RETURN

KB_BIT_ADDER_20
		MOVF	PORTB, W		; Key data read
		ANDLW	B'11110000'		; Claer Bit0-3
		SUBLW   B'10110000'		; Check Pressing 'COL 2' ?
		BTFSS	STATUS,2	
		GOTO	KB_BIT_ADDER_30
		MOVLW	2H				; If COL 0="L" then add value '2'
		ADDWF	KEYDATA			
		RETURN

KB_BIT_ADDER_30
		MOVF	PORTB, W		; Key data read
		ANDLW	B'11110000'		; Claer Bit0-3
		SUBLW   B'01110000'		; Check Pressing 'COL 2' ?
		BTFSS	STATUS,2	
		GOTO	KB_BIT_ADDER_40
		MOVLW	3H				; If COL 0="L" then add value '2'
		ADDWF	KEYDATA			
		RETURN

KB_BIT_ADDER_40

		RETURN

;--------------- Local DDS (2nd OSC) Write ------------
DDS2_WR
		MOVLW	28H				; Control Data 2028H set
		MOVWF	DDS2_DT_L
		MOVLW	20H
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 1st word

;		MOVLW	00H	   	; Lower data 4000H set
		MOVF	DDS2_2W_L,W		; Read Lower data 
		MOVWF	DDS2_DT_L
;		MOVLW	43H
		MOVF	DDS2_2W_H,W		; Read highr data
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 2nd word

		MOVLW	03H				; Lower data 6D00H set
		MOVWF	DDS2_DT_L
		MOVLW	62H
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 3rd word

		RETURN
;------ Local DDS (2nd OSC) - 455KHz for AM Mode ---------
DDS2_AM
		MOVLW	28H				; Control Data 2028H set
		MOVWF	DDS2_DT_L
		MOVLW	20H
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 1st word

;		MOVLW	00H	   	; Lower data 4000H set
		MOVF	DDS2_2W_L,W		; Read Lower data 
		MOVWF	DDS2_DT_L
;		MOVLW	43H
		MOVF	DDS2_2W_H,W		; Read highr data
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 2nd word

		MOVLW	4AH				; Lower data 6D00H set
		MOVWF	DDS2_DT_L
		MOVLW	64H
		MOVWF	DDS2_DT_H		
		CALL	DDS_2nd			; Write 3rd word

		RETURN

;--------------- Local DDS (2nd OSC) accsess ----------
DDS_2nd
        BSF		PORTD,5			; SCLK1　initialize
		BSF		PORTD,7			; FSYNC initialize
		CALL	TIME50U			; 50uS wait

		BCF		PORTD,7			; FSYNC active (goes L)
		CALL	TIME50U			; 50uS wait

		MOVLW	8H				; Loop Count set
		MOVWF	DDS2_CT

DDS_2nd_10
		BCF		STATUS,0		; Carry flag clear
		RLF		DDS2_DT_H,1		; Move LSB to C flag
		BTFSS	STATUS,0		; If C is clear, skip the next instruction
		GOTO	DDS_2nd_20

		BSF		PORTD,6			; DDS data is '1'
		GOTO	DDS_2nd_30
DDS_2nd_20
		BCF		PORTD,6			; DDS data is '0'
DDS_2nd_30		
		CALL	TIME50U			; 50uS wait
		BCF		PORTD,5			; Falls CLK
		CALL	TIME50U			; 50uS wait
		BSF		PORTD,5			; Rise CLK
		CALL	TIME50U			; 50uS wait

		DECFSZ	DDS2_CT,1		; Loop
		GOTO	DDS_2nd_10

;        (High Byte)
		MOVLW	8H				; Loop Count set
		MOVWF	DDS2_CT

DDS_2nd_40
		BCF		STATUS,0		; Carry flag clear
		RLF		DDS2_DT_L,1		; Move LSB to C flag
		BTFSS	STATUS,0		; If C is clear, skip the next instruction
		GOTO	DDS_2nd_50

		BSF		PORTD,6			; DDS data is '1'
		GOTO	DDS_2nd_60
DDS_2nd_50
		BCF		PORTD,6			; DDS data is '0'
DDS_2nd_60		
		CALL	TIME50U			; 50uS wait
		BCF		PORTD,5			; Falls CLK
		CALL	TIME50U			; 50uS wait
		BSF		PORTD,5			; Rise CLK
		CALL	TIME50U			; 50uS wait


		DECFSZ	DDS2_CT,1		; Loop
		GOTO	DDS_2nd_40

		BSF		PORTD,7			; FSYNC inactive (goes H)
		CALL	TIME50U			; 50uS wait

		RETURN
; -------------- Exchange Binary to BCD ---------------
BinTOBCD:

		MOVF	BIN_L2,W
		MOVWF	BIN_L

		MOVF	BIN_H2,W
		MOVWF	BIN_H

		BCF		STATUS,0	;Clear Carry bit
		MOVLW	.16
		MOVWF	Count
		CLRF	R0
		CLRF	R1
		CLRF	R2
Loop16
		RLF		BIN_L,F
		RLF		BIN_H,F
		RLF		R2,F
		RLF		R1,F
		RLF		R0,F

		DECFSZ	Count,F
		GOTO	adjDEC
    	RETLW	0
adjDEC
		MOVLW	R2
		MOVWF	FSR
		CALL	adjBCD	
		
		MOVLW	R1
		MOVWF	FSR
		CALL	adjBCD

		MOVLW	R0
		MOVWF	FSR
		CALL	adjBCD

		GOTO	Loop16

adjBCD
		MOVLW	3
		ADDWF	0,W
		MOVWF	Temp1
		BTFSC	Temp1,3		; test if result >7
		MOVWF	0
		MOVLW	30
		ADDWF	0,W
		MOVWF	Temp1
		BTFSC	Temp1,7		; Test if result >7
		MOVWF	0			; Save As MSD
		RETLW	0	
;-------------------- < BCD data to ASCII >------------------------
BCDtoASC:
d1_writebcd:
      movf  R1,W            	          ; Fetch 
      swapf  R1,W                        ; swap nibbles
      andlw  0x0f                        ; clear bits 4-7
      addlw  0x06                        ; add 6
      btfss  STATUS,DC                   ; if a-f, DC=1
      goto   d1_lessnine                 ; if DC=0, < 9, so goto lessnine
      addlw  0x31                        ; add 31h to make ascii
      goto   d1_save_asc1                ; skip to output
d1_lessnine:
      addlw  0x2a   
d1_save_asc1:                            ; add offset for 0-9 to make ascii
	  movwf	 D_POS4

      movf   R1,W                        ; restore W
      andlw  0x0f                        ; clear bits 4-7
      addlw  0x06                        ; add 6
      btfss  STATUS,DC                   ; if a-f, DC=1
      goto   d1_lessnine2                ; if DC=0, < 9, so goto lessnine
      addlw  0x31                        ; add 31h to make ascii
      goto   d1_save_asc2                ; skip to output
d1_lessnine2:
      addlw  0x2a                        ; add offset for 0-9 to
d1_save_asc2:
	  movwf	 D_POS4

d2_writebcd:
      movf  R2,W            	          ; Fetch 
      swapf  R2,W                        ; swap nibbles
      andlw  0x0f                        ; clear bits 4-7
      addlw  0x06                        ; add 6
      btfss  STATUS,DC                   ; if a-f, DC=1
      goto   d2_lessnine                 ; if DC=0, < 9, so goto lessnine
      addlw  0x31                        ; add 31h to make ascii
      goto   d2_save_asc3                ; skip to output
d2_lessnine:
      addlw  0x2a                        ; add offset for 0-9 to make ascii
d2_save_asc3:
	  movwf	 D_POS5

      movf   R2,W                        ; restore W
      andlw  0x0f                        ; clear bits 4-7
      addlw  0x06                        ; add 6
      btfss  STATUS,DC                   ; if a-f, DC=1
      goto   d2_lessnine2                ; if DC=0, < 9, so goto lessnine
      addlw  0x31                        ; add 31h to make ascii
      goto   d2_save_asc4                ; skip to output
d2_lessnine2:
      addlw  0x2a                        ; add offset for 0-9 to
d2_save_asc4:
	  movwf	 D_POS6

	  RETURN


;---------------- Port Initialize -----------------------------
PORTINI							; Port A and B initialize
        BSF		STATUS,RP0
		BCF		STATUS,RP1
		BCF		INTCON,GIE

		MOVLW	b'01000000'		; PB0 interrupt edge polality is "Rise"
		MOVWF	OPTION_REG

	;	MOVLW	b'00100000'		; Bit0-6 are output Bit 4 is set to Analog(AN4)
	;	MOVWF	TRISA
		BSF		TRISA,0			; Port A Bit 0 clear
		BCF		TRISA,1			; Port A Bit 1 clear
		BCF		TRISA,2			; Port A Bit 2 clear
		BCF		TRISA,3			; Port A Bit 3 clear
		BCF		TRISA,4			; Port A Bit 4 clear

		MOVLW	b'11110011'		; PB7-4 for keyboard sense PB0,1 INT
		MOVWF	TRISB
	
		MOVLW	b'00000000'		;
		MOVWF	TRISD			; DDS2(Bit5=SCLK1, 6=SADATA1, 7=FSYNC1)
								; Bit4=Keyout, 3=Relay, 2=Mute
		MOVLW	b'00000111'		; 
		MOVWF	TRISE			; RE0=DOT, RE1=LINE, RE2=MIC PTT

		MOVLW	b'10000010'		; ADCON1 (ADFM=Right, RE2-RE0 Degi in, AN4=Analog
								; VREF+=VDD, VREF-=Vss)

		MOVWF	ADCON1

		BCF		STATUS,RP1
		BCF		STATUS,RP0

		MOVLW   b'01100001'		; ADCON0 (Fosc/8, select RA5/AN4, GO, ADOFF)
		MOVWF	ADCON0

		RETURN

;--------Initialize registers for SPI communication-----------
SPIINI
		BANKSEL SSPCON			; Because SSPCON=14H
		BCF		SSPCON, SSPM3	; SSPM3-0:0001
		BCF		SSPCON, SSPM2
		BCF		SSPCON, SSPM1
		BSF		SSPCON, SSPM0

		BANKSEL SSPSTAT			; Because SSPSTAT=94H
		BCF		SSPSTAT,SMP		; Sample timing =1 as Input data sampled at end of data output time
		BCF		SSPSTAT,CKE		; CKE=0 

		BANKSEL SSPCON
		BCF		SSPCON, CKP
		BSF		SSPCON, SSPEN	; MSSP enable

		BANKSEL	TRISC
		BCF		TRISC,3			; Clock output from the SPI master
		BSF		TRISC,4			; PC4 is set with SPI data input
		BCF		TRISC,5			; PC5 is set with SPI data output

		BCF		TRISC,0			; PC0 is set to DO
		BCF		TRISC,1			; PC0 is set to D1
		BCF		TRISC,2			; PC0 is set to D2
		BCF		TRISC,6			; PC0 is set to D6
		BCF		TRISC,7			; PC0 is set to D7
	
		BANKSEL	SSPCON
		BCF		SSPCON,7		; Clear collision detection bit
		BCF		SSPCON,6		; Clear receive overflow bit

		RETURN

;----------------- Communication by SPI -------------------
SPICOM
		MOVF	SPITX_AD,W		; Address data (Command) set
		MOVWF	SSPBUF			; STore to the buffer (transmittingwill be started)
		WAIT_SSPIF
		CLR_SSPIF
SPICOM15
		MOVF	SPITX_DT,W		; Data set
		MOVWF	SSPBUF			; STore to the buffer (transmitting will be started)
		WAIT_SSPIF
		MOVFW	SSPBUF
		CLR_SSPIF
SPICOM30
		BANKSEL	PIR1
;		BCF		SSPCON, WCOL
;		BCF		SSPCON, SSPOV
		CLR_SSPIF				; Clear SSPIF

;		BSF		INTCON,GIE		; Enable Interrupt
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		RETURN

;----------------- Electric keyer -------------------------
KEYER
		MOVF	Mode,W			; Fetch Mode data
		SUBLW	01H				; Compare "CW" as 01H
		BTFSS	STATUS,2
		GOTO	KEYER100		; If mode is not "CW", go trough Keyer

		BTFSC	PORTE,0			; Check press "DOT"
		GOTO	KEYER50			; If dot doses not come, go to "LINE" check
		BSF		PORTD,2			; Mute ON

		BSF		PORTD,3			; Relay ON
		MOVLW	01H				; Now "Trs"lag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		CALL	TIME50M			; Wait 100mS
		CALL	TIME50M
		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		BCF		PORTD,2			; Mute OFF

KEYER10
		CALL	CHK_SP			; Keyer speed check&set
		CALL	DOT				; "DOT" sends

		MOVF	LINE_PRESS,W	; Check "LINE" is pressed
		SUBLW	02H				
		BTFSS	STATUS,2
		GOTO	KEYER15			; If not, through
		MOVLW	01H				; "LINE" flag clear
		MOVWF	LINE_PRESS
		GOTO	KEYER60			; Goto "LINE"
KEYER15
		MOVF	DOT_PRESS,W		; Check "DOT" press
		SUBLW	02H				
		BTFSS	STATUS,2
		GOTO	KEYER20			; If not, through
		MOVLW	01H				; "DOT" flag clear
		MOVWF	DOT_PRESS
		GOTO	KEYER10			; Goto "DOT"	
KEYER20		
		BTFSS	PORTE,1			; Check press "LINE"
		GOTO	KEYER60			; Goto "LINE" 
		BTFSS	PORTE,0			; Check "DOT" stll pressed ?
		GOTO	KEYER10			; If still press "DOT", repeat "DOT"
		
		CALL	TEST_Time		; Delay Relay on time

		BTFSS	PORTE,1			; Check press "LINE"
		GOTO	KEYER60			; Goto "LINE" 
		BTFSS	PORTE,0			; Check "DOT" stll pressed ?
		GOTO	KEYER10			; If still press "DOT", repeat "DOT"

		CALL	TEST_Time		; Delay Relay on time

		BTFSS	PORTE,1			; Check press "LINE"
		GOTO	KEYER60			; Goto "LINE" 
		BTFSS	PORTE,0			; Check "DOT" stll pressed ?
		GOTO	KEYER10			; If still press "DOT", repeat "DOT"

		CALL	TEST_Time		; Delay Relay on time

		BTFSS	PORTE,1			; Check press "LINE"
		GOTO	KEYER60			; Goto "LINE" 
		BTFSS	PORTE,0			; Check "DOT" stll pressed ?
		GOTO	KEYER10			; If still press "DOT", repeat "DOT"
	
KEYER47
		BSF		PORTD,2			; Mute ON

		BCF		PORTD,3			; Relay OFF
		MOVLW	02H				; "Rec" flag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		BCF		PORTD,2			; Mute OFF

		RETURN

KEYER50
		BTFSC	PORTE,1			; Check press "LINE"
		GOTO	KEYER100		; Go through the routine
		BSF		PORTD,2			; Mute ON

		BSF		PORTD,3			; Relay ON
		MOVLW	01H				; "Trs"flag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	

		BCF		PORTD,2			; Mute OFF
KEYER60
		CALL	CHK_SP			; Keyer speed check&set
		CALL	LINE			; "LINE" Sends
		
		MOVF	DOT_PRESS,W		; Check "DOT" press
		SUBLW	02H				
		BTFSS	STATUS,2
		GOTO	KEYER65			; If not, through
		MOVLW	01H				; "DOT" flag clear
		MOVWF	DOT_PRESS
		GOTO	KEYER10			; Goto "DOT"
KEYER65
		MOVF	LINE_PRESS,W	; Check "LINE" is pressed
		SUBLW	02H				
		BTFSS	STATUS,2
		GOTO	KEYER70			; If not, through
		MOVLW	01H				; "LINE" flag clear
		MOVWF	LINE_PRESS
		GOTO	KEYER60
	
KEYER70
		BTFSS	PORTE,0			; Check "DOT"  pressed ?
		GOTO	KEYER10			; If press "DOT", goto "DOT"
		BTFSS	PORTE,1			; Check "LINE" still pressed ?
		GOTO	KEYER60			; If still press "LINE", repeat "LINE"

		CALL	TEST_Time		; Delay relay on time

		BTFSS	PORTE,0			; Check "DOT"  pressed ?
		GOTO	KEYER10			; If press "DOT", goto "DOT"
		BTFSS	PORTE,1			; Check "LINE" still pressed ?
		GOTO	KEYER60			; If still press "LINE", repeat "LINE"

		CALL	TEST_Time		; Delay relay on time

		BTFSS	PORTE,0			; Check "DOT"  pressed ?
		GOTO	KEYER10			; If press "DOT", goto "DOT"
		BTFSS	PORTE,1			; Check "LINE" still pressed ?
		GOTO	KEYER60			; If still press "LINE", repeat "LINE"

		CALL	TEST_Time		; Delay relay on time

		BTFSS	PORTE,0			; Check "DOT"  pressed ?
		GOTO	KEYER10			; If press "DOT", goto "DOT"
		BTFSS	PORTE,1			; Check "LINE" still pressed ?
		GOTO	KEYER60			; If still press "LINE", repeat "LINE"
		
		BSF		PORTD,2			; Mute ON

		BCF		PORTD,3			; Relay OFF
		MOVLW	02H				; "Rec" flag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		CALL	TIME50M			; Wait 100mS
		CALL    TIME50M	
		BCF		PORTD,2			; Mute OFF

KEYER100
		RETURN

;------------------ Line ------------------------------
LINE
		BSF		PORTD,4			; Key ON
		BSF		PORTB,3			; SideTone ON
		CALL	TEST_Time		; ON Timing (X3)
		CALL	TEST_Time
		CALL	TEST_Time

		BTFSC	PORTE,0			; Check press "DOT"
		GOTO	LINE10			; If not, trough
		MOVLW	02H				; "DOT" press flag on
		MOVWF	DOT_PRESS
		GOTO	LINE20
LINE10
		BTFSC	PORTE,1			; Check press "LINE"
		GOTO	LINE20			; If not, trough
		MOVLW	02H				; "DOT" press flag on
		MOVWF	LINE_PRESS
LINE20
		BCF		PORTD,4			; Key OFF
		BCF		PORTB,3			; SideTone OFF
		
		CALL	TEST_Time		; OFF Timing (X1)
		RETURN

;------------------- Dot -------------------------------
DOT
	 	BSF		PORTD,4			; Key ON
		BSF		PORTB,3			; SideTone ON
		CALL	TEST_Time		; ON Timing (X1)

		BTFSC	PORTE,1			; Check press "LINE"
		GOTO	DOT10			; If not, trough
		MOVLW	02H				; "DOT" press flag on
		MOVWF	LINE_PRESS
DOT10		
		BCF		PORTD,4			; Key OFF
		BCF		PORTB,3			; SideTone OFF
		
		CALL	TEST_Time		; OFF Timing (X1)

		BTFSC	PORTE,0			; Check press "DOT"
		GOTO	DOT20			; If not, trough
		MOVLW	02H				; "DOT" press flag on
		MOVWF	DOT_PRESS		
DOT20
		RETURN
;---------------- Check Speed from Analag Voltage ---------
CHK_SP	
		BCF		INTCON,GIE	
		
		CALL	TIME50U			; Wait 50uS
		BSF		ADCON0,2		; Set Go bit

CHK_SP_10
		BTFSC	ADCON0,2		;
		GOTO	CHK_SP_10		; Complate coversion
		
CHK1							; High=03 Low FF-C1
		MOVF	ADRESH,W		; Read ADC data 
		SUBLW	03H				; Check High byte
		BTFSS   STATUS, 2		; ADC(High byte)- 1 
		GOTO	CHK5			; If High byte > 3 then CHK5
		
		BANK1 
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	0C0H			; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK2			;

		BANK0
		MOVLW	11H				; Set 15 to CNT6(Speed)
		MOVWF	CN_ST		
		GOTO	CHK_END			; Processing End

CHK2							; High=03 Low=C0-81
		BANK1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	80H				; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK3			;

		BANK0
		MOVLW	10H				; Set 14 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK3							; High=03 Low=80-41
		BANK1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	40H				; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK4			;

		BANK0
		MOVLW	0FH				; Set 13 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK4							; High=03 Low=40-00
		BANK0
		MOVLW	0EH				; Set 12 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK5
		MOVF	ADRESH,W		; Read ADC data 
		SUBLW	02H				; Compare to "5"
		BTFSS   STATUS,2		; ADC(High byte)- 5 
		GOTO	CHK9			; Next
		
		BANK1					; High=02 Low=FF-C1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	0C0H			; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK6			;

		BANK0
		MOVLW	0DH				; Set 11 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK6							; High=02 Low=C0-81
		BANK1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	80H				; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK7			;

		BANK0
		MOVLW	0CH				; Set 10 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK7							; High=02 Low=80-41
		BANK1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	40H				; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHK8			;

		BANK0
		MOVLW	0BH				; Set 9 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK8							; High=02 Low=40-00
		BANK0
		MOVLW	0AH				; Set 8 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHK9							; High=01 Low=FF-C1
		MOVF	ADRESH,W		; Read ADC high data 
		SUBLW	01H				; Compare to "9"	
		BTFSS   STATUS,2		; ADC(High byte)- 9 
		GOTO	CHKC			; Next

		BANK1					; High=02 Low=FF-C1
		MOVF	ADRESL,W		; Read ADC Low data 
		SUBLW	0C0H			; Check Low byte
		BTFSC	STATUS,0		;
		GOTO	CHKA			;

		BANK0
		MOVLW	9H				; Set 7 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKA							; High=01 Low C0-81
		BANK1
		MOVF	ADRESL,W		; Read ADC data 
		SUBLW	80H				; Compare to "A"
		BTFSC   STATUS,0		; ADC(High byte)- 10(A)
		GOTO	CHKB			; Next

		BANK0
		MOVLW	8H				; Set 6 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKB	
		BANK1					; High=01 Low=80-41
		MOVF	ADRESL,W		; Read ADC data 
		SUBLW	40H				; Compare to "B"
		BTFSC   STATUS,0		; ADC(High byte)- 11(B) 
		GOTO	CHKC			; Next

		BANK0
		MOVLW	7H				; Set 5 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKC	
		BANK1					; High=00 Low=FF-C1
		MOVF	ADRESL,W		; Read ADC data 
		SUBLW	0C0H			; Compare to "C"
		BTFSC   STATUS,0		; ADC(High byte)- 12(C)
		GOTO	CHKD			; Next

		BANK0
		MOVLW	6H				; Set 4 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKD	
		BANK1					; High=00 Low=C0-81
		MOVF	ADRESL,W		; Read ADC data 
		SUBLW	80H				; Compare to "D"
		BTFSC   STATUS,0		; ADC(High byte)- 13(D)
		GOTO	CHKE			; Next

		BANK0
		MOVLW	5H				; Set 3 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKE
		BANK1					; High=00 Lo=80-41
		MOVF	ADRESL,W		; Read ADC data 
		SUBLW	40H				; Compare to "E"
		BTFSC   STATUS,0		; ADC(High byte)- 14(E) 
		GOTO	CHKF			; Next

		BANK0
		MOVLW	4H				; Set 2 to CNT6(Speed)
		MOVWF	CN_ST			
		GOTO	CHK_END			; Processing End

CHKF
		MOVLW	3H				; Set 1 to CNT6(Speed)
		MOVWF	CN_ST			

CHK_END
		BANK0
		BSF		INTCON,GIE					
		RETURN					; Return

;----------------- Timing 1--------------------------
TEST_Time
    	MOVF	CN_ST,0		; Load speed date to W registor
		MOVWF	KEYER_SP	; Store W regi(Speed) to CNT6
T_LP7	
		CALL	TIME5M
		DECFSZ	KEYER_SP,F
		GOTO	T_LP7
		RETURN
;----------------- MIC PTT -------------------------------
PTT		BTFSC	PORTE,2			; Check press MIC PTT
		GOTO	PTT30			; Go through the routine
		
		CALL	TIME5U			; Delay 5mS (Degi-Fil)
		BTFSC	PORTE,2			; Check press MIC PTT again
		GOTO	PTT30			; PTT release >=5ms go through without Relay On
	
PTT10	MOVF	TX_RX,W			; TX/RX status
		SUBLW	01H				; Is last state TX ?
		BTFSS	STATUS,2		; 
		GOTO	PTT50			;
		GOTO	PTT200			;　Go through if not

PTT30	MOVF	TX_RX,W			; TX?RX status
		SUBLW	02H				; Is last state RX ?
		BTFSS	STATUS,2		; 
		GOTO	PTT100			;
		GOTO	PTT200			; Go through if not
PTT50	
;		CALL	MODE_SPI	
		BSF		PORTD,2			; Mute ON

		BSF		PORTD,3			; Relay ON
		MOVLW	01H				; "Trs" flag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		MOVF	Mode,W			; Fetch Mode data
		SUBLW	01H				; Compare to "CW" as 01H 
		BTFSC	STATUS,2		; If Mode="CW" then skip "CW KEY ON"
		GOTO	PTT60

		BSF		PORTD,4			; CW KEY on when either of mode is AM or SSB
PTT60	
		MOVF	Mode,W			; Fetch Mode data
		SUBLW	03H				; Compare to "AM" as 03H 
		BTFSS	STATUS,2		; If Mode is not "AM" then goto PTT70
		GOTO	PTT70
;------- AM Transmit mode -------
		MOVLW	80H				; DDS2 lower data set  5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	77H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Accsess DDS2

PTT70	
		CALL	TIME50M			; Wait 250mS
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		MOVLW	01H				; TX/RX=01H(TX)
		MOVWF	TX_RX
		BCF		PORTD,2			; Mute OFF
		RETURN					
		
PTT100							; No pressing PTT button
		BSF		PORTD,2			; Mute ON

		BCF		PORTD,3			; Relay Off	
		MOVLW	02H				; "Rec" flag will be sent to DSP
		MOVWF	TRS_SEL
		CALL	TRS_SPI

		BCF		PORTD,4			; CW KEY OFF

			
		MOVF	Mode,W			; Fetch Mode data
		SUBLW	03H				; Compare to "AM" as 03H 
		BTFSS	STATUS,2		; If Mode is not "AM" then goto PTT70
		GOTO	PTT150
; ----- AM Recieve Mode -------
		MOVLW	00H				; DDS2 lower data set 5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	50H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_AM			; -455KHz for AM Mode

PTT150
		CALL	TIME50M			; Wait 250mS
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		CALL	TIME50M
		MOVLW	02H				; TX/RX=02H(RX)
		MOVWF	TX_RX			;
		BCF		PORTD,2			; Mute OFF
PTT200
		RETURN
;----------------- Piezo Buzzer activate -----------------
BUZZER
		MOVLW	80H				;set 200
		MOVWF	CNT5
T_LP9	
		BSF		PORTD,0			; Buzzer ON
		CALL	TIME100U		; Wait 100uS
		BCF		PORTD,0			; Buzzer OFF
		CALL	TIME100U		; Wait 100uS

		DECFSZ	CNT5,F
		GOTO	T_LP9
		RETURN

;----------------- Timers ---------------------------------
TIME50U						;50usec
		MOVLW	9H		
		MOVWF	CNT1		
T_LP1	
		CALL	TIME5U		;2+(25+3)*9-1=253		
		DECFSZ	CNT1,F
		GOTO	T_LP1
		RETURN				;254*0.4=100usec(about)

TIME5U						;5usec
		MOVLW	14H 		; previous =7h
		MOVWF	CNT2		
T_LP2	
		DECFSZ	CNT2,F		;2+3*7-1=22		
		GOTO	T_LP2		
		RETURN				;22+1=23

TIME500U					;500uS
		MOVLW	0AH
		MOVWF	CNT3
T_LP3
		CALL	TIME50U		;2+(254+3)*10-1=2541
		DECFSZ	CNT3,F
		GOTO	T_LP3
		RETURN				;2542

TIME5M						;5msec(about)
		MOVLW	3BH
		MOVWF	CNT4
T_LP4	
		CALL	TIME50U		;2+(254+3)*59-1=15164
		DECFSZ	CNT4,F
		GOTO	T_LP4
		RETURN				;15165

TIM1S
		MOVLW	0C8H		;set 200
		MOVWF	CNT5
T_LP5	
		CALL	TIME50M
		DECFSZ	CNT5,F
		GOTO	T_LP5
		RETURN

TIME50M
		MOVLW	14H			; Set 20
		MOVWF	CNT6
T_LP6
		CALL	TIME5M
		DECFSZ	T_LP6
		RETURN

TIME100U					;100uS
		MOVLW	01H
		MOVWF	CNT8
T_LP8
		CALL	TIME50U		;2+(254+3)*10-1=2541
		DECFSZ	CNT8,F
		GOTO	T_LP8
		RETURN				;2542

;--------------------- EEPROM Write ----------------------------------
EEP_WR
		BSF		STATUS,RP1		; Select bank3
		BSF		STATUS,RP0		
		BTFSC	EECON1,WR		; Wait for write
		GOTO	$-1				; To complete

		BCF		STATUS,RP0		; Select bank2
		MOVF	EE_ADDR,0		; Set address
		MOVWF	EEADR			;
		MOVF	EE_DATA,0		; Set data
		MOVWF	EEDATA			;
		BSF		STATUS,RP0		; Select bank3
		BCF		EECON1,EEPGD	; Select "Data memory" in EEPROM
		BSF		EECON1,WREN		; Enable write

		MOVLW	55H				; Dummy write 55H
		MOVWF	EECON2			; Write
		MOVLW	0AAH			; Dummy write AAH
		MOVWF	EECON2			; Write
		BSF		EECON1,WR		; Set WR bit to begin write
		BCF		EECON1,WREN		; Disable write

		BCF		STATUS,RP1		; Bank0
		BCF		STATUS,RP0			

		RETURN
;--------------------- EEPROM Read -----------------------------------
EEP_RD  ; W reg has address data when call the routine. The routine reads
        ; EEPROM data and transfer to w reg and return.

		BSF		STATUS,RP1		; Select bank2
		BCF		STATUS,RP0
		MOVWF	EEADR			; Set read address
		BSF		STATUS,RP0		; Select bank3
		BCF		EECON1,EEPGD	; Select "Data memory" in EEPROM
		BSF		EECON1,RD		; Read enable
		
		BCF		STATUS,RP0		; Back to bank2
		MOVF	EEDATA,W		; Read data
		MOVWF	PORTA
		BCF		STATUS,RP1		; Back to bank0

		RETURN

;----------------------- MODE Read from EEPROM --------------------------------
EEP_MODE
		MOVLW	4EH				; Set EEPROM reading address
		CALL	EEP_RD			; Read EEPROM data
		MOVWF	Mode			; Store Mode data to RAM

		SUBLW	01H				; CW? 
		BTFSS	STATUS,2		; If CW then goto next process
		GOTO	EEP_MODE10
		CALL	CW_MODE_SET		; Set CW Mode
		GOTO	EEP_MODE40		; END

EEP_MODE10
		MOVFW	Mode
		SUBLW	02H				; SSB? 
		BTFSS	STATUS,2		; If SSB then goto next process
		GOTO	EEP_MODE20
		CALL	SSB_MODE_SET	; Set SSB Mode
		GOTO	EEP_MODE40		; END

EEP_MODE20	
		MOVFW	Mode
		SUBLW	03H				; AM? 
		BTFSS	STATUS,2		; If AM then goto next process
		GOTO	EEP_MODE30
		CALL	AM_MODE_SET		; Set AM Mode
		GOTO	EEP_MODE40		; END

EEP_MODE30
		MOVLW	02H				; If EEPROM data is inlavid, "SSB" as 02H
		MOVWF	Mode

EEP_MODE40
		RETURN
;--------------------- SSB Mode Set ------------------------------------
SSB_MODE_SET
		BCF		PORTD,1			; Mode"AM" OFF
		BCF		PORTB,3			; SideTone OFF
		BCF		PORTB,2			; TX Carrier OFF

		MOVLW	80H				; DDS2 lower data set  5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	77H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Accsess DDS2

		RETURN
;---------------------- CW Mode Set -----------------------------------
CW_MODE_SET
		BCF		PORTD,1			; Mode"AM" OFF
		BCF		PORTB,3			; SideTone OFF
		BSF		PORTB,2			; TX Carrier ON

		MOVLW	00H				; DDS2 lower data set 5.9977MHz
		MOVWF	DDS2_2W_L
		MOVLW	40H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_WR			; Accsess DDS2

		RETURN
;---------------------- AM Mode Set -----------------------------------
AM_MODE_SET
		BSF		PORTD,1			; Mode"AM" ON
		BCF		PORTB,3			; SideTone OFF
		BSF		PORTB,2			; TX Carrier ON

		MOVLW	00H				; DDS2 lower data set 5.9970MHz
		MOVWF	DDS2_2W_L
		MOVLW	50H				; DDS2	higher data set
		MOVWF	DDS2_2W_H
		CALL	DDS2_AM			; -455KHz for AM Mode		

		RETURN

;--------------------- STEP Read from EEPROM -------------------------------
		END

