;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		実験用周波数カウントユニットVer2
;
;		PIC16F688 10MHZ
;
;		PIC16F688プログラムVer1との相違
;
;		HEXバッファは32ビットで、RF入力用と外部データ入力用の2種類ある
;		スイッチはオフセット切替とゲート時間の切替の2種類
;		外部データ出力基板を接続する必要がある。
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



		LIST	P=PIC16F688
		INCLUDE	P16F688.INC

;
;ここの設定方法はPIC12F683とほぼ同じです	
;
;CALIBRATION WORD(ADDRESS:2008H)今回は設定しません。
;bit13		Unimplemented
;bit12-6	FCAL	内部発振器調整
;					0111111=最大発振周波数
;					.
;					0000000=中間
;					.
;					1111111=最小発振周波数
;bit5		Unimplemented
;bit4-3		POR		パワーオンリセット電圧調整
;					00=最小電圧
;					11=最大電圧
;bit2-0		BOD		ブラウンアウト電圧調整
;					000=Reservd
;					001=最小電圧
;					111=最大電圧
;
;		
;CONFIGURATION WORD(ADDRESS:2007H)
;					設定
;bit13-12	Unimplemented
;bit11		FCMEN	0	Fail-Safe Clock Monitor
;						1=有効,0=無効
;bit10		IESO	0	内部･外部切替スイッチモード
;						1=有効,0=無効
;bit9-8		BODEN	00	ブラウンアウト設定
;						11=有効
;						10=スリープ時以外有効
;						01=PCONレジスタSBODENビットでコントロールされる
;						00=無効
;bit7		CPD		1	データメモリプロテクション
;						1=無効,0=有効
;bit6		CP		1	プログラムメモリプロテクション　
;						1=無効,0=有効
;bit5		MCLRE	0	RA3/MCLRピン選択ビット
;						1=MCLR有効,0=RA3有効(Digital input)
;bit4		PWRTE	0	power_up timer　使います。
;						1=無効,0=有効
;bit3		WDTE	0	Watchdog Timer　使いません。
;						1=有効,0=無効
;bit2-0		FOSC	010	発振器選択ビット、今回はHSを使用
;						111=RC:2pinでRC発振、3pinCLKOUT、I/O不可
;						110=RCIO:　〃　RA4I/O可
;						101=INTOSC:内部発振　3pinCLKOUT、RA5I/O可
;						100=INTOSCIO:内部発振、RA4-5I/O可
;						011=EC:2pin外部クロック入力、RA4I/O可
;						010=HS：外部発振子、I/O不可
;						001=XT：　〃
;						000=LP：　〃
;
;bit	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
;data    0  0  0  0  0  0  0  0  1  1  0  0  0  0  1  0
;

		__CONFIG	B'0000000011000010'
	

;		ワークエリア定義
;
;		BANK0	20h-7Fh
;
;		使用していないのもあります
;

hex0		equ			020h		;RF入力HEXデータ
hex1		equ			021h		;
hex2		equ			022h
hex3		equ			023h
colum		equ			028h		;現在の桁位置
cnt0		equ			029h		;時間待ちルーチン用
cnt1		equ			02ah
cnt2		equ			02bh
cnt3		equ			02ch
tmp0		equ			02dh		;雑用
tmp1		equ			02eh
bcdw0		equ			02fh		;BCD変換ルーチン用
bcdw1		equ			030h
cary1		equ			031h
cary2		equ			032h
cary3		equ			033h
shift		equ			034h		;送信ルーチンでのシフトカウンタ用
work1		equ			035h
work2		equ			036h
bsyc0		equ			037h
bsyc1		equ			038h
tcnt0		equ			039h
tcnt1		equ			03ah
tcnt2		equ			03bh		;表示基板への伝達フラグ
flg			equ			03ch		;エラー＆設定フラグ
band		equ			03dh		;プリスケーラ設定
gtime		equ			03eh		;ｹﾞｰﾄタイム設定
pscnt		equ			03fh		;プリスケーラ残カウント
hexw0		equ			040h		;HEXデータ演算用ワーク
hexw1		equ			041h
hexw2		equ			042h
hexw3		equ			043h
rhex0		equ			044h		;外部入力HEXデータ
rhex1		equ			045h
rhex2		equ			046h
rhex3		equ			047h
rflg		equ			048h
mode		equ			049h

;

			ORG			0h
			goto		init
			ORG			04h
			goto		int

			org			05h
			


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			PIC16F688　イニシャライズ			
;
;		CMCON0_REG
;			bit7	C2OUT	コンパレータ2出力ビット
;			bit6	C1OUT	コンパレータ１出力ﾋﾞｯﾄ
;			bit5	C2INV	コンパレータ2出力反転ビット
;			bit4	C1INV	コンパレータ１出力反転ビット
;			bit3	CIS		コンパレータ入力スイッチビット
;			bit2-0	CM		コンパレータモード	111	Off
;										入力はデジタル
;										他モードは使用しない
;
;		ANSEL_REG
;			bit7-0	ANS		アナログ選択ビット
;							1=アナログ入力
;							0=デジタルI/O
;
;		TRISA_REG	1=input mode,0=output mode
;			bit7=0	Unimplemented
;			bit6=0	Unimplemented
;			bit5=0	RA5	I/O	設定条件あり、コンフィグレーションワード参照
;			bit4=0	RA4	I/O　設定条件あり、　〃
;			bit3=1	RA3	Inputのみ
;			bit2=1	RA2	I/O	外部割込み入力
;			bit1=0	RA1	I/O
;			bit0=0	RA0	I/O
;
;		TRISC_REG	1=input mode,0=output mode
;			bit7=0	Unimplemented
;			bit6=0	Unimplemented
;			bit5=0	RC5	I/O
;			bit4=0	RC4	I/O
;			bit3=1	RC3	I/O
;			bit2=0	RC2	I/O
;			bit1=0	RC1	I/O
;			bit0=0	RC0	I/O
;
;		OPTION_REG
;			bit7=1	RAPU	POTRAプルアップOFF
;							0=enabled,1=disabled
;			bit6=1	INTEGE	INT割り込み信号エッジ↑
;							1=↑,0=↓
;			bit5=1	T0CS	TMR0クロックは外部
;							1=外部入力RA2,0=内部
;			bit4=0	T0SE	TMR0カウントエッジ↑
;							1=↓,0=↑,
;			bit3=0	PSA		プリスケーラ割当ビット
;							1=WDT,0=TMR0
;			bit2-0	PS		プリスケーラ分周比	000 1/2
;										001	1/4
;										010	1/8
;										011	1/16
;										100	1/32
;										101	1/64
;										110	1/128
;										111	1/256
;
;		INTCONレジスタ(#2)
;			bit7	GIE		全割込制御
;							1許可、0禁止
;			bit6	PEIE	周辺割込制御
;							1許可、0禁止
;			bit5	T0IE	タイマ0割込許可制御
;							1許可、0禁止
;			bit4	INTE	RA2外部割込許可制御
;							1許可、0禁止
;			bit3	RAIE	RAポート状態変化割込許可制御
;							1許可、0禁止	
;			bit2	T0IF	タイマ0割込みフラグ(#1)
;							1オーバーフロー、0オーバーフローなし
;			bit1	INTF	RA2外部割込みフラグ(#1)
;							1割込み発生、0割込み発生なし
;			bit0	RAIF	RAポート状態変化割込フラグ(#1)
;							1割込発生、0割込無
;
;							#1)ソフトウエアでリセット必要
;							#2)初期値=0なので、初期設定で0設定する必要は無い
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
init
			bcf			STATUS,RP0	;Bank0
			clrf		PORTA		;Init PORTA
			clrf		PORTC		;Init PORTC
			clrf		INTCON		;割込みOFF
			movlw		07h
			movwf		CMCON0		;コンパレータoff、アナログポート→デジタル
			bsf			STATUS,RP0	;バンク１に切替
			clrf		ANSEL		;デジタルI/O
			movlw		0e7H		;11100111b
			movwf		OPTION_REG	;プリスケーラ1/256にセット
			movlw		0ch			;00001100b
			movwf		TRISA		;RA2,3入力　RA0,1出力モード
			movlw		019h		;00011001b
			movwf		TRISC		;RC0,3,4入力 RC1,2,5出力モード
			bcf			STATUS,RP0	;バンク０に切替
			bcf			PORTA,1		;GATE1クローズ
			bcf			ADCON0,ADON	;ADコンバータOFF
			bsf			PORTA,0		;GATE2オープン
			bsf			PORTC,5		;DATA_H
			nop
			bsf			PORTC,2		;LED OFF
			
;			goto		main_dbg1
;			goto		main_dbg2
;			goto		main_dbg3
			
main
			call		get_mode	;各種モード確認
			call		fcount		;入力１　RFカウント
			call		rxs_data	;入力２　データ受信
			call		correct		;データ演算
			call		txs_data	;データ送信
			goto		main

;
;			割込み発生＝エラーストップ
;
int
			bcf			PORTC,2
			call		wait500m
			bsf			PORTC,2
			call		wait500m
			goto		int

;
;			実験用
;
;			455KHz=0006F158H
;			 10MHz=00989680H
;			  5MHZ=004C4B40H
;			  6MHz=005B8D80H
;			 25MHz=017D7840H
;			 30MHz=01C9C380H
;			 34MHz=0206CC80H
;

main_dbg1
			movlw		040h		;5MHz
			movwf		hex0
			movlw		04bh
			movwf		hex1
			movlw		04ch
			movwf		hex2
			clrf		hex3

			movlw		080h		;30MHz
			movwf		rhex0
			movlw		0c3h
			movwf		rhex1
			movlw		0c9h
			movwf		rhex2
			movlw		01h
			movwf		rhex3
			
			call		off_ext		;25MHz
			goto		main_dbg1

;
;			デバッグ用
;
;			外部データをそのままデータ出力へ送信
;
main_dbg3
;			call		get_mode
			call		rxs_data

			movf		rhex0,W
			movwf		hex0
			
			movf		rhex1,W
			movwf		hex1
			
			movf		rhex2,W
			movwf		hex2
			
			movf		rhex3,W
			movwf		hex3
			
			movf		rflg,W
			movwf		flg

			call		txs_data	;データ送信
			goto		main_dbg3
			




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			動作モードセット(100ms+プリスケーラON、1s+プリスケーラON）
;
;		プリスケーラ		1/256固定
;		ゲートタイムSW	ON(RA3=0) 1秒、OFF(RA3=1)　0.1秒
;		モード設定SW	ON(RC3=0)　２入力演算モード、OFF(RC3=1)　RFカウンタモード
;
;		使用ワーク
;				狭帯域(1/1)モード	band=0	0000B
;				広帯域(1/8)モード	band=1	0001B
;				広帯域(1/16)モード	band=2	0010B
;				広帯域(1/256)モード	band=4	0100B
;				0.1秒ゲートタイム		gtime=0
;				１秒ゲートタイム		gtime=1
;				RFカウンタモード		mode=0
;				外部入力オフセットモード	mode=1
;				固定値オフセットモード	mode=
;				2桁表示指令		flg=xxxxx001
;				4桁表示指令		flg=xxxxx011
;				6桁表示指令		flg=xxxxx101
;				8桁表示指令		flg=xxxxx111
;				ドット表示指令		flg=x000xxxx　表示なし
;									bit4=1	2,5桁点燈
;									bit5=1	3,6桁点燈
;									bit6=1	4,7桁点燈
;				オーバーフロー		flg=1xxxxxxx
;				
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

get_mode
			clrf		flg
			clrf		band
			clrf		mode
			bsf			PORTC,0		;
			nop
			btfss		PORTC,3		;オフセットSW,ON=0
			bsf			mode,0		;mode=1

ps_on256	;プリスケーラ　ON(1/256)
			bsf			band,2		;256倍モード(BAND=4)

ckgtm		;ｹﾞｰﾄタイム　設定
			btfss		PORTA,3		;ゲートタイム設定SWチェック
			goto		ckg00		;RA3=0(SW_ON)
			clrf		gtime		;RA3=1(SW_OFF)set 0.1s
			movlw		01dh		;00011101b
        	movwf		flg			;6桁表示、2,5桁ドット表示指定
      		
			return
ckg00		bsf			gtime,0		;RA3=0(SW_ON) set 1s
			movlw		04fh		;01001111b
        	movwf		flg			;8桁表示、4,7桁ドット表示指定
			return		

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
;			入力パルス　カウントサブルーチン
;
;		ゲート1制御		RA1=0,GATE1_OUTPUT=1(ゲート1クローズ)
;					RA1=1,GATE1_OUTPUT=x(ゲート1オープン)
;		ゲート2制御		RA0=0,GATE2_OUTPUT=1(ゲート2クローズ)
;					RA0=1,GATE2_OUTPUT=x(ゲート2オープン)
;					#注意　G2O=1(G2クローズ）,RA2=0が同時設定不可
;
;		入力ポート		RA2
;		ゲート解放時間	1s、100ms
;		出力データ		hex1
;					hex2
;					hex3
;
;		ゲートSW		H=100ms、L=1s
;
;		使用ワーク		;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fcount
;			カウント準備
			bcf			PORTA,1		;GATE1=OFF,G1O=1
			bsf			PORTA,0		;GATE2=ON,G2O=0
			clrf		hex0		;データエリアリセット
			clrf		hex1
			clrf		hex2
			clrf		hex3
			bcf			flg,7		;OverFlowフラグをクリア
			clrf		TMR0		;タイマー０カウンタ及びプリスケーラリセット
			bcf			INTCON,T0IF	;T0IFフラグをリセット
			bcf			STATUS,C	;キャリーフラグをリセット
			btfss		gtime,0		;gtime=1 then 1s 
			goto		gate100m	;gtime=0 then 100ms
			goto		gate1s		;
;
;			ゲートタイム100ms=250000cycles
;
gate100m
			bcf			PORTC,2		;LED ON
			nop
			bsf			PORTA,1		;GATE1オープン
			call		count100m	;249998cycles
			bcf			PORTA,1		;GATE1クローズ
			bsf			PORTC,2		;LED OFF
			call		postcnt
			call		readps		;プリスケーラ読み出し
			nop
			nop
			return

;
;			ゲートタイム1sec=2500000cycles
;
gate1s
			bcf			PORTC,2		;LED ON
			nop
			bsf			PORTA,1		;GATE1_OPEN
			call		count100m	;249998cycle-01
			nop
			nop
			call		count100m	;249998cycle-02
			nop
			nop
			call		count100m	;249998cycle-03
			nop
			nop
			call		count100m	;249998cycle-04
			nop
			nop
			call		count100m	;249998cycle-05
			nop
			nop
			call		count100m	;249998cycle-06
			nop
			nop
			call		count100m	;249998cycle-07
			nop
			nop
			call		count100m	;249998cycle-08
			nop
			nop
			call		count100m	;249998cycle-09
			nop
			nop
			call		count100m	;249998cycle-10
			bcf			PORTA,1		;GATE1_CLOSE
			bsf			PORTC,2		;LED OFF
			call		postcnt
			call		readps		;プリスケーラ読み出し
			return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		タイマー０への入力パルス　カウントループ
;
;		ゲートオン、オフの時間も考慮し、100ms間の入力パルスカウントとなる様に設定する事
;		f=10MHZ only	249998cycles(call&return命令含む)
;
;		入力		無し
;
;		出力		hex1	下位8ビット(TMR0)
;				hex2	中位8ビット
;				hex3	上位8ビット
;
;	INTCONレジスタ
;		bit7	GIE		全割込制御
;						1許可、0禁止
;		bit6	PEIE	周辺割込制御
;						1許可、0禁止
;		bit5	T0IE	タイマ0割込許可制御
;						1許可、0禁止
;		bit4	INTE	RA2外部割込許可制御
;						1許可、0禁止
;		bit3	RAIE	RAポート状態変化割込許可制御
;						1許可、0禁止	
;		bit2	T0IF	タイマ0割込みフラグ(#1)
;						1オーバーフロー、0オーバーフローなし
;		bit1	INTF	RA2外部割込みフラグ(#1)
;						1割込み発生、0割込み発生なし
;		bit0	RAIF	RAポート状態変化割込フラグ(#1)
;						1割込発生、0割込無
;
;		#1)ソフトウエアでリセット必要
;
;		使用ワーク		tcnt1	外周カウンタ　
;					tcnt2	内周カウンタ　
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



count100m							;100ms=100000us=250000cycles
			movlw		08dh		;外周カウンタ141
			movwf		tcnt1

cnt101m		movlw		088H		;内周カウンタ=136
			movwf		tcnt2		;
;
;	タイマ0のオーバーフローした時の桁上げカウント処理
;	下位(HEX1)8ビットはゲートクローズ後、TMR0から読み込みすること
;

cnt102m
			btfss		INTCON,T0IF	;タイマ0オーバーフラグチェック
			goto		if_off		;T0IF=0 then 
			bcf			INTCON,T0IF	;T0IFフラグをリセット
			movlw		01h			;add,sub命令でなければキャリー使えない
			goto		if_on		;T0IF=1なので繰上げ処理へ
if_off		nop						;時間差調整
			nop						;　〃
			movlw		0h			;
if_on		addwf		hex2,F		;hex2=hex2+W_REG(=1or0)
			rlf			hex2,W		;キャリービットがWの0ビット目に入る
			andlw		01h			;キャリー以外をマスク
			addwf		hex3,F		;hex3=hex3+Carry(Wreg)
									;cnt102mからここまで11cycles
;			内周ループカウンタ　13cycles/loop
			decfsz		tcnt2,F		;内周ループ終了か？
			goto		cnt102m		;
			nop						;13*136=1768c/s
									;
;			外周ループカウンタ　13*xxcycles/loop
cnt103m		decfsz		tcnt1,F		;(13*tcnt2+2+3)*tcnt1+2
			goto		cnt101m		;(1773)*141+2-1=2499994cycles
									;CALLとRETURNで4cycles
			return					;合計249998cycles
									;

;
;
;		取りこぼしビットチェック
;
;		最後のT0IFフラグチェック後からゲートクローズのまでの時間に
;		フラグが変化したかをチェックし、必要なら補正処理
;
;		呼出条件
;		ゲートクローズ直後
;

postcnt
			movf		TMR0,W		;下桁を保存
			movwf		hex1

			btfss		INTCON,T0IF	;タイマ0オーバーフラグチェック
			return					;T0IF=0なので終了 
			;T0IF=1なので繰上げ処理
			bcf			INTCON,T0IF	;T0IFフラグをリセット
			movlw		01h			;add,sub命令でなければキャリー使えない
			addwf		hex2,F		;hex2=hex2+W_REG(=1or0)
			rlf			hex2,W		;キャリービットがWの0ビット目に入る
			andlw		01h			;キャリー以外をマスク
			addwf		hex3,F		;hex3=hex3+Carry(Wreg)
			return					;補正終了
			

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		プリスケーラ読み出し
;
;		実行条件	GATE1がクローズされている事
;				GATE2はオープンのままである事
;				RA2(TMR0)が入力設定のままである事
;				以上の条件により、G2O=0となっている
;
;		出力		hex0
;				TMR0の内容は+1される
;
;		使用ワーク	pscnt
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

readps
			clrf		pscnt		;プリスケーラ残カウント数ワーク
rdps1		;パルス注入、カウントアップループ
			nop
			bcf			PORTA,0		;G2O=1(G2クローズ）
			nop
			bsf			PORTA,0		;G2O=0(G2オープン)
			nop
			decf		pscnt,F
			movf		hex1,W
			subwf		TMR0,W		;W=TMR0-W
			btfsc		STATUS,Z
			goto		rdps1		;W=0(TMR0=HEX1)then　loop
			;TMR0が1つカウントアップした、＝プリスケーラが満タンになった
			movf		pscnt,W
			movwf		hex0		;プリスケーラ残カウント数をhex0に保存
			return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		計測値の補正　
;
;				0.1秒ゲートタイム		gtime=0
;				１秒ゲートタイム		gtime=1
;				オフセットOFF		mode=0
;				オフセットON			mode=1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

correct
;			モード確認
			btfss		mode,0
			goto		cor1		;RF入力モード処理
			btfss		gtime,0		;外部オフセットモード処理
			call		x10			;RF入力ゲートタイム補正
			call		off_ext		;オフセット補正
			return

;			ゲートタイム確認
cor1		btfsc		gtime,0		;
			return

;
;			32ビット10倍演算
;
;		入力	hex3-0	32ビット
;		出力　hex3-0	
;
;		使用ワーク	hexw0-3	4バイト
;

x10
;			データ保存
			movf		hex0,W
			movwf		hexw0
			movf		hex1,W
			movwf		hexw1
			movf		hex2,W
			movwf		hexw2
			movf		hex3,W
			movwf		hexw3			

;			32ビットデータを8倍
			bcf			STATUS,C	;
			rlf			hex0,F		;2倍を3回実行する
			rlf			hex1,F
			rlf			hex2,F
			rlf			hex3,F
			bcf			STATUS,C	;
			rlf			hex0,F
			rlf			hex1,F
			rlf			hex2,F
			rlf			hex3,F
			bcf			STATUS,C
			rlf			hex0,F
			rlf			hex1,F
			rlf			hex2,F
			rlf			hex3,F

			call		add32b		;元データを加算
			call		add32b


			btfsc		STATUS,C	;オーバーフローか？
			bsf			flg,7		;オーバーフローフラグをON
			bcf			flg,7		;オーバーフローフラグをOFF
			return


;			32ビットバイナリ加算
;
;		(hex0-3) = (hex0-3) + (hexw0-3)
;

add32b
			movf		hexw0,W		;hex0=hex0+hexw0
			addwf		hex0,F
			movlw		01h
			btfss		STATUS,C	;if c=1 then hex1=hex1+1	
			goto		adb1
			addwf		hex1,F
			btfsc		STATUS,C	;if c=1 then hex2=hex2+1
			addwf		hex2,F
			btfsc		STATUS,C	;if c=1 then hex3=hex3+1
			addwf		hex3,F
			
adb1		movf		hexw1,W
			addwf		hex1,F
			movlw		01h
			btfsc		STATUS,C
			addwf		hex2,F
			btfsc		STATUS,C
			addwf		hex3,F
			
adb2		movf		hexw2,W
			addwf		hex2,F
			movlw		01h
			btfsc		STATUS,C
			addwf		hex3,F
			movf		hexw3,W
			addwf		hex3,F
			retlw		0h


;
;
;		外部データによるオフセット減算
;
;		減算エラーチェックはしていません
;
;		hex(0-3)=rhex(0-3)-hex(0-3)
;
;


off_ext
			movf		hex0,W		;hex(0-3)とrhex(0-3)を入換え
			movwf		hexw0
			movf		rhex0,W
			movwf		hex0
			
			movf		hex1,W
			movwf		hexw1
			movf		rhex1,W
			movwf		hex1
			
			movf		hex2,W
			movwf		hexw2
			movf		rhex2,W
			movwf		hex2
			
			movf		hex3,W
			movwf		hexw3
			movf		rhex3,W
			movwf		hex3
			
			goto		sub32b

;
;		455KHz減算
;
;		hex(0-3)=hex(0-3)-455KHZ
;
;		W=0で減算成功
;		W=1でエラー発生
;

off_455k
			movf		hex3,W		;４バイト目のデータ存在チェック
			andlw		0ffh
			btfss		STATUS,Z
			goto		loc01
			
			movf		hex2,W		;３バイト目上位４ビットのデータ存在チェック
			movwf		hexw2
			andlw		0f0h
			btfss		STATUS,Z
			goto		loc01
			
			swapf		hexw2,W		;３バイト目下位４ビットを上位４ビットへ
			andlw		0f0h
			movwf		hexw2

			movf		hex1,W		;500KHz=7a120h
			andlw		0f0h		;07a100h以下はエラーと判定
			movwf		hexw1
			swapf		hexw1,W
			iorwf		hexw2,W
			sublw		07ah
			btfsc		STATUS,C
			retlw		01h			;減算エラー･リターン
			
loc01								;減算開始
			movlw		058h		;455KHz=455000HZ
			movwf		hexw0		;=0006f158h
			movlw		0f1h
			movwf		hexw1
			movlw		06h
			movwf		hexw2
			clrf		hexw3

;
;
;			32ビットバイナリ減算
;
;		(hex0-3) = (hex0-3) - (hexw0-3)
;

sub32b
			movf		hexw0,W		;hex0=hex0-hexw0
			subwf		hex0,F
			movlw		01h
			btfsc		STATUS,C	;if c=0 then hex1=hex1-1
			goto		sbb1
			subwf		hex1,F
			btfss		STATUS,C	;if c=0 then hex2=hex2-1
			subwf		hex2,F
			btfss		STATUS,C	;if c=0 then hex3=hex3-1
			subwf		hex3,F

sbb1		movf		hexw1,W
			subwf		hex1,F
			movlw		01h
			btfss		STATUS,C
			subwf		hex2,F
			btfss		STATUS,C
			subwf		hex3,F

sbb2		movf		hexw2,W
			subwf		hex2,F
			movlw		01h
			btfss		STATUS,C
			subwf		hex3,F
			movf		hexw3,W
			subwf		hex3,F
			retlw		0h


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			シリアルデータ、ハンドシェイク受信サブルーチン(50us版)
;
;		出力バッファ		rhex0	16進バイナリ32ビット
;					rhex1
;					rhex2
;					rhex3
;					rflg	制御フラグ
;		ステータス		W=0	受信成功
;					W=1	受信失敗
;					W=2　送信未準備
;
;
;		データ線	RDATA	RC0		1ビット幅 = 50us
;		制御線	RRX		RC1		アクティブH
;
;		使用ワーク	bsyc0,shift
;
;	TX format
;
;	通常(H)→準備OK(L)待機→　スタートビット(L)→データビット→ストップビット(H)→通常(H)
;
;						50us		各50us	50us
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


rxs_data
;
;		受信チェック
;
;		RC0ポートRDATA線兼RTX線(Lにて送信準備OK）
;		RC1ポートRRX線制御
;
		btfss		PORTC,0			;TX 受信チェック
		goto		rsst
		retlw		01h				;送信未準備
		
;
;		受信可能ステータス送出
;
;		RC1	RRX送出、アクティブH
;		RC0	RDATA受信
;
rsst	movlw		028h			;40ビット分
		movwf		shift			;シフトカウンタ
		bsf			PORTC,1			;RRX_ON送出、受信準備OK
		call		wait25u
		btfss		PORTC,0			;スタートビット(0)確認
		goto		rsloop			;データ受信開始
		call		wait25u
		bcf			PORTC,1			;RRX_OFF　送信
		retlw		01h				;受信失敗
		

;
;		40bitシリアルデータ受信開始
;
;		１ループに付き、50us間隔でデータ取込
;

rsloop
		call		d10u
		call		d10u
		call		d10u
		call		d10u
rslp0	rlf			rflg,F			;
		rlf			rhex0,F			;全ビット左シフト
		rlf			rhex1,F			;
		rlf			rhex2,F
		rlf			rhex3,F			;
		bcf			rflg,0			;最下位に0をセット
		btfsc		PORTC,0			;入力データを取得
		bsf			rflg,0			;最下位に1にセット
		nop
		movlw		04h				;時間調整
		movwf		bsyc0			;2+3*3+2=13cycles
rslp1	decfsz		bsyc0,F
		goto		rslp1

		decfsz		shift,F			;40ビット受信完了か
		GOTO		rsloop			;40+(9+3+13)*0.4=50usec

		call		wait50u			;
		btfss		PORTC,0			;ストップビット確認
		goto		rslp2
		goto		rslp3
rslp2	call		wait50u
		bcf			PORTC,1			;RX OFF
		
		bcf			PORTC,2			;error
		call		wait100m		;
		bsf			PORTC,2
		
		retlw		03h				;受信失敗

rslp3	call		wait50u
		bcf			PORTC,1			;RX OFF
		retlw		0h				;受信完了







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			シリアルデータ送信サブルーチン(ビット幅50us版)
;
;		入力		hex0	16進バイナリ40ビット
;				hex1
;				hex2
;				hex3
;				flg
;		出力		W=0	送信成功
;				W=1	送信失敗
;
;		データ線	DATA(送信)	RC5		1bit width = 100us
;		制御線	RX（受信）		RC4	=0	受信不可
;							RC4	=1	受信可
;				SW2(HET)	RC3 =0	HET ON
;							RC3 =1	HET OFF
;
;		使用ワーク	bsyc0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

txs_data
;
;		送信準備OK
;
;		DATAとRXラインを使用して送信タイミングを合わせる
;

		bcf			PORTC,5		;TX_ON(データラインと兼用）

;
;		応答待ち
;
stbs1
		call		d10u
		btfss		PORTC,4		;RX line check
		goto		stbs1
;
;		送信開始
;
;		割込み使用の場合はここからスタート
;

txs_start
		bcf			PORTC,5		;スタートビット　セット
		call		wait50u		;　
		movf		hex3,W		;DATAビット
		call		txs_byte
		movf		hex2,W
		call		txs_byte
		movf		hex1,W
		call		txs_byte
		movf		hex0,W
		call		txs_byte
		movf		flg,W
		call		txs_byte

;
;		送信終了
;

		bsf			PORTC,5		;ストップビット　セット
		call		wait50u
		retlw		0h			;送信終了

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		１バイト送信サブルーチン
;
;		上位ビットから送信します
;
;		1ビット幅は概ね50usで送出
;
;		使用ワーク	shift
;				work1
;				bsyc0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


								;コール以前に3cyles
txs_byte
		movwf		tmp0		;送信バイトをワークへ保存
		movlw		08H			;
		movwf		shift		;左シフトカウンタ

txsb0							;tx loop
		rlf			tmp0,F		;左シフトで最上位ビットはキャリーへ
		btfss		STATUS,C	;キャリービット　チェック
		GOTO		sends0
		nop
sends1	bsf			PORTC,5		;DATA 1 send
		goto		txsb1
sends0	bcf			PORTC,5		;DATA 0 send
		nop
		nop
txsb1	call		d10u		;40us delay
		call		d10u
		call		d10u
		call		d10u
		
		movlw		04h			;時間調整
		movwf		bsyc0		;2+3*3+2=13cycles/5.2us
txsb2	decfsz		bsyc0,F
		goto		txsb2
		
		decfsz		shift,F		;(shift-1)=0 then return 
		goto		txsb0		;(7+3）+13=23cycles/9.2us
		return					;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン
;
;		clock = 10MHz(0.1usec)
;		use work reg = cnt0,cnt1,cnt2,cnt3
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u							;呼び出しも含めて、100usec
									;call is 2cycles
			movlw		08h			;1
			movwf		cnt2		;1
w1u			nop						;
			nop						;
			call		d10u		;10*8=80usec(ここだけ命令ステップを数えない）
			decfsz		cnt2,F		;5*8+4=44cycles
			goto		w1u
			return					;2+44+4=50cycles=20usec

wait50u								;呼び出しも含めて、50usec
									;call is 2cycles
			movlw		04h			;1
			movwf		cnt2		;1
w05u		nop						;
			call		d10u		;10*4=40usec(ここだけ命令ステップを数えない）
			decfsz		cnt2,F		;4*4+3=19cycles
			goto		w05u
			return					;2+19+4=25cycles=10usec

wait25u
			call		d10u
			call		d10u
			
			movlw		02h			;1
			movwf		cnt2		;1
w02u		decfsz		cnt2,F		;2+3+2+1=8cycles
			goto		w02u
			return					;2+8+2=12cycles=4.8usec

wait2m
			movlw		02h
			movwf		cnt2
w2m			call		d1m
			decfsz		cnt2,F
			goto		w2m
			return

wait5m								; 5msec delay
			movlw		05h
			movwf		cnt2
w5m			call		d1m
			decfsz		cnt2,F
			goto		w5m
			return

wait10m								; 10msec delay
			movlw		d'10'
			movwf		cnt2
w10m		call		d1m
			decfsz		cnt2,F
			goto		w10m
			return

wait20m								; 20msec delay
			movlw		d'20'
			movwf		cnt2
w20m		call		d1m
			decfsz		cnt2,F
			goto		w20m
			return

wait50m								; 50msec delay
			movlw		d'50'
			movwf		cnt2
w50m		call		d1m
			decfsz		cnt2,F
			goto		w50m
			return

wait100m							; 100msec delay
			movlw		d'100'
			movwf		cnt2
w100m		call		d1m
			decfsz		cnt2,F
			goto		w100m
			return

wait500m							; 500msec delay
			movlw		05h
			movwf		cnt3
w500m		call		wait100m
			decfsz		cnt3,F
			goto		w500m
			return

wait1s								; 1sec delay
			movlw		d'10'
			movwf		cnt3
w1s			call		wait100m
			decfsz		cnt3,F
			goto		w1s
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1msec Base delay 
;
;		clock = 10MHz(0.1usec)
;		1cycle = 0.4usec
;		1msec = 0.4usec * 2500cycles
;
;		# goto and call and return - 2cycles
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d1m
			movlw		02h
			movwf		cnt0		;loop0 2times
d1m0		movlw		d'249'		;
			movwf		cnt1		;loop1 249times

d1m1		nop						;5cycles*cnt1
			nop						;5*249=1245
			decfsz		cnt1,F		;
			goto		d1m1		;

			decfsz		cnt0,F		;(d1m1-1+3)*cnt0
			goto		d1m0		;(1245-1+5)*2=2498cycles
			return					;other=3cycles
									;Total 2501*0.4usec=1msec

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10usec Base delay
;			呼び出しも含めて、10usecとなる。
;
;		clock = 10MHZ(0.1usec)
;		1cycle = 0.4usec
;		10usec = 0.4usec * 25cycles
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

									;"call" inst = 2cycles
d10u
			movlw		05h			;1
			movwf		cnt0		;1
d10u0		nop						;4*4+3=19
			decfsz		cnt0,F		;
			goto		d10u0		;
			return					;2+1+1+19+2=25cycles
;


;
;			データ転送デバッグ用
;

main_dbg2
			clrf		hex0
			clrf		hex1
			clrf		hex2
			clrf		hex3
			movlw		07h
			movwf		flg
			bcf			PORTC,2		;LED ON
			call		txs_data
			bsf			PORTC,2		;LED OFF
			call		wait1s

			movlw		0c7h
			movwf		hex0
			movlw		08ah
			movwf		hex1
			movlw		0a9h
			movwf		hex2		;11111111
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		08eh
			movwf		hex0
			movlw		015h
			movwf		hex1
			movlw		053h
			movwf		hex2
			movlw		01h
			movwf		hex3		;22222222
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		055h
			movwf		hex0
			movlw		0a0h
			movwf		hex1
			movlw		0fch
			movwf		hex2
			movlw		01h
			movwf		hex3		;33333333
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		01ch
			movwf		hex0
			movlw		02bh
			movwf		hex1
			movlw		0a6h
			movwf		hex2
			movlw		02h
			movwf		hex3		;44444444
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		0e3h
			movwf		hex0
			movlw		0b5h
			movwf		hex1
			movlw		04fh
			movwf		hex2
			movlw		03h
			movwf		hex3		;55555555
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		0aah
			movwf		hex0
			movlw		040h
			movwf		hex1
			movlw		0f9h
			movwf		hex2
			movlw		03h
			movwf		hex3		;66666666
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		071h
			movwf		hex0
			movlw		0cbh
			movwf		hex1
			movlw		0a2h
			movwf		hex2
			movlw		04h
			movwf		hex3		;77777777
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		038h
			movwf		hex0
			movlw		056h
			movwf		hex1
			movlw		04ch
			movwf		hex2
			movlw		05h
			movwf		hex3		;88888888
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		0ffh
			movwf		hex0
			movlw		0e0h
			movwf		hex1
			movlw		0f5h
			movwf		hex2
			movlw		05h
			movwf		hex3		;99999999
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		04eh
			movwf		hex0
			movlw		061h
			movwf		hex1
			movlw		0bch
			movwf		hex2
			movlw		0h
			movwf		hex3		;12345678
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s

			movlw		0b1h
			movwf		hex0
			movlw		07fh
			movwf		hex1
			movlw		039h
			movwf		hex2
			movlw		05h
			movwf		hex3		;87654321
			movlw		07h
			movwf		flg
			bcf			PORTC,2
			call		txs_data
			bsf			PORTC,2
			call		wait1s
			goto		main_dbg2





			END
			
