;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		ＰＯＷＥＲ ＭＯＳ ＦＥＴ 制御プログラム
;								Ver1.0	JA0QON
;
;		4桁7セグLEDの動作(0-9999表示)
;			OPA1を使用した0-2Aまでの電流計(ADC1ルーチン)
;				0-1Aまでは1mAの解像度
;				1-2Aは2mAの解像度
;			OPAxを使用しない0-4Aまでの電流計(拡張モード時、ADC2ルーチン)
;				0-2Aまでは2mAの解像度
;				2-4Aは4mAの解像度
;		ドレイン電流制限動作(電流制限時は定電流動作)
;			ADC3ルーチンによる制限電流値の可変設定
;				通常モード時は0-2027mA
;				拡張モード時は0-4097mA
;			ドレイン電流値と制限電流値の比較
;			DAC1によるゲート電圧制御
;
;		PIC16F1709 32MHZ 内部発振
;		POWER MOS FET	EKI04047
;		電流センサ	1 OHM
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LIST	P=PIC16F1709
    INCLUDE	P16F1709.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
;演算用ワーク
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
;7segLED処理専用ワーク
ZBK			equ		043H		;桁位置＆ゼロブランキング
SEG0		equ		044H		;セグメントデータ
SEG1		equ		045H		;
SEG2		equ		046H		;
SEG3		equ		047H		;
SEG4		equ		048H
SEG5		equ		049H
SEG6		equ		04AH
SEG7		equ		04BH
MODE		equ		04CH
ON_TIME1	equ		04DH
OFF_TIME0	equ		04EH
OFF_TIME1	equ		04FH
;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
;DAC用配列データアクセス用ワーク
FDA0		equ     060h        ;電流値下位8ビット
FDA1		equ     061h        ;電流値上位8ビット
FDB0		equ		062H
FDB1		equ		063H
DAC_DATA0	equ		064H        ;DACデータテーブルNO過去データ
DAC_DATA1	equ		065H        ;DACデータテーブルNO現在データ
PSDT0		equ		066H        ;プリスケーラ過去データ
PSDT1		equ		067H        ;プリスケーラ現在データ
fdw0		equ		068H        ;専用ワーク
fdw1		equ		069H        ;専用ワーク
;ADC用ワーク
ADC_DATA0	equ		06AH		;10bitADC取得下位8bitデータ
ADC_DATA1	equ		06BH		;10bitADC取得上位2bitデータ
;割込みルーチン内広域変数保存用
ISRW0		equ		06CH
ISRW1		equ		06DH
ISRW2		equ		06EH
ISRW3		equ		06FH
;共通RAM領域
ISQ			equ		070h		;ISR内処理指示フラグ
IRS			equ		071h		;TMR0 リスタートデータ
IPS         equ     072h        ;TMR0 プリスケーラ設定データ
IWK			equ		073H		;一時保存
;
			ORG		0h			;リセットベクタ
			goto	init
			ORG		04h			;割り込みベクタ

;
;		ＰＩＣ１６Ｆ１７０９　３２ＭＨＺ ＩＳＲ
;       ７セグＬＥＤダイナミック制御処理
;
;       使用ワーク
;		IRS		TMR0リスタートデータ
;		IPS		プリスケーラ データ
;		ISQ		処理指示フラグ
;		IWK		処理ワーク
;		SEG1	1桁目セグデータ
;		SEG2	2桁目セグデータ
;		SEG3	3桁目セグデータ
;		SEG4	4桁目セグデータ

;
;		使用ポート
;		RC0		SEG_A
;		RC1		SEG_B
;		RB6		SEG_C
;		RB7		SEG_D
;		RC4		SEG_E
;		RC5		SEG_F
;		RC6		SEG_G
;		RA0-RA1
;				00=1桁目選択
;				01=2桁目選択
;				10=3桁目選択
;				11=4桁目選択
INT
;			処理する7セグLEDへ分岐
			movlb	0h			;BANK0
			movlw	04H			;
			xorwf	ISQ,W
			btfsc	STATUS,Z	;
			bra		CLM4
			movlw	03H
			xorwf	ISQ,W
			btfsc	STATUS,Z
			bra		CLM3
			movlw	02H
			xorwf	ISQ,W
			btfsc	STATUS,Z
			bra		CLM2
			movlw	01H
			xorwf	ISQ,W
			btfsc	STATUS,Z
			bra		CLM1
			movlw	0H
			xorwf	ISQ,W
			btfsc	STATUS,Z
			bra		CLM0
			clrf	ISQ			;ERR
			bra		INTOUT
;
CLM4
			movlb	02H			;LAT_BANK
			bsf		LATA,0
			bsf		LATA,1		;SEL LED4
			clrf	BSR
			movf	SEG4,W
			movwf	IWK
			bra		SEG_OUT
;
CLM3
			movlb	02H			;LAT_BANK
			bcf		LATA,0
			bsf		LATA,1		;SEL LED3
			clrf	BSR
			movf	SEG3,W
			movwf	IWK
			bra		SEG_OUT
;
CLM2
			movlb	02H			;LAT_BANK
			bsf		LATA,0
			bcf		LATA,1		;SEL LED2
			clrf	BSR
			movf	SEG2,W
			movwf	IWK
			bra		SEG_OUT
;
CLM1
			movlb	02H			;LAT_BANK
			bcf		LATA,0
			bcf		LATA,1		;SEL LED1
			clrf	BSR
			movf	SEG1,W
			movwf	IWK
			bra		SEG_OUT
;
CLM0
			movlw	05H
			movwf	ISQ			;ISQリセット
			movlw	0FFH
			movwf	IWK			;BLANK
;			bra		SEG_OUT
;
SEG_OUT
			movlb	02H

SEGA		btfss	IWK,0
			bra		SEGA0
SEGA1		bsf		LATC,0
			bra		SEGB
SEGA0		bcf		LATC,0

SEGB		btfss	IWK,1
			bra		SEGB0
SEGB1		bsf		LATC,1
			bra		SEGC
SEGB0		bcf		LATC,1

SEGC		btfss	IWK,2
			bra		SEGC0
SEGC1		bsf		LATB,6
			bra		SEGD
SEGC0		bcf		LATB,6

SEGD		btfss	IWK,3
			bra		SEGD0
SEGD1		bsf		LATB,7
			bra		SEGE
SEGD0		bcf		LATB,7

SEGE		btfss	IWK,4
			bra		SEGE0
SEGE1		bsf		LATC,4
			bra		SEGF
SEGE0		bcf		LATC,4

SEGF		btfss	IWK,5
			bra		SEGF0
SEGF1		bsf		LATC,5
			bra		SEGG
SEGF0		bcf		LATC,5

SEGG		btfss	IWK,6
			bra		SEGG0
SEGG1		bsf		LATC,6
			bra		SEGH
SEGG0		bcf		LATC,6

SEGH		clrf	BSR
			decf	ISQ,F

INTOUT
;			TMR0リスタート処理
;		Fosc=32MHZで1inst=0.125us
;		PS=32で32us×32=1024us
;		TIMER0は約1msに再セット

;			movlw	07H
;			andwf	IPS,F		;bit3-7をクリア
;			movlb	01h			;OPTION_REG
;			movf	OPTION_REG,W
;			clrf	BSR
;			iorwf	IPS,W
;			movlb	01H
;			movwf	OPTION_REG	;PS値を再セット（基本的に不要）
;           movf	IRS,W		;TMR0リスタート情報(今回はIRS=0)
;			movwf	TMR0		;TMR0書込
			clrf	TMR0		;実験なので1ms固定、今回はこれだけ
			bcf		INTCON,TMR0IF
			retfie				;




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			PIC16F1709　イニシャライズ
;
;		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）
;			bit5	RA5		GPI/O,CLKIN
;			bit4	RA4		GPI/O,AN3
;			bit3	RA3		Degital Input Only
;			bit2	RA2		GPI/O,AN2,DAC1OUT2
;			bit1	RA1		GPI/O,AN1
;			bit0	RA0		GPI/O,AN0,DAC1OUT
;
;		PORTB(BANK0　00DH）
;			bit7	RB7		GPI/O
;			bit6	RB6		GPI/O,SCL
;			bit5	RB5		GPI/O,AN11,OPA1IN+
;			bit4	RB4		GPI/O,AN10,OPA1IN-,SDA
;			bit0-3	Unimplemented(read=0)
;
;		PORTC(BANK0　00EH）
;			bit7	RC7		GPI/O,AN9,OPA2IN+
;			bit6	RC6		GPI/O,AN8,OPA2IN-
;			bit5	RC5		GPI/O
;			bit4	RC4		GPI/O
;			bit3	RC3		GPI/O,AN7,OPA2OUT
;			bit2	RC2		GPI/O,AN6,OPA1OUT
;			bit1	RC1		GPI/O,AN5
;			bit0	RC0		GPI/O,AN4
;
;		TRISA(BANK1　08CH)
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	1=入力、0=出力
;			bit3	RA3		常に1
;			bit2	RA2-0	1=入力、0=出力
;
;		TRISB(BANK1 08DH)
;			bit4-7	RA5-4	1=入力、0=出力
;			bit0-3	Unimplemented(read=0)
;
;		TRISC(BANK1　08EH)
;			bit0-7	RC0-7	1=入力、0=出力
;
;		LATA(BANK2　10CH)　データラッチレジスタ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	出力データ保持
;			bit3	Unimplemented(read=0)
;			bit2	RA2-0	出力データ保持
;		（このラッチデータはTRISAレジスタ設定で各ピンに反映される）
;
;		LATB(BANK2 10DH)
;			bit4-7	RB4-7	出力データ保持
;			bit0-3	Unimplemented(read=0)
;		（このラッチデータはTRISBレジスタ設定で各ピンに反映される）
;
;		LATC(BANK2　10EH)　データラッチレジスタ
;			bit0-7	RC0-7	出力データ保持
;		（このラッチデータは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(アナログ入力)となっている
;
;		ANSELB(BANK3 18DH)
;			bit7-6	Unimplemented(read=0)
;			bit5-4	ANSB5-4/RB5-4	アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			bit3-0	Unimplemented(read=0)
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;		ANSELC(BANK3　18EH)
;			bit0-7	ANSC5-0/RC5-0アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;		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　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モジュール
;
;       オペアンプ制御レジスタ(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
;			各レジスタ初期設定(PIC16F1709)
			movlb	0h			;BANK0
			movlw	020h		;00100000B
			movwf	INTCON		;全割込みOFF、タイマ0割込みON
			clrf	PORTA		;Init PORT
			clrf	PORTB
			clrf	PORTC
			;クロック
			movlb	01h			;BANK１
			movlw	0f0h		;1111000B
			movwf	OSCCON		;内部発振器は8MHZに設定
								;4xPLL=ON
			;TMR0およびプルアップ
			movlw	084H		;10000100b
			movwf	OPTION_REG	;プルアップOFF
								;割込みエッジ↓
								;クロックソース内部（Fosc/4）
								;TMR0カウントエッジ↓
								;プリスケーラ割当→TMR0
								;プリスケーラ分周1/32にセット
			;10ビットADC
			movlw	0A3H		;10100011B
			movwf	ADCON1		;右詰め、基準電圧FVR
								;ADCクロック　Fosc/32=1us(32MHZ)

			;I/Oポート(TRIS→BANK1、ANSEL→BANK3)
				;RA0,1	HC138へデジタル出力
				;RA2	ADCアナログ入力
				;RA3	MODE_SW デジタル入力
				;RA4	ADCアナログ入力
				;RA5	LED デジタル出力
				;RB4	OPA1IN- アナログ入力
				;RB5	OPA1IN+ アナログ入力
				;RB6,7	7セグ デジタル出力
				;RC0-1	7セグ デジタル出力
				;RC2	OPA1OUT アナログ入力
				;RC3	OPA2OUT アナログ入力
				;RC4-6	7セグ デジタル出力
				;RC7	ADCアナログ入力(重負荷接続注意、デジタル出力禁止)
			movlw	01CH		;00011100B
			movwf	TRISA		;RA0,1,5出力、RA2,3,4入力

			movlw	030H		;00110000B
			movwf	TRISB		;RB4,5入力、RB6,7出力

			movlw	08CH		;10001100B
			movwf	TRISC		;RC0-1出力、RC2,3,7入力、RC4-6出力

			movlb	03h			;BANK3
			movlw	014H		;00010100B
			movwf	ANSELA		;RA0,1,3,5デジタル、RA2,4アナログ

			movlw	030H		;00110000B
			movwf	ANSELB		;RB6,7デジタル、RB4,5アナログ

			movlw	08CH		;10001100B
			movwf	ANSELC		;RC0,1,4-6=デジタル、RC2,3,7アナログ
;
			;FVR(BANK2)
			movlb	02h			;BANK2
			movlw	082h		;10000010B
			movwf	FVRCON		;FVRイネーブル
								;DACとCPSに対してOFF
								;ADCには2.048V

			;8ビットDAC1(BANK2)
			movlw	080h		;10000000B
			movwf	DAC1CON0	;DAC1イネーブル
			movlb	0h			;基準電圧はVDD
                                 ;DACOUTピン切り離し

			;オペアンプ1(BANK10)
			movlb	0AH			;BANK10
			movlw	080H		;10000000B
			movwf	OPA1CON		;OPA1イネーブル
								;反転入力にOPA1IN-ピンを接続
								;低GBWPモード
								;非反転入力にOPA1IN+ピンを接続
			;オペアンプ2(BANK10)
			movlw	0D2H		;11010010B
			movwf	OPA2CON		;OPA2イネーブル
								;高GBWPモード、ユニティゲイン
								;OPA1出力を反転入力に接続(電圧バッファ）
								;非反転入力にDAC1出力を接続
;			注意	オペアンプ出力ピンもアナログ入力に設定する事

			;初期設定終了
			clrf	BSR

;
;		メインプログラム
;
;	下記フラグバイトが各サブルーチンの動作を指示します
;
;	MODE
;		bit7		警告LED
;						1=LED発光
;						0=LED消灯
;		bit6		動作モード
;						1=4Aモード(定格越え設定、使用は危険です)
;						0=2Aモード(標準設定)
;		bit5-3		予約
;		bit2		DAC1値
;						1=FFH未満(電流制限動作中)
;						0=FFH(MAX_Bias_Voltage)
;		bit1		FVR設定
;						1=4.096V
;						0=2.048V
;		bit0		7セグLED表示ソース
;						1=制限電流値表示
;						0=ドレイン電流値表示
coldst
;			デフォルト設定
			clrf	FDA0
			clrf	FDA1
			movlw	0B0H		;電流制限初期値
			movwf	FDB0
			movlw	04H
			movwf	FDB1		;FDBX=04B0H=1200mA
			clrf	hex0
			clrf	hex1
			clrf	hex2
			clrf	hex3
			movlw	05H
			movwf	ISQ
			movlw	014H
			movwf	fdw0		;メインループ 進行カウンタ
			call	SET_MODE	;動作モード初期値(電源ON時のみ有効)
								;MODE_SW=ONで拡張モード
								;MODE_SW=OFFで通常モード
			bsf		INTCON,GIE	;割り込み開始

mloop		;メインループ
			call	SET_CCUR	;FDB(0-1)電流制限設定値
			call	GET_CUR		;FDA(0-1)現在電流値
			call	LMCUR		;FETバイアス制御
			call	SET_LED		;警告LED点灯処理
			call	wait5m
			decfsz	fdw0,F
			goto	mloop
			movlw	014H		;カウンタ リセット
			movwf	fdw0
			;ディスプレイ表示値更新
			call	GET_SW1		;DISP_MODE_SW
			call	SET_SEG		;FDA(0-1)値あるいはFDB(0-1)値を表示
;			call	wait100m
			goto	mloop

;			警告LED発光処理
SET_LED
			btfss	MODE,6		;LED_FLG
			bra		sld02
sld01		movlb	02H			;BANK02
			bcf		LATA,5		;LED_ON
			clrf	BSR
			return
sld02		movlb	02H
			bsf		LATA,5		;LED_OFF
			clrf	BSR
			return

;
SET_MODE
			clrf	MODE
			call	GET_SW1
			iorlw	0H
			btfsc	STATUS,Z
			return
			bsf		MODE,7
			return


;
;			現在電流値取得サブルーチン
;
;		出力		FDA(0-1)16bit電流値
;
GET_CUR
			btfsc	MODE,7
			goto	CUR4M
CUR2M		;通常モード(最大2Aモード)
			call	GET_ADC1	;hex0-1=OPA1_OUTPUT
			call	HEXFDA		;FDA0-1=hex0-1
			return
CUR4M		;最大4Aモード
			call	GET_ADC2
			call	HEXFDA
			return

;
;			定電流値設定サブルーチン
;
;		出力	FDB(0-1)定電流値
;
SET_CCUR
			call	GET_ADC3		;hex(0-1)=0-1023
			btfsc	MODE,7			;EX_MODE
			call	MLT16_X2
			call	MLT16_X2		;hex(0-1)=0-2046 (2/step)
			movf	hex0,W
			movwf	FDB0
			movf	hex1,W
			movwf	FDB1
			return

;
;			電流制限処理サブルーチン
;
;		入力	FDA(0-1)現在電流値
;				FDB(0-1)制限電流値
;		DAC1処理用ワーク
;				DAC_DATA0
;				DAC_DATA1
;		＊この処理の前に必ず新規電圧測定が必要
;		制限電流が10mA以下の時は機能OFFとする
;
LMCUR
			movf	FDB1,W
			iorlw	0H
			btfss	STATUS,Z
			bra		lcr01
			movf	FDB0,W
			sublw	09H			;W=K-W
			btfss	STATUS,C
			bra		lcr01
			;FDB(0-1)<10mA以下の処理
			movlb	02H
			clrf	DAC1CON1
			clrf	BSR
			bsf		MODE,2		;DAC1
			bsf		MODE,6		;LED_ON
			return
lcr01		call	FDAHEX		;hex(0-1)=FDA(0-1)
			movf	FDB0,W
			movwf	hexw0
			movf	FDB1,W
			movwf	hexw1		;hexw(0-1)=FDB(0-1)
			call	SUB16B
			iorlw	0H
			btfss	STATUS,Z
			bra		CURUP		;演算ボローなので現在電流は制限電流以下
CURDWN		;バイアス電圧下降処理
			movlb	02H			;BANK02
			movf	DAC1CON1,W
			clrf	BSR
			movwf	DAC_DATA0
			decf	DAC_DATA0,W
			movwf	DAC_DATA1
			movlb	02H
			movwf	DAC1CON1
			clrf	BSR
			bsf		MODE,2		;DAC1最大値フラグ、0=最大値、1=未満
			bsf		MODE,6		;LED_ON
			return
CURUP		;バイアス電圧上昇処理
			btfss	MODE,2
			bra		CURUP02		;DAC1=FFH
			movlb	02H			;BANK02 DAC1<FFH
			movf	DAC1CON1,W
			clrf	BSR
			movwf	DAC_DATA0
			incf	DAC_DATA0,W
			movwf	DAC_DATA1
			movlb	02H
			movwf	DAC1CON1
			clrf	BSR
			xorlw	0FFH
			btfss	STATUS,Z
			return
			bcf		MODE,2		;DAC1最大値フラグ、0=最大値、1=未満
			bcf		MODE,6		;LED_OFF
			return
CURUP02		;フラグが0(最大値出力)なのに制限電流以下、DAC出力最大
			movlb	02H			;
			movlw	0FFH
			movwf	DAC1CON1
			clrf	BSR
			bcf		MODE,6		;LED_OFF
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
;			Ａ／Ｄ変換サブルーチン(PIC16F1709)
;
;		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コンバータ停止
;
;		使用ワーク
;			ADC_DATA0	10bit取得データ下位8bit
;			ADC_DATA1	10bit取得データ上位2bit
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;			ADC1 OPA1出力電圧取得
;
;		基準電圧はFVR(2.048V or 4.096V)
;		入力チャンネルはRA4/AN3
;		出力は10bitでhex0-hex1の16bitに右詰で格納
;		解像度はMODEのbit1で判定
;		FVR2Vで2mV/digitだが、OPA1で2倍しているため、1mV/digit
;		FVR4Vでは4mV/digitが2mV/digit
GET_ADC1
			movlb	01h			;BANK1
			movlw	0Dh			;00001101b
								;右詰め、基準電圧FVR、
								;AN3(RA4)選択、ADON_ON
			movwf	ADCON0		;電圧サンプリング開始
			clrf	BSR
			call	wait10u		;サンプリング電圧安定化待ち
			call	wait10u
			movlb	01h
			bsf		ADCON0,GO	;A/D変換開始指令
aloop1
			btfsc	ADCON0,GO	;A/D変換完了待ち
			goto	aloop1		;GO=0ならば次へ
			movf	ADRESH,W	;データ上位８ビット
			clrf	BSR
			movwf	ADC_DATA1
			movlb	01H
			movf	ADRESL,W
			bcf		ADCON0,ADON	;A/DコンバータOFF
			movlb	0h
			movwf	ADC_DATA0		;
			movlw	03H
			andwf	ADC_DATA1,F		;上位6bit
			;hex(0-1)にデータをコピー
			movf	ADC_DATA0,W
			movwf	hex0			;
			movf	ADC_DATA1,W
			movwf	hex1			;
;		FVR電圧切替
;
;		HEXx=>1020mV(1000,3FCH,FVR2モード)でFVR4に切り替え
;		HEXx=<970mV(485,1E5H,FVR4モード)でFVR2に切り替え
GAD1M01
			btfsc	MODE,1
			bra		GAD1M04
			;FVR2モードで1020mV以上かチェック
			movlw	0FBH
			movwf	hexw0
			movlw	03H
			movwf	hexw1		;hexw(0-1)=03FBH(1019mV)
			call	SUB16B		;hex(0-1)=hex(0-1)-hexw(0-1)
			iorlw	0H			;Wreg=0なら正常減算、0以外ならボロー
			btfss	STATUS,Z	;Z=1なら1020mV以上、Z=0なら1019mV以下
			bra		GAD1M05		;モード内数値で切り替え不要
			;FVR4モードにして電圧再取得
			call	SET_FVR4
			goto	GET_ADC1
			;FVR4モードで970mV以下かチェック
GAD1M04		movlw	0E6H
			movwf	hexw0
			movlw	01H
			movwf	hexw1		;hexw(0-1)=01E6H(971mV)
			call	SUB16B
			iorlw	0H
			btfsc	STATUS,Z	;Z=0なら970mV以下、Z=1なら971mV以上
			bra		GAD1M05		;モード内数値で切り替え不要
			;FVR2モードで電圧再取得
			call	SET_FVR2
			goto	GET_ADC1

GAD1M05		;数値補正
			movf	ADC_DATA0,W
			movwf	hex0			;
			movf	ADC_DATA1,W
			movwf	hex1			;
			btfss	MODE,1		;FVR_FLG,0=2V,1=4V
			return				;FVR=2V
			;FVR=4V,2mV/dig
			call	MLT16_X2
			return

;			ADC2 電流センサ(1Ω抵抗)出力電圧取得
;
;		基準電圧はFVR(2.048V or 4.096V)
;		入力チャンネルはRC7/AN9
;		出力は10bitでhex0-hex1の16bitに右詰で格納
;		FVR2Vで2mV/digit
;		FVR4Vでは4mV/digit
GET_ADC2
			movlb	01h			;BANK1
			movlw	025h		;00100101b
								;右詰め、基準電圧FVR、
								;AN9(RC7)選択、ADON_ON
			movwf	ADCON0		;電圧サンプリング開始
			clrf	BSR
			call	wait10u		;サンプリング電圧安定化待ち
			call	wait10u
			movlb	01h
			bsf		ADCON0,GO	;A/D変換開始指令
aloop2
			btfsc	ADCON0,GO	;A/D変換完了待ち
			goto	aloop2		;GO=0ならば次へ
			movf	ADRESH,W	;データ上位８ビット
			clrf	BSR
			movwf	ADC_DATA1
			movlb	01H
			movf	ADRESL,W
			bcf		ADCON0,ADON	;A/DコンバータOFF
			movlb	0h
			movwf	ADC_DATA0		;
			movlw	03H
			andwf	ADC_DATA1,F		;上位6bit
			;hex(0-1)にデータをコピー
			movf	ADC_DATA0,W
			movwf	hex0			;
			movf	ADC_DATA1,W
			movwf	hex1			;

;		FVR電圧切替
;
;		HEXx=>1020(1000,3FCH,FVR2モード)でFVR4に切り替え
;		HEXx=<970(485,1E5H,FVR4モード)でFVR2に切り替え
GAD2M01
			btfsc	MODE,1
			bra		GAD2M04
			;FVR2モードで1020(2040mV)以上かチェック
			movlw	0FBH
			movwf	hexw0
			movlw	03H
			movwf	hexw1		;hexw(0-1)=03FBH(1019)
			call	SUB16B		;hex(0-1)=hex(0-1)-hexw(0-1)
			iorlw	0H			;Wreg=0なら正常減算、0以外ならボロー
			btfss	STATUS,Z	;Z=1なら1020以上、Z=0なら1019以下
			bra		GAD2M05		;モード内数値で切り替え不要
			;FVR4モードにして電圧再取得
			call	SET_FVR4
			goto	GET_ADC2
			;FVR4モードで970以下かチェック
GAD2M04		movlw	0E6H
			movwf	hexw0
			movlw	01H
			movwf	hexw1		;hexw(0-1)=01E6H(971)
			call	SUB16B
			iorlw	0H
			btfsc	STATUS,Z	;Z=0なら970以下、Z=1なら971以上
			bra		GAD2M05		;モード内数値で切り替え不要
			;FVR2モードで電圧再取得
			call	SET_FVR2
			goto	GET_ADC2
GAD2M05		;数値補正処理
			movf	ADC_DATA0,W
			movwf	hex0			;
			movf	ADC_DATA1,W
			movwf	hex1			;
			call	MLT16_X2
			btfss	MODE,1		;FVR_FLG,0=2V,1=4V
			return				;FVR=2V
			;FVR=4V,2mV/dig
			call	MLT16_X2
			return

;			ADC3 制限電流値設定用ボリウム分電圧取得
;
;		基準電圧はVDD
;		入力チャンネルはRA2/AN2
;		出力は10bitでhex0-hex1の16bitに右詰で格納
GET_ADC3
			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変換開始指令
aloop3
			btfsc	ADCON0,GO	;A/D変換完了待ち
			goto	aloop3		;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


SET_FVR2
			movlb	02h			;BANK2
			movlw	082h		;10000010B
			movwf	FVRCON		;FVRイネーブル
								;DACとCPSに対してOFF
								;ADCには2.048V
			clrf	BSR
			bcf		MODE,1		;FVR_FLG=2V
			return
SET_FVR4
			movlb	02h			;BANK2
			movlw	083h		;10000011B
			movwf	FVRCON		;FVRイネーブル
								;DACとCPSに対してOFF
								;ADCには4.096V
			clrf	BSR
			bsf		MODE,1		;FVR_FLG=4V
			return

;
;		16bitバイナリから4桁分のセグメントデータ生成
;
;	入力		FDA0,FDA1	16bitバイナリ数値
;				FDB0,FDB1	16bitバイナリ数値
;	出力		SEG1-SEG4バッファにロード
;	使用変数	ZBK
SET_SEG
			btfsc	MODE,0		;DSP_MODE
			bra		SSG01		;bit0=1
			call	FDAHEX		;FDAxをHEXxにデータ移動
			bra		SSG02		;ドレイン電流表示
SSG01		movf	FDB0,W
			movwf	hex0
			movf	FDB1,W
			movwf	hex1		;制限電流表示
SSG02		clrf	hex2
			clrf	hex3
			call	BCD			;BCDに変換
;			表示するセグメントデータをバッファに書込み
			clrf	ZBK			;ブランキング フラグ リセット
			bcf		INTCON,GIE	;割り込み禁止
			swapf	digit34,W
			andlw	0fh
			btfss	STATUS,Z
			bsf		ZBK,3		;4桁目ゼロでない
			call	GET_7SEG
			movwf	SEG4		;4桁目に数値データ書込み

			movf	digit34,W
			andlw	0fh
			btfss	STATUS,Z
			bsf		ZBK,2
			call	GET_7SEG
			movwf	SEG3		;3桁目に数値データ書込み

			swapf	digit12,W
			andlw	0fh
			btfss	STATUS,Z
			bsf		ZBK,1
			call	GET_7SEG
			movwf	SEG2		;2桁目に数値データ書込み

			movf	digit12,W
			andlw	0fh
			bsf		ZBK,0
			call	GET_7SEG
			movwf	SEG1		;1桁目に数値データ書込み
			bsf		INTCON,GIE	;割り込み再開

			return

;			HEX(0-3)=FDA(0-3)
FDAHEX		movf	FDA0,W
			movwf	hex0
			movf	FDA1,W
			movwf	hex1
			return

;			FDA(0-3)=HEX(0-3)
HEXFDA		movf	hex0,W
			movwf	FDA0
			movf	hex1,W
			movwf	FDA1
			return

GET_SW1
			btfsc	PORTA,3		;DISP_SW
			bra		GSW02		;RA3=1(SW=OFF)
			call	wait10m		;RA3=0(SW=ON)
			btfsc	PORTA,3
			;SW ON
			bra		GET_SW1
			bsf		MODE,0
			retlw	0FFH
GSW02		;SW OFF
			bcf		MODE,0
			retlw	0H

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			BCDからLEDセグメントデータへの変換
;
;	入力		Wregに表示16進バイナリデータを入れてコール
;				DP制御データは無い
;	出力		Wレジスタに8ビットポート出力データを入れてリターン
;
;	OSL40562-IR anodo common	PORT=0　then　seg=ON
;
;		a				RC0=a	RC4=e
;	f		b			RC1=b	RC5=f
;		g				RB6=c	RC6=g
;	e		c			RB7=d	Dp	接続無
;		d		dp		
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GET_7SEG
			andlw		0fh			;下位4ビット取り出し
			btfsc		STATUS,Z	;
			goto		g7s1
g7s0		brw
			retlw		B'11000000'	;Code 0 abcdef
			retlw		B'11111001'	;Code 1 bc
			retlw		B'10100100'	;Code 2 abdeg
			retlw		B'10110000'	;Code 3 abcdg
			retlw		B'10011001'	;Code 4 bcfg
			retlw		B'10010010'	;Code 5 acdfg
			retlw		B'10000010'	;Code 6 acdefg
			retlw		B'11111000'	;Code 7 abc
			retlw		B'10000000'	;Code 8 abcdefg
			retlw		B'10011000'	;Code 9 abcfg

			retlw		B'10001000'	;Code A abcefg
			retlw		B'10000011'	;Code B cdefg
			retlw		B'11000110'	;Code C adef
			retlw		B'10100001'	;Code D bcdeg
			retlw		B'10000110'	;Code E adefg
			retlw		B'10001110'	;Code F aefg

g7s1		;ゼロブランキング処理
			movf		ZBK,W
			iorlw		0h
			btfsc		STATUS,Z	;
			retlw		0FFH		;ブランク返し
			retlw		B'11000000'	;0表示返し



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		４バイトバイナリの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
