;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		ＰＩＣ１６Ｆ１７０５　ＢＡＳＩＣ　０３
;
;							2018年02月	Ver1.0	JA0QON
;
;	基本的なサブルーチンを設定済み
;
;
;	ディスプレイ
;		DFR0090 SPI 8桁7セグLEDモジュール
;		デフォルト ポート
;		RC3=DATA
;		RC4=LATCH
;		RC5=CLOCK
;		ポート変更はマクロ定義で行う
;
;		PIC16F1705 32MHZ 内部発振
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		LIST	P=PIC16F1705
		INCLUDE	P16F1705.INC

;
;CONFIGURATION WORD 1(ADDRESS:8007H)
;					設定
;bit13		FCMEN	0	Fail-Safe Clock Monitor
;						1=有効,0=無効
;bit12		IESO	0	内部･外部切替スイッチモード
;						1=有効,0=無効
;bit11		CLKOUTEN 1	クロックアウトイネーブルビット
;						1=無効　RA4I/O使用可
;						0=有効　FoscがCLKPUTピンに出力される
;bit10-9	BOREN	00	ブラウンアウト設定
;						11=有効
;						10=スリープ時以外有効
;			___			00=無効
;bit8		CPD		1	データメモリプロテクション
;			__			1=無効,0=有効
;bit7		CP		1	プログラムメモリプロテクション　
;						1=無効,0=有効
;bit6		MCLRE	0	RA3/MCLRピン選択ビット
;			_____		1=MCLR有効,0=RA3有効(Digital input)
;bit5		PWRTE	0	power_up timer　使います。
;						1=無効,0=有効
;bit4-3		WDTE	00	Watchdog Timer
;						11=有効
;						10=ランニング中に有効、スリープ中は無効
;						01=レジスタによるコントロール
;						00=無効
;bit2-0		FOSC	010	発振器選択ビット
;						111=ECH:外部クロック入力（4-32MHZ)、RA4I/O可
;						110=ECM:外部クロック入力（0.5-4MHZ)、RA4I/O可
;						101=ECL:外部クロック入力（0-0.5MHZ)、RA4I/O可
;						100=INTOSC:内部発振、RA4-RA5I/O可
;						011=EXTRC:外部RC発振、RA4I/O可、RA5不可
;						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  1  0  0  1  1  0  0  0  0  1  0  0
;
;
	__CONFIG _CONFIG1,	B'0000100110000100'
;
;CONFIGURATION WORD 2(ADDRESS:8008H)マニュアル52ページ
;					設定
;bit13		LVP		0	低電圧プログラミング設定
;						1=有効
;			_____		0=無効、高電圧必要
;bit12		DEBUG	1	インサーキット･デバッガ モード設定
;						1=無効
;						0=有効、RA0-1をデバッガに使用
;bit11				0	Unimplemented
;bit10		BORV	0	ブラウンアウト･リセット電圧選択ビット（Vbor参照)
;						1=低電圧で動作
;						0=高電圧で動作
;bit9		STVREN	0	スタック･オーバーフロー･リセット設定
;						1=有効
;						0=無効
;bit8		PLLEN	0	PLL設定
;						1=4xPLL有効
;						0=4xPLL無効
;bit7       ZCDDIS  1   ZCDディセーブルビット
;                       1=ZCDを無効にする、ZCDCONで有効可
;                       0=ZCDを常に有効にする
;bit6-3					Unimplemented:read as 1
;bit2		PPS1WAY 0   PPSLOCKビット単方向セット･イネーブルビット
;                       1=ロック解除シーケンスを実行後に1度だけ解除できる
;                       0=ロック解除シーケンスを実行すると何度でも解除できる
;bit1-0		WRT		11	フラッシュメモリ プロテクション設定
;						11=無効
;						10=0h-1FFh有効、200H?1FFFHはPMCONで制御可
;						01=0h-FFFh有効、1000H?1FFFHはPMCONで制御可
;						00=0h-1FFFh有効、PMCON制御不可
;
;bit	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
;data    0  0  0  1  0  0  0  0  1  1  1  1  1  0  1  1
;
;
	__CONFIG _CONFIG2,	B'0001000011111011'



;		ワークエリア定義
;
;		BANK0	20h-7Fh
;
;		使用していないのもあります
;

;ウエイトルーチン内専用ワーク
cnt0		equ		020H		;時間待ちルーチン用専用ワーク
cnt1		equ		021H
cnt2		equ		022H
cnt3		equ		023H
;汎用ローカルワーク
tmp0		equ		024H		;サブルーチン内限定汎用ワーク
tmp1		equ		025H		;移動した場合、破壊されること有
tmp2		equ		026H
tmp3		equ		027H
;汎用広域ワーク
wrk0		equ		028H        ;演算用広域汎用ワーク
wrk1		equ		029H
wrk2		equ		02AH
wrk3		equ		02BH
BLK			equ		02CH		;ゼロブランキング制御フラグ
colum		equ		02DH		;現在の桁位置
colw0		equ		02EH		;桁位置処理ワーク
colw1		equ		02FH		;
;演算用ワーク
hex0		equ		030H		;
hex1		equ		031H		;
hex2		equ		032H		;
hex3		equ		033H		;
hexw0		equ		034H		;
hexw1		equ		035H		;
hexw2		equ		036H		;
hexw3		equ		037H		;
div0		equ		038H		;
div1		equ		039H		;
div2		equ		03AH		;
div3		equ		03BH		;
divw0		equ		03CH		;
divw1		equ		03DH		;
divw2		equ		03EH		;
divw3		equ		03FH		;
hexd		equ		040H		;
;可変ウエイト用ワーク
delay0		equ		041H
delay1		equ		042H
;機能専用広域ワーク
FLG			equ		043H		;8桁7セグLED表示設定フラグ
MODE		equ		044H		;実行モード設定フラグ
DSPM		equ		045H		;ディスプレイモード スイッチフラグ
;BCD用広域ワーク
digit12     equ     050H        ;BCD変換出力1，2桁
digit34     equ     051H		;BCD変換出力3，4桁
digit56     equ     052H        ;BCD変換出力5，6桁
digit78     equ     053H        ;BCD変換出力7，8桁
digit9A     equ     054H        ;BCD変換出力9，10桁
bcdw0		equ		055H		;BCD補正処理ワーク
bcdw1		equ		056H
shift		equ		057H
;8桁7セグLED専用広域ワーク
DBUF0		equ		058H		;SPI送信データ編集用バッファ
DBUF1		equ		059H
DBUF2		equ		05AH
DBUF3		equ		05BH
DBUF4		equ		05CH
DBUF5		equ		05DH
DBUF6		equ		05EH
DBUF7		equ		05FH
;ロータリーエンコーダ専用ワーク
REDAT       equ     060h        ;ロータリーエンコーダ・ビットデータ
RESP0       equ     061h        ;変化ステップ量 下位バイト
RESP1		equ		062h		;
RESP2		equ		063h		;
rew0        equ     064h        ;専用ワーク
rew1        equ     065h        ;専用ワーク
;メインループ用広域ワーク
FDA0        equ     066H		;32ビット基本動作用
FDA1        equ     067H		;
FDA2		equ     068H		;
FDA3		equ     069H		;
FDB0		equ		06AH		;32ビット副動作用
FDB1		equ		06BH		;
FDB2		equ		06CH		;
FDB3		equ		06EH		;

;SPIポート定義
SPI_DATH	MACRO
			movlb	02H
			bsf		LATC,3		;DATA PORT=1
			clrf	BSR
			ENDM
SPI_DATL	MACRO
			movlb	02H
			bcf		LATC,3		;DATA PORT=0
			clrf	BSR
			ENDM
SPI_LATH	MACRO
			movlb	02H
			bsf		LATC,4		;LATCH PORT=1
			clrf	BSR
			ENDM
SPI_LATL	MACRO
			movlb	02H
			bcf		LATC,4		;LATCH PORT=0
			clrf	BSR
			ENDM
SPI_CLKH	MACRO
			movlb	02H
			bsf		LATC,5		;CLOCK PORT=1
			clrf	BSR
			ENDM
SPI_CLKL	MACRO
			movlb	02H
			bcf		LATC,5		;CLOCK PORT=0
			clrf	BSR
			ENDM


;
			ORG		0h			;リセットベクタ
			goto	init
			ORG		04h			;割り込みベクタ

;
;		割込み処理ルーチン
;
;		割込み発生から割込みベクタまで3サイクル程度（同期割込み）
;		FSRxはコアレジスタなので、自動で PUSH-POPされる
;		よって、割り込み終了後、元の設定値に戻る
;
INT
;
INTOUT
;
			retfie				;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			PIC16F1705　イニシャライズ
;
;		OSCCON(BANK1　099H) 
;			bit7	SPLLEN	ソフトウエアPLL設定ビット
;							1 = 4xPLL有効
;							0 = 4xPLL無効(リセット後)
;			＊コンフィグレーションワードPLLEN=1の時、この設定は無視される。
;			bit6-3	IRCF	内部発振器クロック選択ビット
;							000x = 31KHZ LF
;							0010 = 31.25KHZ MF
;							0011 = 31.25KHZ HF
;							0100 = 62.5KHZ MF
;							0101 = 125KHZ MF
;							0110 = 250KHZ MF
;							0111 = 500KHZ MF（デフォルト）
;							1000 = 125kHZ HF
;							1001 = 250kHZ HF
;							1010 = 500kHZ HF
;							1011 = 1MHZ HF
;							1100 = 2MHZ HF
;							1101 = 4MHZ HF
;							1110 = 8MHZ or 32MHZ HF
;							1111 = 16MHZ HF
;			bit2			Unimplemented
;			bit1-0	SCS		システムクロック選択ビット
;							1x = 内部発振器
;							01 = タイマ1発振器
;							00 = FOSCで指定された発振器(リセット後)
;			(注)詳細はマニュアルあるいは当局HP内解説を参照
;							HF=HFINTOSC（16MHZ)
;							MF=MFINTOSC(500KHZ)
;							LF=LFINTOSC(32KHZ)
;
;
;			32MHZ内部発振設定
;		コンフィグレーションワード1		FOSC=100
;		OSCCON				SCS=00
;		OSCCON				IRCF=1110
;		OSCCON				SPLLEN=1(#1)
;		コンフィグレーションワード2		PLLEN=1(#1)
;						(#1)設定はどちらかでOKだが、PLLEN=1とすると、
;							OSCCONのSPLLEN=0の設定は無効となる。
;							また、8MHZのHFINTOSCは選択の余地が無い。
;
;		PORTA(BANK0　00CH）
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	デジタルI/O、アナログ入力
;			bit3	RA3		デジタルInputのみ
;			bit2	RA2-1	デジタルI/O、アナログ入力
;			bit0	RA0		デジタル･アナログI/O,DAコンバータ出力
;
;		PORTC(BANK0　00EH）
;			bit7-6	Unimplemented(read=0)
;			bit5-0	RC5-0	デジタルI/O、アナログ入力
;
;		TRISA(BANK1　08CH)
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	1=入力、0=出力
;			bit3	RA3		常に1
;			bit2	RA2-0	1=入力、0=出力
;
;		TRISC(BANK1　08EH)
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-0	1=入力、0=出力
;
;		LATA(BANK2　10CH)　データラッチレジスタ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	出力データ保持
;			bit3	Unimplemented(read=0)
;			bit2	RA2-0	出力データ保持
;		（このラッチデータはTRISAレジスタ設定で各ピンに反映される）
;
;		LATC(BANK2　10EH)　データラッチレジスタ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RC5-0	出力データ保持
;		（このラッチデータはTRISCレジスタ設定で各ピンに反映される）
;
;
;		ANSELA(BANK3　18CH)
;			bit7-5	Unimplemented(read=0)
;			bit4	ANSA3/RA4	アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			bit3	Unimplemented(read=0)
;			bit2-0	ANSA2-0/RA2-0アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;		ANSELC(BANK3　18EH)
;			bit7-6	Unimplemented(read=0)
;			bit5-0	ANSC5-0/RC5-0アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;
;		WPUA(BANK4　20CH)　ポートAプルアップ設定ビット
;			bit7-6	Unimplemented(read=0)
;			bit5-0			1=PORTA各ビットプルアップ有効
;					 _____	0=PORTA各ビットプルアップ無効
;					*WPUENビットが有効の時のみ、設定有効となる。
;
;		WPUC(BANK4　20EH)　ポートCプルアップ設定ビット
;			bit7-6	Unimplemented(read=0)
;			bit5-0			1=PORTA各ビットプルアップ有効
;					 _____	0=PORTA各ビットプルアップ無効
;					*WPUENビットが有効の時のみ、設定有効となる。
;
;		FVRCONレジスタ(BANK2　117H)
;			bit7	FVREN	FVRイネーブルビット
;							1=有効
;							0=無効
;			bit6	FVRRDY	FVR準備フラグビット(#1)書込み不可
;							1=使用可能
;							0=使用不可能あるいは禁止されている
;			bit5	TSEN	温度表示器イネーブルビット
;							1=有効
;							0=無効
;			bit4	TSRNG	温度表示器測定レンジ選択ビット
;							1=High Range:Vout=VDD-4VT
;							0=Low Range:Vout=VDD-2VT
;			bit3-2	CDAFVR	コンパレータとDACへのFVR電圧選択ビット
;							11 = FVR出力　4x(4.096V)#2
;							10 = FVR出力　2x(2.048V)#2
;							01 = FVR出力 1x(1.024V)
;							00 = FVR出力OFF
;			bit1-0	ADFVR	ADCへのFVR電圧選択ビット
;							11 = FVR出力　4x(4.096V)#2
;							10 = FVR出力　2x(2.048V)#2
;							01 = FVR出力 1x(1.024V)
;							00 = FVR出力OFF
;
;							#1)16F1705/16F1709では常に"1"
;							#2)FVR電圧出力はVDDを超える事は出来ない
;
;		DAC1CON0レジスタ(BANK2　118H)
;		bit7	DACEN	DAC1イネーブルビット　P156 Fig17-1参照
;						1=許可
;						0=禁止
;		bit6	Unimplemented(read=0)
;		bit5	DAC1OE1	DAC1電圧出力1イネーブルビット
;						1=DAC1出力電圧をDACOUT1ピンにも出力される
;						0=DAC1出力電圧をDACOUT1ピンから切り離す
;		bit4	DAC1OE2	DAC1電圧出力2イネーブルビット
;						1=DAC1出力電圧をDACOUT2ピンにも出力される
;						0=DAC1出力電圧をDACOUT2ピンから切り離す
;		bit3-2	DAC1PSS	DAC1 正入力接続選択ビット
;						00 = VDD
;						01 = VREF+ピン(RA1)
;						10 = FVRバッファ2出力
;						11 = 使用不可
;		bit1	Un		Read as '0'
;		bit0	DAC1NSS DAC1 負入力選択ビット
;						1=VREF-ピン(RA0)
;						0=GND
;
;		ADCON0レジスタ(BANK1　09EH)
;		bit7	Unimplemented(read=0)
;		bit6-2	CHSx	アナログチャンネル入力選択ビット
;						11111 = FVRバッファ1出力
;						11110 = DAC1_OUTPUT
;						11101 = 温度インジケータ
;						11100 = FVRバッファ2出力
;						11011 = 予約 未接続
;								?
;						01100 = 予約 未接続
;						01011 = AN11
;						01010 = AN10
;						01001 = AN9
;						01000 = AN8
;						00111 = AN7
;						00110 = AN6
;						00101 = AN5
;						00100 = AN4
;						00011 = AN3
;						00010 = AN2
;						00001 = AN1
;						00000 = AN0
;		bit1	GO/DONE	A/D変換ステータスビット
;						1=変換開始指令（1にすると変換動作開始）
;						0=変換完了(変換完了すると0になる）
;		bit0	ADON	A/D変換ステータスビット
;						1=A/Dコンバータ動作
;						0=A/Dコンバータ停止
;
;		ADCON1レジスタ(BANK1　09EH)
;		bit7	ADFM	変換結果格納指定
;						1=右詰
;						0=左詰め
;		bit6-4	ADCS	A/D変換クロック選択ビット
;						111 = Frc
;						110 = Fosc/64
;						101 = Fosc/16
;						100 = Fosc/4
;						011 = Frc
;						010 = Fosc/32
;						001 = Fosc/8
;						000	= Fosc/2
;		bit3-2	Unimplemented(read=0)
;		bit1-0	ADPREF	参照正電圧指定
;						11 = 内部FVRモジュール
;						10 = 外部VREF+ピン (RA1)
;						01 = Reserved
;						00 = VDD
;
;
;		オペアンプ制御レジスタ(OPA1,OPA2)
;		OPAxCON(BANK10 0511H,0515H)
;		bit7	OPAxEN	OPAxイネーブルビット
;						1=有効
;						0=無効
;		bit6	OPAxSP  オペアンプ速度/消費電力選択ビット
;						1=高GBWPモードで動作
;						0=低GBWPモードで動作
;		bit5	Unimplemented(read=0)
;		bit4	OPAxUG	オペアンプ ユニティゲイン選択ビット
;						1=OPA出力を反転入力に接続。
;							OPAxIN-ピンは汎用I/Oとして使用できる
;						0=反転入力をOPAxIN-ピンに接続する
;		bit3-2	Unimplemented(read=0)
;		bit1-0	OPAxCH	非反転チャンネル選択ビット
;						11 = 非反転入力にFVRバッファ2出力を接続
;						10 = 非反転入力にDAC_outputを接続
;						11 = 非反転入力にOPAxIN+を接続
;
;		OPTION_REG(BANK1　095H)
;					_____
;			bit7=1	WPUEN	プルアップ グローバル設定ビット
;							0=有効,1=無効
;			bit6=0	INTEDG	INTピン割り込み信号エッジ
;							1=↑
;							0=↓
;			bit5=0	TMR0CS	TMR0クロックソース選択ビット
;							1=外部入力RA2/T0CKI
;							0=内部システムクロック(Fosc/4)
;			bit4=1	TMR0SE	TMR0ソースエッジ選択ビット
;							1=RA4/T0CKIピンが↑の時インクリメント
;							0=RA4/T0CKIピンが↓の時インクリメント
;			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)　コア　00BH
;			bit7	GIE		全割込制御
;							1許可、0禁止
;			bit6	PEIE	周辺装置割込制御
;							1許可、0禁止
;			bit5	TMR0IE	タイマ0割込許可制御
;							1許可、0禁止
;			bit4	INTE	RA2外部割込許可制御
;							1許可、0禁止
;			bit3	IOCIE	I/Oポート状態変化割込許可制御
;							1許可、0禁止
;			bit2	TMR0IF	タイマ0割込みフラグ(#1)
;							1オーバーフロー
;							0オーバーフローなし
;			bit1	INTF	RA2外部割込みフラグ(#1)
;							1割込み発生
;							0割込み発生なし
;			bit0	IOCIF	I/Oポート状態変化割込フラグ(#1)
;							1割込発生
;							0割込無
;
;							#1)ソフトウエアでリセット必要
;							#2)初期値=0なので、初期設定で0設定する必要は無い
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

init
;			各レジスタ初期設定(PIC16F1705)
			movlb	0h			;BANK0
			movlw	000h		;00000000B
			movwf	INTCON		;全割込みOFF
			movlb	0h			;BANK0
			clrf	PORTA		;Init PORT
			clrf	PORTC
			movlb   02h         ;BANK2
			clrf    LATA
			clrf    LATC
			;クロック
			movlb	01h			;BANK１
			movlw	0f0h		;1111000B
			movwf	OSCCON		;内部発振器は8MHZに設定
								;4xPLL=ON
			;TMR0およびプルアップ
			movlw	083H		;10000011b
			movwf	OPTION_REG	;プルアップOFF
								;割込みエッジ↓
								;クロックソース内部（Fosc/4）
								;TMR0カウントエッジ↓
								;プリスケーラ割当→TMR0
								;プリスケーラ分周1/16にセット
			;10ビットADC
;			movlw	020h		;0010000B
;			movwf	ADCON1		;左詰め、基準電圧VDD
								;ADCクロック　Fosc/32=1us(32MHZ)
			;I/Oポート(TRIS→BANK1、ANSEL→BANK3)
			movlw	01FH        ;00011111B
			movwf	TRISA		;RA0-3入力、RA4-5出力
			movlw	07h			;00000111B
			movwf	TRISC		;RC0-2入力、RC3-5出力
			movlb	03h			;BANK3
			movlw	00h			;00000000B
			movwf	ANSELA		;RA0-5=デジタル
			movlw	00h			;00000000B
			movwf	ANSELC		;RC0-5=デジタル

			;FVR(BANK2)
;			movlb	02h			;BANK2
;			movlw	088h		;10001000B
;			movwf	FVRCON		;FVRイネーブル
								;DACとCPSに2.048V
								;ADCにはOFF

;			8ビットDAC(BANK2)
;			movlw	088h		;10001000B
;			movwf	DAC1CON0	;DAC1イネーブル
;			movlb	0h			;基準電圧はFVR
								;DACOUTピン切り離し

;			オペアンプ1(BANK10)
;			movlb	0ah			;BANK10
;			movlw	0d2h		;11010010B
;			movwf	OPA1CON		;OPA1イネーブル
;			movlb	0h			;高GBWPモード、ユニティゲイン
								;IN+=DAC1_OUTPUT
;			注意	オペアンプ出力ピンはアナログ入力に設定する事

;			レジスタ初期設定終了
			clrf	BSR


;			初期値セット
			clrf	hex0
			clrf	hex1
			clrf	hex2
			clrf	hex3
;
;		メインループ
;
;

coldst
			movlw	04FH		;FLG=01001111B
			movwf	FLG			;8桁、ゼロブランキングON
								;4,7桁ドット有
			call	SET_MODE
mloop		;メインループ
			movlw	01h
			movwf	hexw0
			clrf	hexw1
			clrf	hexw2
			clrf	hexw3
			call	ADD32B
			call	BCD			;BCDに変換
			call	SET_BUF		;データ整理
			call	PUTL		;モジュールに送信
;			call	wait100m
			goto	mloop

;			call	RE_DATA     ;生成周波数カウンタ FDAxを出力
;			iorlw   0h			;W=0でカウント無
								;W=1でREカウント有
;			btfsc	STATUS,Z
;			goto	mloop		;RE変化無
;			REカウントされた
			movf	FDA0,W
			movwf	hex0
			movf	FDA1,W
			movwf	hex1
			movf	FDA2,W
			movwf	hex2
			movf	FDA3,W
			movwf	hex3

;			hex(0-3)32ビットバイナリ数値を8桁7セグLED「DFR0090」に表示
;			表示方法は「FLG」バイトで指定
			call	BCD			;hex(0-3)32bitバイナリ数値をBCDに変換
								;出力はdigit(12-34-56-78-9A)の5バイト
			call	SET_BUF		;BCD出力をDBUF(0-7)にデータ変換
			call	PUTL		;DBUF(0-7)をセグメントデータに変換、
								;LEDモジュールに送信・表示
								;XC8版「PUTL」関数との操作互換性はありません。
			goto	mloop



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			動作モードセット設定
;
;	入力制御フラグ	FLG　この内容は保存される
;	　2桁表示指令	FLG=xxxxx001
;	　4桁表示指令	FLG=xxxxx011
;	　6桁表示指令	FLG=xxxxx101
;	　8桁表示指令	FLG=xxxxx111
;	　ゼロブランキング
;					FLG=xxxx0xxx　しない
;					FLG=xxxx1xxx　する
;	　ドット表示指令
;					FLG=x000xxxx　表示なし
;						bit4=1	2,5桁点燈
;						bit5=1	3,6桁点燈
;						bit6=1	4,7桁点燈
;	　警告LED		FLG=1xxxxxxx　LED点灯する
;					FLG=0xxxxxxx　LED点灯しない
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SET_MODE
			movf	FLG,W
			andlw	07h
			movwf	colum
			iorlw	0h
			btfss	STATUS,Z
			bra		stmd0
			movlw	07h			;桁指定無いので8桁にする
			movwf	colum
stmd0		btfss	FLG,7		;オーバーフローLED制御
			goto	stmd1
			bsf		PORTA,5		;LED ON
;			bcf		PORTA,5		;LED ON
			return

stmd1
			bcf		PORTA,5		;LED OFF
;			bsf		PORTA,5		;LED OFF
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		表示データバッファのセッティング
;
;	入力データ	5バイト(10桁分)BCD　この内容は保存される
;				digit12
;				digit34
;				digit56
;				digit78
;				digit9A（表示されない）
;
;	表示桁		colum　この内容は保存される
;	
;	入力制御フラグ	FLG　この内容は保存される
;		2桁表示指令	FLG=xxxxx001
;		4桁表示指令	FLG=xxxxx011
;		6桁表示指令	FLG=xxxxx101
;		8桁表示指令	FLG=xxxxx111
;	ゼロブランキング
;					FLG=xxxx0xxx　しない
;					FLG=xxxx1xxx　する
;	ドット表示指令
;					FLG=x000xxxx　表示なし
;						bit4=1	2,5桁点燈
;						bit5=1	3,6桁点燈
;						bit6=1	4,7桁点燈
;	警告LED			FLG=1xxxxxxx　LED点灯する
;					FLG=0xxxxxxx　LED点灯しない
;
;	上位桁から書き込みます
;
;		DBUFx　	各桁バッファ データフォーマット
;			bit0-3	表示する数値データ	bit0-3=0H-FH
;			bit4	ドット表示			0=OFF、1=ON
;			bit5	ブランク			0=OFF、1=ON
;			bit6	予約
;			bit7　　予約
;			*桁データは専用サブルーチンにて、転送ビットデータに変換されます
;
;	使用ワーク	bufw0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SET_BUF
;			表示する数値データを全バッファに書込み
			swapf	digit78,W
			andlw	0FH
			movwf	DBUF7		;8桁目に数値データ書込み

			movf	digit78,W
			andlw	0FH
			movwf	DBUF6		;7桁目に数値データ書込み
			
			swapf	digit56,W
			andlw	0FH
			movwf	DBUF5		;6桁目に数値データ書込み

			movf	digit56,W
			andlw	0FH
			movwf	DBUF4		;5桁目に数値データ書込み
			
			swapf	digit34,W
			andlw	0FH
			movwf	DBUF3		;4桁目に数値データ書込み

			movf	digit34,W
			andlw	0FH
			movwf	DBUF2		;3桁目に数値データ書込み
			
			swapf	digit12,W
			andlw	0FH
			movwf	DBUF1		;2桁目に数値データ書込み

			btfss	FLG,7
			goto	setb01		;ノーマル処理
;			オーバーフロー表示処理
			movlw	0EH			;最下位桁に`E`を表示
			movwf	DBUF0
			goto	setb02

setb01		movf	digit12,W
			andlw	0FH
			movwf	DBUF0		;1桁目に数値データ書込み

;			その他指定処理を全バッファに行う
;			呼び出し順番によっては上手く機能しなくなるので注意
setb02		call	ZBK			;ゼロブランキング処理
			call	SPOS		;指定表示桁数処理
			call	ADDOT		;ドット表示処理

;			オーバーフローチェック
;			警告LEDを発光させる、7セグ表示は残り8桁分を表示
			movf	digit9A,W	;ここにデータがある場合O.Fとなる
			iorlw	0h
			btfss	STATUS,Z
			bra		sbfer
			bcf		PORTA,5			
;			bsf		PORTA,5		;LED OFF
			return
sbfer		bsf		PORTA,5		;オーバーフロー発生
;			bcf		PORTA,5		;LED ON
			retlw	0FFH

;
;			ゼロブランキング処理
;
;		入力	DBUFx　（数値データ設定済であること)
;				FLG	ビット3　ZBKフラグ
;		使用ワーク	無
;
ZBK
			btfss	FLG,3		;ZBK命令フラグチェック
			return				;命令無いので終了
			movf	DBUF7,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF7,5		;ブランキングセット

			movf	DBUF6,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF6,5		;ブランキングセット

			movf	DBUF5,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF5,5		;ブランキングセット

			movf	DBUF4,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF4,5		;ブランキングセット

			movf	DBUF3,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF3,5		;ブランキングセット

			movf	DBUF2,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF2,5		;ブランキングセット

			movf	DBUF1,W		;
			andlw	0fh			;数値データゼロチェック
			btfss	STATUS,Z
			return				;データはゼロで無いので終了
			bsf		DBUF1,5		;ブランキングセット

			return				;DBUF0はゼロブランキングしない



;
;			表示桁位置調整サブルーチン
;			データバッファへの準備ルーチンから呼ばれる事を想定
;
;			指定表示桁数になるまでバッファのデータを右シフトする
;			余った左側桁は「0」に書換える
;			はみ出た下位桁は破棄される
;
;		入力		DBUFx	調整処理するデータバッファ
;					colum	設定表示桁数
;		出力		DBUFx	調整処理されたデータバッファ
;		使用ワーク	colw0	桁位置ワーク
;

SPOS
			movlw	07h
			subwf	colum,W		;バイトシフト回数設定
			btfsc	STATUS,C	;ボローなら処理開始
			return				;表示桁変更無で終了
			movf	colum,W		;バイトシフト回数設定
			sublw	07h			;W=07-W
			movwf	colw0
spos01		;1バイト右シフト
			movf	DBUF1,W		;DB1→DB0
			btfsc	FLG,7
			call	sposer
			movwf	DBUF0
			bcf		DBUF0,5		;ブランクビットリセット
			
			movf	DBUF2,W		;DB2→DB1
			movwf	DBUF1
			
			movf	DBUF3,W		;DB3→DB2
			movwf	DBUF2
			
			movf	DBUF4,W		;DB4→DB3
			movwf	DBUF3
			
			movf	DBUF5,W		;DB5→DB4
			movwf	DBUF4
			
			movf	DBUF6,W		;DB6→DB5
			movwf	DBUF5
			
			movf	DBUF7,W		;DB7→DB6
			movwf	DBUF6
			
			movlw	020h		;bit5=1、他ビット=0
			movwf	DBUF7		;ブランクビットセット
			
			decf	colw0,F
			btfss	STATUS,Z
			goto	spos01
			retlw	0h

;			W_REGの下位4ビットをEHにする
sposer
			andlw	0f0h
			iorlw	0eh
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			ドットを表示するか否かの処理ルーチン
;
;		入力	FLG		
;
;		出力	DBUFx,4=0		ドット点燈無
;		出力	DBUFx,4=1		ドット点燈有
;
;		FLG
;		ドット表示位置		flg=x111xxxx
;							bit4=1	2,5桁点燈
;							bit5=1	3,6桁点燈
;							bit6=1	4,7桁点燈
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ADDOT
			bcf		DBUF0,4		;ドット点灯ビットリセット
			bcf		DBUF1,4		;
			bcf		DBUF2,4		;
			bcf		DBUF3,4		;
			bcf		DBUF4,4		;
			bcf		DBUF5,4		;
			bcf		DBUF6,4		;
			bcf		DBUF7,4		;

			;2,5桁点燈指令チェック
			btfss	FLG,4		;2,5点燈指令か？
			goto	adt2		;違うので次ビットチェック
			;2,5桁目点燈処理
			bsf		DBUF1,4		;2桁目ドット点燈
			bsf		DBUF4,4		;5桁目ドット点燈
			return

adt2		;3,6桁点燈指令チェック
			btfss	FLG,5		;3,6点燈指令か？
			goto	adt4		;違うので次ビットチェック
			;3桁目点燈処理
			bsf		DBUF2,4		;3桁目ドット点燈
			bsf		DBUF5,4		;6桁目ドット点燈
			return

adt4		;4,7桁点燈指令チェック			
			btfss	FLG,6		;4,7点燈指令か？
			return				;点灯無終了
			;4桁点燈処理
			bsf		DBUF3,4		;4桁目ドット点燈
			bsf		DBUF6,4		;7桁目ドット点燈
			return

;
;		8桁すべて表示させる
;		表示位置指定はできない
;		表示データは、ワークレジスタDBUFxに事前に準備必要
;
;		入力		DBUF0-DBUF7
;
;		番号は桁番号と一致、例)DBUF7=8桁目（最上位桁）
;

PUTL
			movf	DBUF0,W		;桁データをレジスタに転送
			call	PUTR		;ラッチはしない=旧データ表示のまま
			movf	DBUF1,W
			call	PUTR
			movf	DBUF2,W
			call	PUTR
			movf	DBUF3,W
			call	PUTR
			movf	DBUF4,W
			call	PUTR
			movf	DBUF5,W
			call	PUTR
			movf	DBUF6,W
			call	PUTR
			movf	DBUF7,W
			call	PUTR
			
			call	PTLAT		;ラッチする=新データ表示する
			return


;
;		Wregの1ケタデータを最上位桁に表示(ラッチ)させる
;		もちろん、旧データはシフトしていき、最下位桁は破棄されます。
;
;		使用変数	wrk0、wrk1
;
PUTC
			call	GET_7SEG	;Wreg=SEG_DATA
			movwf	wrk0		;セグメントビットデータ
			movlw	08h			;8ビット分送出カウンタ
			movwf	wrk1		;カウンタ
			SPI_CLKL
			SPI_LATL
ptclp
			lsrf	wrk0,F		;C=LSB
			btfsc	STATUS,C
			goto	ptc01
			
ptc00		;DATA=0送出
			SPI_DATL
			call	wait01u		;ウエイト1us
			SPI_CLKH
			call	wait01u		;ウエイト1us
			SPI_CLKL
			goto	ptcen
			
ptc01		;DATA=1送出
			SPI_DATH
			call	wait01u		;ウエイト1us
			SPI_CLKH
			call	wait01u		;ウエイト1us
			SPI_CLKL

ptcen		;
			decfsz	wrk1
			goto	ptclp		;残ビット有
;			ラッチパルス送出して終了
			SPI_LATH
			call	wait01u
			SPI_LATL
			return

;
;		Wregの1ケタデータを最上位桁レジスタに転送するがラッチしない
;		7セグ表示は旧データのままで、更新されたデータは表示されない
;		レジスタの旧データはシフトしていき、最下位桁分は破棄されます。
;
;		使用変数	wrk0、wrk1
;
PUTR
			call	GET_7SEG
			movwf	wrk0		;セグメントビットデータ
			movlw	08h
			movwf	wrk1		;カウンタ
			SPI_CLKL
			SPI_LATL
ptrlp
			lsrf	wrk0,F		;C=LSB
			btfsc	STATUS,C
			goto	ptr01
			
ptr00		;DATA=0送出
			SPI_DATL
			call	wait01u		;ウエイト1us
			SPI_CLKH
			call	wait01u		;ウエイト1us
			SPI_CLKL
			goto	ptren
			
ptr01		;DATA=1送出
			SPI_DATH
			call	wait01u		;ウエイト1us
			SPI_CLKH
			call	wait01u		;ウエイト1us
			SPI_CLKL

ptren							;
			decfsz	wrk1
			goto	ptrlp
			return				;ラッチしないで終了

;			ラッチパルス送出
;
;			コールするだけでOK
;			
PTLAT
			SPI_LATH
			call	wait01u
			SPI_LATL
			call	wait01u
			return

;
;		１桁分のブランクデータを転送する
;		表示（ラッチ）はしない
;
CLC
;			ブランクデータ転送準備
			movlw	08H			;8
			movwf	wrk0
			SPI_CLKL
			call	wait01u
			SPI_LATL
			call	wait01u
			SPI_DATH
			call	wait01u
;			データ転送ループ
clc01
			SPI_CLKH
			call	wait01u
			SPI_CLKL
			call	wait01u
			decfsz	wrk0
			goto	clc01
			return

;
;		8桁すべてブランク表示とする
;
CLL
;			ブランクデータ転送準備
			movlw	040h		;8×8
			movwf	wrk0
			SPI_CLKL
			call	wait01u
			SPI_LATL
			call	wait01u
			SPI_DATH
			call	wait01u
;			データ転送ループ
cll01
			SPI_CLKH
			call	wait01u
			SPI_CLKL
			call	wait01u
			decfsz	wrk0
			goto	cll01
;			終了処理（ラッチする）
			call	wait01u
			SPI_LATH
			call	wait01u
			SPI_LATL
			call	wait01u
			SPI_DATL
			return




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		DFR0090モジュール用セグメントデータへの変換
;
;	入力		Wレジスタに桁データ(DBUFx)を入れてコール
;				ドット消灯の場合、00H-0FH
;				ドット点灯の場合、10H-1FH
;
;	使用ワーク	BLK
;				
;	出力		Wレジスタに8ビット分ポート出力データを入れてリターン
;				これをLSBから順番にDATAポートに出力する事
;				
;	SIポート	データビット=1	Qx=1　セグメント発光OFF
;				データビット=0	Qx=0　セグメント発光ON
;				ビットデータはQAから順に入り、QHへデータがシフトしていく。
;				よって、8回データ取り込みで全セグメント分設定となる。
;				また、QHからシフトしたデータは次のQAへシフトする。
;				よって、データは最上位桁（左側）から順に最下位桁へシフトしていく。
;
;	モジュール内セグメント
;
;		a				QA=a	QE=e
;	f		b			QB=b	QF=f
;		g				QC=c	QG=g
;	e		c			QD=d	QH=Dp
;		d		Dp		
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GET_7SEG
			
			movwf	BLK			;Wreg保存
			btfsc	BLK,5		;ブランク制御フラグチェック
			retlw	0FFH		;ブランク返し
;			movf	BLK,W		;Wreg復活
			andlw	01FH		;下位5ビット取り出し
			brw

;			ドット無
			retlw	B'00000011'	;Code 0 abcdef
			retlw	B'10011111'	;Code 1 bc
			retlw	B'00100101'	;Code 2 abdeg
			retlw	B'00001101'	;Code 3 abcdg
			retlw	B'10011001'	;Code 4 bcfg
			retlw	B'01001001'	;Code 5 acdfg
			retlw	B'01000001'	;Code 6 acdefg
			retlw	B'00011111'	;Code 7 abc
			retlw	B'00000001'	;Code 8 abcdefg
			retlw	B'00011001'	;Code 9 abcfg
			retlw	B'00010001'	;Code A abcefg
			retlw	B'11000001'	;Code B cdefg
			retlw	B'01100011'	;Code C adef
			retlw	B'10000101'	;Code D bcdeg
			retlw	B'01100001'	;Code E adefg
			retlw	B'01110001'	;Code F aefg

;			ドット有
			retlw	B'00000010'	;Code 0 abcdef
			retlw	B'10011110'	;Code 1 bc
			retlw	B'00100100'	;Code 2 abdeg
			retlw	B'00001100'	;Code 3 abcdg
			retlw	B'10011000'	;Code 4 bcfg
			retlw	B'01001000'	;Code 5 acdfg
			retlw	B'01000000'	;Code 6 acdefg
			retlw	B'00011110'	;Code 7 abc
			retlw	B'00000000'	;Code 8 abcdefg
			retlw	B'00011000'	;Code 9 abcfg

			retlw	B'00010000'	;Code A abcefg
			retlw	B'11000000'	;Code B cdefg
			retlw	B'01100010'	;Code C adef
			retlw	B'10000100'	;Code D bcdeg
			retlw	B'01100000'	;Code E adefg
			retlw	B'01110000'	;Code F aefg



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
;		ロータリーエンコーダ入力パルス　カウントサブルーチン
;
;		想定部品	ALPS	EC12E2420801(クリックタイプ）
;							EC12E2420803(ノンクリックタイプ)
;							チャタリング	3ms(max),R=10KΩ
;							バウンズ	2ms(max),R=10KΩ
;		エンコーダA端子		RA0
;		エンコーダB端子		RA1
;		カウント出力データ	FDA0
;							FDA1
;							FDA2
;							FDA3
;
;		エンコーダ右回り	アップカウント
;		エンコーダ左回り	ダウンカウント
;       カウントステップ	RESP0-RESP2(24bit)に事前設定
;
;
;		状態変化無ならWreg=0でリターン
;		状態変化有ならWreg=1、REDAT下位2ビットに記録
;		REDAT	エンコーダ用ビットデータ
;		旧ビットデータは左シフトされ、オーバーフロービットは破棄される
;		t(0)	→bit1,0(REA,REB)
;		t(-1)	→bit3,2(REA,REB)
;		t(-3)	→bit5,4(REA,REB)
;		t(-4)	→bit7,6(REA,REB)
;
;		使用専用ワーク	rew0,rew1,REDAT,RESTP
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RE_DATA
;			ポートデータチェック(REポートアクセスはここだけ）
;			rew0	取得データ（下位2ビット有効）
			movf	PORTA,W     ;RA0,RA1ポート読込(1'st)
			andlw	03h
			movwf	rew0        ;bit0=REA,bit1=REB
			call	wait1m			;チャタリング終了待ち3ms
			call	wait1m
			call	wait1m
			movf	PORTA,W		;RA0,RA1ポート読込(2'st)
			andlw	03h
			movwf	rew1		;
			xorwf	rew0,W		;1'stと2'stを比較
			btfss	STATUS,Z	;Z=1ならば取得データ有効
			goto	RE_DATA     ;データ読込エラー リトライ

;			ポートデータ新旧比較
			movf	REDAT,W
			movwf	rew1		;過去データをコピー
			movlw	03h
			andwf	rew1,W		;不要ビットをクリア
			xorwf	rew0,W		;新旧データ比較
			btfsc	STATUS,Z	;Z=0ならば状態変化有
			goto	re_end0		;状態変化無

;			保存データ更新
;			過去データ      REDAT
;			一時保存ワーク  rew1
			movf	REDAT,W		;過去ビット保存データ
			movwf	rew1		;過去データ一時保存
			lslf	REDAT,F		;新データ挿入のため2ビット左シフト
			lslf	REDAT,F		;bit0-1はクリアされます
			movf	rew0,W
			iorwf	REDAT,F		;保存データ更新
								;bit0→REA新取得データ
								;bit1→REB新取得データ
								;bit2→REA旧データ
								;bit3→REB旧データ

;			回転方向判別
;			rew1=過去データ
;			rew0=現在データ
;			判別式D=rew1*2 XOR rew0
;			D(bit1)=0ならCW（時計回り）
;			D(bit1)=1ならCCW（反時計回り）
			movlw	03h			;
			andwf	rew1,F		;rew1=F(-1)の2ビットのみとする
			lslf	rew1,W		;F(-1)ビットを左シフト
			xorwf	rew0,F		;(取得ビット)XOR(旧ビット)
			btfsc	rew0,1		;Lなら時計回転
			goto	ccw			;Hなら反時計回転

;			右回転処理
;   		FDA(0-3)を指定ステップでインクリメント
;			RESP(0-2)=アップダウンステップ
cw			movf	RESP0,W     ;1カウントの加算ステップ数
			movwf	hexw0
			movf	RESP1,W
			movwf	hexw1
			movf	RESP2,W
			movwf	hexw2
			clrf	hexw3
			call	FDAHEX
			call	ADD32B		;ステップ周波数分を加算
			call	HEXFDA
			goto	re_end1		;
;			最大行番号越えをチェック
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			movf	hex2,W
			movwf	hexw2
			movf	hex3,W
			movwf	hexw3		;hexw=hex
			movlw	0ffh
			movwf	hex0
			movlw	0e0h
			movwf	hex1
			movlw	0f5h
			movwf	hex2
			movlw	05h
			movwf	hex3		;hex=05F5E0FFH=99,999,999
			call	SUB32B		;hex=hex-hexw、W=1ならボロー発生
			iorlw	0h			;ボローチェック
			btfsc	STATUS,C
			goto	re_end1		;状態変化有、正常終了
;			ボロー発生、最大周波数保護
			movlw	0ffh
			movwf	FDA0
			movlw	0e0h
			movwf	FDA1
			movlw	0f5h
			movwf	FDA2
			movlw	05h
			movwf	FDA3		;FDAx=05F5E0FFH=99,999,999（表示最大値）
			goto	re_end0		;状態変化無、カウンタ最大値

;			左回転処理		FDA(0-1)を指定ステップでデクリメント
ccw			movf	RESP0,W		;1カウントの減算ステップ数
			movwf	hexw0
			movf	RESP1,W
			movwf	hexw1
			movf	RESP2,W
			movwf	hexw2
			clrf	hexw3
			call	FDAHEX
			call	SUB32B		;ステップ周波数分を減算
			iorlw	0h			;ボローチェック
			btfss	STATUS,C
			goto	ccwer
			call	HEXFDA
			goto	re_end1		;状態変化有、終了
ccwer		clrf	FDA0		;
			clrf	FDA1
			clrf	FDA2
			clrf	FDA3
;			goto	re_end0		;状態変化無、カウンタリセット

;		RE変化無での終了処理
re_end0
			retlw	0h			;RE、ADC、共に変化無
;		RE変化有での終了処理
re_end1
			retlw	01h			;RE変化有、ADC変化無

;		FDAxをHEXxにコピー
FDAHEX		movf	FDA0,W
			movwf	hex0
			movf	FDA1,W
			movwf	hex1
			movf	FDA2,W
			movwf	hex2
			movf	FDA3,W
			movwf	hex3
			return

;			HEXxをFDAxにコピー
HEXFDA		movf	FDA0,W
			movwf	hex0
			movf	FDA1,W
			movwf	hex1
			movf	FDA2,W
			movwf	hex2
			movf	FDA3,W
			movwf	hex3
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
;			Ａ／Ｄ変換サブルーチン(PIC16F1705)
;
;		アナログ入力ポート		RA1/AN1/CH1
;		結果格納方法		ADFM=0/左詰め/ADRESHのみ取得
;		出力データ			hex0
;
;		ADCON0レジスタ（BANK1　09DH)
;		bit7	Unimplemented(read=0)
;		bit6-2	CHSx	アナログチャンネル指定
;						00000 = AN0/RA0
;						00001 = AN1/RA1
;						00010 = AN2/RA2
;						00011 = AN3/RA4
;						00100 = AN4/RC0
;						00101 = AN5/RC1
;						00110 = AN6/RC2
;						00111 = AN7/RC3
;						01000 = AN8/RC6
;						01001 = AN9/RC7
;						01010 = AN10/RB4
;						01011 = AN11/RB5
;						01000 = Reserved.No channel connected
;						    ・
;						11011 = Reserved.No channel connected
;						11100 = FVRバッファ２出力
;						11101 = 温度表示器
;						11110 = DAC1出力
;						11111 = FVRバッファ1出力
;		bit1	GO/DONE	A/D変換ステータスビット
;						1=変換開始指令（１にすると変換動作開始）
;						0=変換完了(変換完了すると０になる）
;		bit0	ADON	A/D変換ステータスビット
;						1=A/Dコンバータ動作
;						0=A/Dコンバータ停止
;
;
;		ADCON1レジスタ(BANK1　09EH)
;		bit7	ADFM	変換結果格納指定
;						1=右詰
;						0=左詰め
;		bit6-4	ADCS	A/D変換クロック選択ビット
;						000	= Fosc/2
;						001 = Fosc/8
;						010 = Fosc/32
;						011 = Frc
;						100 = Fosc/4
;						101 = Fosc/16
;						110 = Fosc/64
;						111 = Frc
;		bit3-2	Unimplemented(read=0)
;		bit1-0	ADPREF	参照正電圧指定
;						00 = VDD
;						01 = Reserved
;						10 = 外部VREF+ (RA1)
;						11 = 内部FVRモジュール
;
;		使用ワーク		;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;		ボリウム分電圧取得
;
;		基準電圧はVDD
;		入力チャンネルはRA2/AN2
;		出力は10bitでhex0-hex1の16bitに右詰で格納
GET_ADC
			movlb	01h			;BANK1
			movlw	0A0H
			movwf	ADCON1		;REF=VDD
			movlw	09h		;00001001b
								;右詰め、基準電圧VDD、
								;AN2(RA2)選択、ADON_ON
			movwf	ADCON0		;電圧サンプリング開始
			clrf	BSR
			call	wait10u		;サンプリング電圧安定化待ち
			call	wait10u
			movlb	01h
			bsf		ADCON0,GO	;A/D変換開始指令
aloop
			btfsc	ADCON0,GO	;A/D変換完了待ち
			goto	aloop		;GO=0ならば次へ
			movf	ADRESH,W	;データ上位８ビット
			clrf	BSR
			movwf	hex1
			movlb	01H
			movf	ADRESL,W
			bcf		ADCON0,ADON	;A/DコンバータOFF
			clrf	BSR
			movwf	hex0		;
			movlw	03H
			andwf	hex1,F		;上位6bit
			;
			movlb	01H
			movlw	0A3H
			movwf	ADCON1		;REF=FVR
			clrf	BSR
			return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		４バイトバイナリの10桁BCDへの変換
;		MicroChip社のアプリケーションノートより
;
;		入力		4バイト(32ビット)16進バイナリ
;				hex0
;				hex1
;				hex2
;				hex3
;
;		出力		5バイト(10桁)ＢＣＤ
;				digit12
;				digit34
;				digit56
;				gidit78
;				gidit9A
;
;		使用ワーク
;				hexw0	入力データ保存用
;				hexw1
;				hexw2
;				hexw3
;				shift	シフトカウンタ
;				bcdw0	補正処理ワーク
;				bcdw1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BCD
			BCF		STATUS,C	;キャリーリセット
			MOVLW	020H		;シフトカウンタ初期化
			MOVWF	shift		;4バイト分32回の指定
			CLRF	digit12		;BCDデータエリア初期化
			CLRF	digit34
			CLRF	digit56
			CLRF	digit78
			CLRF	digit9A
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			movf	hex2,W
			movwf	hexw2
			movf	hex3,W
			movwf	hexw3

			;変換ループ処理
loop
			RLF		hexw0,F		;16進データ左シフト
			RLF		hexw1,F
			RLF		hexw2,F
			RLF		hexw3,F
			RLF		digit12,F	;BCDデータ左シフト
			RLF		digit34,F
			RLF		digit56,F
			RLF		digit78,F
			RLF		digit9A,F
			DECFSZ	shift,F		;
			GOTO	adjst		;BCD調整処理へ
			RETURN

			;BCDデータ全桁補正処理
adjst
			MOVF	digit12,W	;digit12
			CALL	adjbcd
			MOVWF	digit12
			MOVF	digit34,W	;digit34
			CALL	adjbcd
			MOVWF	digit34
			MOVF	digit56,W	;digit56
			CALL	adjbcd
			MOVWF	digit56
			MOVF	digit78,W	;digit78
			CALL	adjbcd
			MOVWF	digit78
			MOVF	digit9A,W	;digit9A
			CALL	adjbcd
			MOVWF	digit9A
			GOTO	loop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1バイト2桁分必要に応じて+3補正処理
;
;			入力		W_reg
;			出力		W_reg
;
;			使用ワーク	bcdw0
;					bcdw1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
adjbcd
			MOVWF	bcdw0		;元データをbcdw0に保存
			MOVLW	3			;W=3
			ADDWF	bcdw0,W		;W=3+bcdw0
			MOVWF	bcdw1		;下桁を+3した上下桁をbcdw1に保存
			BTFSC	bcdw1,3		;if 下桁<7 then next_skip
			MOVWF	bcdw0		;下桁を+3した上下桁をbcdw0に保存

			MOVLW	030H		;W+30
			ADDWF	bcdw0,W		;W=上桁+3
			MOVWF	bcdw1		;それをいったんbcdw1に保存
			BTFSC	bcdw1,7		;if 上桁<7 then next_skip
			MOVWF	bcdw0		;上桁を+3した上下桁をbcdw0に保存
			MOVF	bcdw0,W		;W_regに入れてリターン
			RETURN



;
;		数字コードを数値に変換
;
;		入出力はWreg
;		数字コード以外はFFHに変換
;
ASCTONUM
			movwf	wrk0
			movlw	030h		;'0'
			subwf	wrk0,W		;W=wrk0-W
			btfss	STATUS,C
			bra		NUMERR		;wrk0<W
			movwf	wrk1
			sublw	039h		;W=39H('9')-W　？？
			btfss	STATUS,C
			bra		NUMERR
			movf	wrk1,W
			return
NUMERR		retlw	0FFh

;
;       8ビットバイナリ　24倍演算（符号無整数)
;
;       W=W*24
;		エラー発生しても対処されないので、W=<10までで使用
;
MLT8_X24
			movwf	wrk0
			movwf	wrk1
			lslf	wrk0,F		;X2
			lslf	wrk0,F		;X4
			lslf	wrk0,F		;X8
			movf	wrk1,W
			addwf	wrk0,F
			addwf	wrk0,F
			addwf	wrk0,F
			addwf	wrk0,F		;X12
			lslf	wrk0,W		;X24
			return

;
;       16ビットバイナリ　2倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*2
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;
MLT16_X2
			bcf		STATUS,C	;Cフラグクリア
			rlf		hex0,F		;左ローテート（下位8ビット×２）
			rlf		hex1,F		;左ローテート（上位8ビット×２）
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了

;
;       16ビットバイナリ　12倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*12
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;		hexw(0-1)は破壊される
;
MLT16_X12
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			bcf		STATUS,C	;Cフラグクリア
			rlf		hex0,F		;左ローテート（下位8ビット×２）
			rlf		hex1,F		;左ローテート（上位8ビット×２）
			bcf		STATUS,C	;X4
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X8
			rlf		hex0,F		;
			rlf		hex1,F		;
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;元データを加算
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;元データを加算
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;元データを加算
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了


;
;       16ビットバイナリ　24倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*24
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;		hexw(0-1)は破壊される
;
MLT16_X24
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			bcf		STATUS,C	;Cフラグクリア
			rlf		hex0,F		;左ローテート（下位8ビット×２）
			rlf		hex1,F		;左ローテート（上位8ビット×２）
			bcf		STATUS,C	;X4
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X8
			rlf		hex0,F		;
			rlf		hex1,F		;
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;X9
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;X10
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;X11
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD16B		;X12
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
;
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			call	ADD16B		;X24
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了


;
;       16ビットバイナリ　16倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*16
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;
MLT16_X16
			bcf		STATUS,C	;Cフラグクリア
			rlf		hex0,F		;左ローテート（下位8ビット×２）
			rlf		hex1,F		;左ローテート（上位8ビット×２）
			bcf		STATUS,C	;X4
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X8
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X16
			rlf		hex0,F		;
			rlf		hex1,F		;
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了

;
;       16ビットバイナリ　32倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*32
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;
MLT16_X32
			bcf		STATUS,C	;Cフラグクリア
			rlf		hex0,F		;左ローテート（下位8ビット×２）
			rlf		hex1,F		;左ローテート（上位8ビット×２）
			bcf		STATUS,C	;X4
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X8
			rlf		hex0,F		;
			rlf		hex1,F		;
			bcf		STATUS,C	;X16
			rlf		hex0,F		;
			rlf		hex1,F		;
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
;
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			call	ADD16B		;X32
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了


;
;		16bitバイナリ　1/4除算(符号無整数）
;
;		hex(0-1)=hex(0-1)/4
;
DIV16_X4
			bcf		STATUS,C	;Cフラグクリア
			rrf		hex1,F		;右ローテート（上位8ビット÷２）
			rrf		hex0,F		;右ローテート（下位8ビット÷２）
			bcf		STATUS,C	;/4
			rrf		hex1,F		;
			rrf		hex0,F		;
			retlw	0h			;演算正常終了


;
;			16bitバイナリ除算（近似値）
;							Ver1.0
;		hex(0-1)=hex(0-1)÷hexw(0-1)
;		小数点以下は8bitまで演算(hexdに格納)、以下切り捨て
;		余りは出ない
;
;		使用ワーク
;		div0		商の下位8bit
;		div1		商の上位8bit
;		divw(0-1)	割られる数の演算途中保存
;		divw(2-3)	割る数の保存
;		hexd		商の小数点位以下8bit
;
DIV16B
			movf	hex0,W
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;割られる数hex(0-1)をdivw(0-1)に保存
			movf	hexw0,W		;割る数hexw(0-1)の保存
			movwf	divw2
			movf	hexw1,W
			movwf	divw3		;hexw(0-1)をdivw(2-3)に保存
			clrf	div0		;商の下位8bit
			clrf	div1		;商の上位8bit
			clrf	hexd		;商の小数点以下部

dv16b01		call	SUB16B		;hex(0-1)=hex(0-1)-hexw(0-1)
			iorlw	0h			;W=0演算成功、W=FFHボロー発生演算不可
			btfss	STATUS,Z
			bra		DV16U		;減算不可で小数点以下処理へ
;			まだ減算可、商加算
ADDIV01
			movlw	01h			;W=1
			addwf	div0,F		;div0=div0+1　div(0-1)は商
			movlw	01h			;この命令はフラグ変化しない
			btfsc	STATUS,C
			addwf	div1,F		;キャリー発生、div1=div1+1
			movf	hex0,W		;減算後のhex(0-1)をdivw(0-1)に保存
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;hex(0-1)をdivw(0-1)に保存
			bra		dv16b01
;			小数点以下の処理
DV16U
			movf	divw0,W		;減算不可のhex(0-1)をdivw(0-1)から引出
			movwf	hex0
			movf	divw1,W
			movwf	hex1		;
			call	MLT16_X16	;hex(0-1)=hex(0-1)×16
			movf	hex0,W		;16倍後のhex(0-1)をdivw(0-1)に保存
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;hex(0-1)をdivw(0-1)に保存
			movf	divw2,W		;割る数のhexw(0-1)をdivw(2-3)から引出
			movwf	hexw0
			movf	divw3,W
			movwf	hexw1		;
;			小数点以下1位の除算
dv16u01
			call	SUB16B		;hex(0-1)=hex(0-1)-hexw(0-1)
			iorlw	0h			;W=0演算成功、W=FFHボロー発生演算不可
			btfss	STATUS,Z
			bra		dv16u03		;減算不可で小数点以下2位処理へ
;			まだ減算可、商加算
dv16u02
			swapf	hexd,F
			movlw	01h			;W=1
			addwf	hexd,F		;div0=div0+1　div(0-1)は商
			swapf	hexd,F
			movf	hex0,W		;減算後のhex(0-1)をdivw(0-1)に保存
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;hex(0-1)をdivw(0-1)に保存
			bra		dv16u01
;			小数点以下2位の除算準備
dv16u03
			movf	divw0,W		;減算不可のhex(0-1)をdivw(0-1)から引出
			movwf	hex0
			movf	divw1,W
			movwf	hex1		;
			call	MLT16_X16	;hex(0-1)=hex(0-1)×16
			movf	hex0,W		;16倍後のhex(0-1)をdivw(0-1)に保存
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;hex(0-1)をdivw(0-1)に保存
			movf	divw2,W		;割る数のhexw(0-1)をdivw(2-3)から引出
			movwf	hexw0
			movf	divw3,W
			movwf	hexw1		;
;			小数点以下2位の除算
dv16u04
			call	SUB16B		;hex(0-1)=hex(0-1)-hexw(0-1)
			iorlw	0h			;W=0演算成功、W=FFHボロー発生演算不可
			btfss	STATUS,Z
			bra		dv16u05		;減算不可で小数点以下3位処理へ
;
			movlw	01h			;W=1
			addwf	hexd,F		;div0=div0+1　div(0-1)は商
			movf	hex0,W		;減算後のhex(0-1)をdivw(0-1)に保存
			movwf	divw0
			movf	hex1,W
			movwf	divw1		;hex(0-1)をdivw(0-1)に保存
			bra		dv16u04
;
dv16u05
			movf	div0,W
			movwf	hex0
			movf	div1,W
			movwf	hex1
			retlw	00h

exchd32
			movf	hex0,W
			movwf	div0
			movf	hex1,W
			movwf	div1
			movf	hex2,W
			movwf	div2
			movf	hex3,W
			movwf	div3

			movf	hexw0,W
			movwf	divw0
			movf	hexw1,W
			movwf	divw1
			movf	hexw2,W
			movwf	divw2
			movf	hexw3,W
			movwf	divw3
			return

excdh32
			movf	div0,W
			movwf	hex0
			movf	div1,W
			movwf	hex1
			movf	div2,W
			movwf	hex2
			movf	div3,W
			movwf	hex3

			movf	divw0,W
			movwf	hexw0
			movf	divw1,W
			movwf	hexw1
			movf	divw2,W
			movwf	hexw2
			movf	divw3,W
			movwf	hexw3
			return

exchd16
			movf	hex0,W
			movwf	div0
			movf	hex1,W
			movwf	div1

			movf	hexw0,W
			movwf	divw0
			movf	hexw1,W
			movwf	divw1
			return

excdh16
			movf	div0,W
			movwf	hex0
			movf	div1,W
			movwf	hex1

			movf	divw0,W
			movwf	hexw0
			movf	divw1,W
			movwf	hexw1
			return


;			32ビットバイナリ加算(整数符号無）
;
;		事前に(hex0-3)、(hexw0-3)に数値を入れておく事
;		演算結果でエラー(桁上がり）が発生しても対処はしない
;		hexw(0-3)は保存される
;
;		演算
;		hex(0-3) = hex(0-3) + hexw(0-3)
;

ADD32B
			movf	hexw0,W		;hex0=hex0+hexw0
			addwf	hex0,F		;桁上がりでC=1
			movlw	01h			;この命令はフラグ変化しない
			btfss	STATUS,C	;if c=1 then hex1=hex1+1
			goto	ad31		;桁上がり無
;			(hex0+W)に桁上がり発生、処理
			addwf	hex1,F		;hex1=hex1+1
			btfsc	STATUS,C	;桁上がり無なら、goto ad31
			addwf	hex2,F		;桁上がり発生、hex2=hex2+1
			btfsc	STATUS,C	;桁上がり無なら、goto ad31
			addwf	hex3,F		;桁上がり発生、hex3=hex3+1
								;ここで桁上がり発生しても対処しない
ad31		movf	hexw1,W
			addwf	hex1,F
			movlw	01h
			btfsc	STATUS,C
			addwf	hex2,F
			btfsc	STATUS,C
			addwf	hex3,F

ad32		movf	hexw2,W
			addwf	hex2,F
			movlw	01h
			btfsc	STATUS,C
			addwf	hex3,F
			movf	hexw3,W
			addwf	hex3,F
			retlw	0h


;
;
;			32ビットバイナリ減算(整数符号無)
;
;		事前にhex(0-3)、hexw(0-3)に数値を入れておく事
;		演算結果でエラー(マイナス）の場合W=1、OKの時はW=0でリターン
;		W=FFHの場合、演算結果は保障されない
;		hexw(0-3)は保存される
;
;		演算
;		hex(0-3) = hex(0-3) - hexw(0-3)
;

SUB32B
;			hex0-hexw0の減算
			movf	hexw0,W		;hex0=hex0-W(hexw0)
			subwf	hex0,F		;W>HEX0の時、ボロー(C=0)
								;W<=HEX0の時、無(C=1)
			movlw	01h			;この命令はフラグ変化しない
			btfss	STATUS,C	;C=1なら、hex1-hexw1へ
;			(hex0-W)にボロー発生、hex1に桁借り処理
			subwf	hex1,F		;hex1=hex1-1
			btfss	STATUS,C	;C=1なら、goto sb31
			subwf	hex2,F		;(hex1-1)にボロー発生、hex2に桁借り
			btfss	STATUS,C	;C=1なら、goto sb31
			subwf	hex3,F		;(hex2-1）ボロー発生、hex3に桁借り
			btfss	STATUS,C
			retlw	0FFh		;hex3にボロー発生、エラー終了

;			hex1-hexw1の減算
sb31		movf	hexw1,W		;
			subwf	hex1,F
			movlw	01h
			btfss	STATUS,C
			subwf	hex2,F
			btfss	STATUS,C
			subwf	hex3,F
			btfss	STATUS,C
			retlw	0FFh
;			hex2-hexw2の減算
			movf	hexw2,W
			subwf	hex2,F
			movlw	01h
			btfss	STATUS,C
			subwf	hex3,F
			btfss	STATUS,C
			retlw	0FFh
;			hex3-hexw3の減算
			movf	hexw3,W
			subwf	hex3,F
			btfss	STATUS,C
			retlw	0FFh
			retlw	0h

;		16ビットバイナリ加算　ver1.2(バグ修正版)
;		hex(0-1)=hex(0-1)+hexw(0-1)
;		W=0の時、正常終了
;		W=FFHの時、エラー発生（キャリー）、演算結果は保障されない
;		hexw(0-1)は保存される
ADD16B
			movf	hexw0,W		;W=hexw0
			addwf	hex0,F		;hex0=hex0+hexw0
			movlw	01h			;この命令はフラグ変化しない
			btfss	STATUS,C
			goto	ad11		;キャリー無で次の加算
			addwf	hex1,F		;キャリー発生、hex1=hex1+1
			btfsc	STATUS,C
			retlw	0FFH			;桁上がり発生、加算エラー終了
ad11		movf	hexw1,W		;W=hexw1
			addwf	hex1,F		;hex1=hex1+hexw1
			btfsc	STATUS,C
			retlw	0FFH		;キャリー発生、加算エラー終了
			retlw	0h			;加算正常終了


;		16ビットバイナリ減算　Ver1.1(バグ修正版)
;		hex(0-1)=hex(0-1)-hexw(0-1)
;		W=0の時、正常終了
;		W=FFHの時、エラー発生（ボロー）、演算結果は保障されない
;		hexw(0-1)は保存される
SUB16B
			movf	hexw0,W		;W=hexw0
			subwf	hex0,F		;hex0=hex0-hexw0
			movlw	01h			;フラグ変化しない
			btfsc	STATUS,C
			goto	sb11		;ボロー無で次の減算
			subwf	hex1,F		;ボロー発生、hex1=hex1-1
			btfss	STATUS,C
			retlw	0FFH			;ボロー発生、減算エラー終了

sb11		movf	hexw1,W		;W=hexw1
			subwf	hex1,F		;hex1=hex1-hexw1
			btfss	STATUS,C
			retlw	0FFh		;ボロー発生、減算エラー終了
			retlw	0h			;減算正常終了



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			指定ディレイ　ミリセカンド　32MHZ
;
;		delay0、delay1の16bitで指定
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DELAY_MS
			movf	delay1,W
			iorwf	delay0,W
			btfsc	STATUS,Z
			retlw	0h
dms01
			movlw	01h			;フラグ変化しない
			subwf	delay0,F	;delay0=delay0-1
			btfss	STATUS,C	;
			bra		dms02		;ボロー発生,桁下がり処理へ
			call	wait1m
			bra		dms01

dms02		movlw	01h			;
			subwf	delay1,F	;delay1=delay1-1
			btfss	STATUS,C
			retlw	0h			;ボロー発生、正常終了
			call	wait1m		;dalay0=256の補正
			movlw	0ffh
			movwf	delay0		;delay0=255
			bra		dms01		;





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン	32MHZ用
;
;		1cycle	= 0.125us
;		使用レジスタ	= cnt2,cnt3
;		BSR		=0(BANK0)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u						;呼び出しも含めて、100us
								;call is 2cycles
			clrf	BSR
			movlw	09h			;1
			movwf	cnt2		;1
			movlb	0h
;			nop
			nop					;3
w100u		nop					;
			call	wait10u		;10*9=90us(ここだけ命令ステップを数えない）
			decfsz	cnt2,F		;4*8+3=31cycles
			goto	w100u
			return				;2+5+31+2=40cycles=20us

wait50u							;呼び出しも含めて、50us
			call	wait25u
wait25u							;呼び出しも含めて、25us
			clrf	BSR
			call	wait10u
			call	wait10u
			movlw	0bh			;5us=0.125us*40cycles
			movwf	cnt2		;
w25u		decfsz	cnt2,F		;ループ 2+10*3+2=34cycles
			goto	w25u
;			nop
			nop
			return				;2+34+2+2=40cycles=5us

wait5m							; 5ms
			clrf	BSR
			movlw	05h
			movwf	cnt2
w5m			call	wait1m
			decfsz	cnt2,F
			goto	w5m
			return

wait10m							; 10ms
			clrf	BSR
			movlw	d'10'
			movwf	cnt2
w10m		call	wait1m
			decfsz	cnt2,F
			goto	w10m
			return

wait20m							; 20ms
			clrf	BSR
			movlw	d'20'
			movwf	cnt2
w20m		call	wait1m
			decfsz	cnt2,F
			goto	w20m
			return
wait50m							; 50ms
			clrf	BSR
			movlw	d'50'
			movwf	cnt2
w50m		call	wait1m
			decfsz	cnt2,F
			goto	w50m
			return

wait100m						; 100ms
			clrf	BSR
			movlw	d'100'
			movwf	cnt2
w100m		call	wait1m
			decfsz	cnt2,F
			goto	w100m
			return

wait500m						; 500ms
			clrf	BSR
			movlw	05h
			movwf	cnt3
w500m		call	wait100m
			decfsz	cnt3,F
			goto	w500m
			return

wait1s							; 1s
			clrf	BSR
			movlw	d'10'
			movwf	cnt3
w1s			call	wait100m
			decfsz	cnt3,F
			goto	w1s
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1ms 基本ウェイト
;			呼び出しを含めて1msとなる。
;
;		clock	= 32MHz(0.03125usec)
;		1cycle	= 0.125usec
;		1ms		= 0.125usec * 8000cycles
;
;			使用変数　cnt0,cnt1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait1m
			clrf	BSR
			movlw	08h
			movwf	cnt0		;
;			外周ループ
w1m0		movlw	0c7h		;199d
			movwf	cnt1		;
;			内周ループ
w1m1		nop					;
			nop					;5cycles*cnt1
			decfsz	cnt1,F		;2+5*198+4=996c/s
			goto	w1m1		;
;
			decfsz	cnt0,F		;
			goto	w1m0		;2+7*999+998=7993cycles
			nop
			return					;other=(3+4)cycles
									;Total 8000*0.125us=1ms


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10us 基本ウェイト
;			呼び出し（call　w10u)も含めて、10usとなる。
;
;		clock	= 32MHZ(0.03125us)
;		1cycle	= 0.125us
;		10us	= 0.125us * 80cycles
;		使用変数　cnt0,cnt1
;		'goto','call','return'は2サイクル消費する
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait10u
			clrf	BSR
			movlw	018h		;18H=24
			movwf	cnt0		;
w10u0		decfsz	cnt0,F		;3*23+2=71
			goto	w10u0		;
			nop
			nop
			return				;2+3+71+2+2=80cycles

wait05u
			clrf	BSR
			movlw	0bh			;5us=0.125us*40cycles
			movwf	cnt0		;
w05u0		decfsz	cnt0,F		;ループ 2+3*10+2=34cycles
			goto	w05u0
;			nop
			nop
			return				;2+34+2+2=40cycles=5us

wait02u
			clrf	BSR
			movlw	04h			;2us=0.125us*16cycles
			movwf	cnt0		;
w02u0		decfsz	cnt0,F		;2+3*3+2+1+2=16cycles
			goto	w02u0
;			nop
			return				;
wait01u
			clrf	BSR			;1us=0.125us*8cycles
			nop					;2+4+2=8cycles
			nop
			nop
			return

			END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン
;
;		clock	= 8MHz(0.125us)
;		1cycle	= 0.5us
;		使用レジスタ	= cnt0,cnt1,cnt2,cnt3
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u						;呼び出しも含めて、100us
								;call is 2cycles
			movlw	09h			;1
			movwf	cnt2		;1
			nop
			nop
			nop					;3
w1u			nop					;
			call	wait10u		;10*8=80us(ここだけ命令ステップを数えない）
			decfsz	cnt2,F		;4*7+3=31cycles
			goto	w1u
			return				;2+5+31+2=40cycles=20us

wait50u							;呼び出しも含めて、50us
			call	wait25u
wait25u							;呼び出しも含めて、25us
			call	wait10u
			call	wait10u
			nop					;5us=0.5us*10cycles			
			nop					;
			nop
			nop
			nop
			nop
			return				;2+6+2=10cycles=5us

wait2m
			movlw	02h
			movwf	cnt2
w2m			call	wait1m
			decfsz	cnt2,F
			goto	w2m
			return

wait5m							; 5ms delay
			movlw	05h
			movwf	cnt2
w5m			call	wait1m
			decfsz	cnt2,F
			goto	w5m
			return

wait10m							; 10ms delay
			movlw	d'10'
			movwf	cnt2
w10m		call	wait1m
			decfsz	cnt2,F
			goto	w10m
			return

wait20m							; 20ms delay
			movlw	d'20'
			movwf	cnt2
w20m		call	wait1m
			decfsz	cnt2,F
			goto	w20m
			return
wait50m							; 50ms delay
			movlw	d'50'
			movwf	cnt2
w50m		call	wait1m
			decfsz	cnt2,F
			goto	w50m
			return

wait100m						; 100ms delay
			movlw	d'100'
			movwf	cnt2
w100m		call	wait1m
			decfsz	cnt2,F
			goto	w100m
			return

wait500m						; 500ms delay
			movlw	05h
			movwf	cnt3
w500m		call	wait100m
			decfsz	cnt3,F
			goto	w500m
			return

wait1s							; 1s delay
			movlw	d'10'
			movwf	cnt3
w1s			call	wait100m
			decfsz	cnt3,F
			goto	w1s
			return

;			Wregで指定した回数10msウェイトルーチンを呼び出す
waitx
			movwf	work1		;
wtx			call	wait10m
			decfsz	work1
			goto	wtx
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1ms 基本ウェイト 
;
;		clock	= 8MHz(0.125usec)
;		1cycle	= 0.5usec
;		1ms		= 0.5usec * 2000cycles
;
;		# 'goto' and 'call' and 'return' - 2cycles
;			使用変数　cnt0,cnt1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait1m
			movlw		02h
			movwf		cnt0		;
;			外周ループ
d1m0		movlw		0c7h		;199d
			movwf		cnt1		;
;			内周ループ
d1m1		nop						;
			nop						;5cycles*cnt1
			decfsz		cnt1,F		;5*199=995c/s
			goto		d1m1		;
;
			decfsz		cnt0,F		;(d1m1-1+3)*cnt0
			goto		d1m0		;(995-1+5)*2=1998cycles
			return					;other=3cycles
									;Total 2001*0.5usec=約1ms

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10us 基本ウェイト
;			呼び出しも含めて、10usとなる。
;
;		clock	= 8MHZ(0.125us)
;		1cycle	= 0.5us
;		10us	= 0.5us * 20cycles
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

									;"call" inst = 2cycles
wait10u
			movlw		05h			;1
			movwf		cnt0		;1
d10u0								;3*4+2=14
			decfsz		cnt0,F		;
			goto		d10u0		;
			return					;2+1+1+14+2=20cycles
