;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		ＰＩＣキット　ＧＣＬＤモジュール
;		（秋月電子ＳＧ１２８６４）
;		テストプログラム		　Ver1.0 ＪＡ０ＱＯＮ
;
;		GLCD基板の搭載文字パターンを試験表示させる
;
;		PIC12F1823 32MHZ（内部オシレータ）
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



		LIST	P=PIC16F1823
		INCLUDE	P16F1823.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=有効　クロックが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	100	発振器選択ビット
;						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  １  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					Unimplemented
;bit10		BORV	0	ブラウンアウト･リセット電圧選択ビット（Vbor参照)
;						1=低電圧で動作
;						0=高電圧で動作
;bit9		STVREN	0	スタック･オーバーフロー･リセット設定
;						1=有効
;						0=無効
;bit8		PLLEN	0	PLL設定
;						1=4xPLL有効
;						0=4xPLL無効
;bit7-5					Unimplemented
;bit4					Reserved
;bit3-2					Unimplemented
;bit1-0		WRT		11	フラッシュメモリ プロテクション設定（EECONレジスタ参照)
;						11=無効
;						10=0h-1FFh有効
;						01=0h-3FFh有効
;						00=0h-7FFh有効
;
;bit	15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
;data    0  0  0  1  1  0  0  0  1  1  1  1  1  1  1  1
;
;
	__CONFIG _CONFIG2,	B'0001100011111111'


;		ワークエリア定義
;
;		BANK0	20h-7Fh
;
;		使用していないのもあります
;

hex0		equ		020h		;32ビット取得HEXデータ
hex1		equ		021h		;
hex2		equ		022h
hex3		equ		023h
hexw0		equ		024h		;32ビットバイナリ演算用
hexw1		equ		025h
hexw2		equ		026h
hexw3		equ		027h
cnt0		equ		028h		;時間待ちルーチン用
cnt1		equ		029h
cnt2		equ		02ah
cnt3		equ		02bh
tmp0		equ		02ch		;汎用ワーク
tmp1		equ		02dh
FLG			equ		02eh		;エラー＆設定フラグ
MODE		equ		02fh		;実行モード設定
hexd		equ		030h		;小数部分
ASC0		equ		031h		;ASCIIデータ下位ビット
ASC1		equ		032h		;ASCIIデータ上位ビット
DCM0		equ		033h		;基数演算用ワーク
DCM1		equ		034h		;
DCM2        equ     035h        ;
MSAD0		equ		036h		;周波数表示データ
MSAD1		equ		037h
TBAL        equ     038h        ;参照テーブル先頭アドレス下位8ビット
TBAH        equ     039h        ;同上位8ビット
;
digit12		equ		03ah		;BCD変換出力1，2桁
digit34		equ		03bh		;BCD変換出力3，4桁
digit56		equ		03ch		;BCD変換出力5，6桁
digit78		equ		03dh		;BCD変換出力7，8桁
digit9A		equ		03eh		;BCD変換出力9，10桁
bcdw0		equ		03fh		;BCD補正処理ワーク
bcdw1		equ		040h
shift		equ		041h		;ビットシフト用ワーク(BCDで使用)
wrk0		equ		042h        ;演算用汎用ワーク
wrk1		equ		043h
wrk2		equ		044h		;
wrk3		equ		045h		;
div0		equ		046h		;除算用ワーク
div1		equ		047h		;
div2		equ		048h		;
div3		equ		049h		;
divw0		equ		04ah		;
divw1		equ		04bh		;
divw2		equ		04ch
divw3		equ		04dh
DBUF4		equ		04eh
DBUF5		equ		04fh
DBUF6		equ		050h
DBUF7		equ		051h
;
DATA0		equ		052h
DATA1		equ		053h
SIGN		equ		05eh
DSP_ADR     equ     05fh
icw0        equ     060h
icw1        equ     061h
DSP_DATA	equ		062h
I2C_ADR		equ		063h
TMP_H		equ		06bh
TMP_L		equ		06ch
HUM_H		equ		06dh
HUM_L		equ		06eh
LDWR		equ		06fh
;
;	液晶表示バッファ
;
;	A0H-AFH		1行目16バイトでA0Hは最右側、AFHが最左側
;	B0H-BFH		2行目
;	FSR0でアクセス

			ORG		0h
			goto	init
			ORG		04h

;
;		割込み処理ルーチン
;
;		割込み発生から割込みベクタまで3サイクル程度（同期割込み）
;		FSRxはコアレジスタなので、自動で PUSH-POPされる
;		よって、割り込み終了後、元の設定値に戻る
;
INT
;
INTOUT
;
			retfie				;




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			PIC16F1823　イニシャライズ
;
;		OSCCON(BANK1　099H) マニュアル69ページ
;			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）　マニュアル126ページ
;			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）　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RC5-4	デジタルI/O
;			bit3	RC3-0	デジタルI/O、アナログ入力
;
;		TRISA(BANK1　08CH)　マニュアル126ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	1=入力、0=出力
;			bit3	RA3		常に1
;			bit2	RA2-0	1=入力、0=出力
;
;		TRISC(BANK1　08EH)　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-0	1=入力、0=出力
;
;		LATA(BANK2　10CH)　データラッチﾚｼﾞｽﾀ　マニュアル127ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-4	RA5-4	出力データ保持
;			bit3	Unimplemented(read=0)
;			bit2	RA2-0	出力データ保持
;			（このラッチデータはTRISAレジスタ設定で各ピンに反映される）
;
;		LATC(BANK2　10EH)　データラッチﾚｼﾞｽﾀ　マニュアル130ページ
;			bit7-6	Unimplemented(read=0)
;			bit5-0	RA5-4	出力データ保持
;			（このラッチデータはTRISCレジスタ設定で各ピンに反映される）
;
;
;		ANSELA(BANK3　18CH)　マニュアル127ページ
;			bit7-5	Unimplemented(read=0)
;			bit4	ANSA3/RA4	アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			bit3	Unimplemented(read=0)
;			bit2-0	ANA2-0/RA2-0アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトでは、すべて1(アナログ入力)となっている
;
;		ANSELC(BANK3　18EH)　マニュアル131ページ
;			bit7-4	Unimplemented(read=0)
;			bit3-0	ANSC3-0/RC3-0　アナログ/デジタル選択ビット
;								1=アナログ入力
;								0=デジタルI/O
;			＊デフォルトではアナログ入力となっている
;
;		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=PORTC各ビットプルアップ有効
;					 _____	0=PORTC各ビットプルアップ無効
;					*WPUENビットが有効の時のみ、設定有効となる。
;
;
;		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モジュール
;
;
;		OPTION_REG(BANK1　095H)　マニュアル177ページ
;					_____
;			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
;
;   SSP1CON1    SSP制御レジスタ１   BSR=4
;       bit7    WCOL：書込みコリジョン検出ビット
;               マスタの場合
;               1=I2Cの送信開始条件が無効の時にSSP1BUFレジスタへ書込みが行われた
;               0=問題無
;               スレーブの場合
;               1=前のワードの送信中にSSP1BUFレジスタへの書き込みが行われた
;               0=問題無
;                   *ソフトウエアでクリアする必要あり
;       bit6    SSP1OV：受信オーバーフロー インジケータービット(注1)
;               1=オーバーフロー発生
;               2=問題無
;                   *ソフトウエアでクリアする必要あり
;       bit5    SSP1EN：同期シリアルポートイネーブルビット
;               1=シリアルポート有効(注2)
;               0=シリアルポート無効、I/Oポート使用可
;       bit4    CKP：クロック極性選択ビット
;               1=クロックを有効化
;               0=クロックをLOWに保持（クロックストレッチ）
;                   *マスタモードでは使用しない
;       bit3-0  SSP1M：同期シリアルポート モード選択ビット
;               0110=スレーブモード、7ビットアドレス
;               0111=スレーブモード、10ビットアドレス
;               1000=マスターモード、クロック=FOSC/(4*SP1ADD+1))(注3)
;               1011=ファームウエア制御のマスターモード（スレーブアイドル）
;               1110=スレーブモード、7ビットアドレス、
;                    スタートビットとストップビットの割込み有効
;               1111=スレーブモード、10ビットアドレス、
;                    スタートビットとストップビットの割込み有効
;
;       注1)マスターモードの場合、新たな送受信はSSP1BUFへの書込みによって
;       　　開始するため、オーバーフロービットはセットされない
;       注2)SDAピンとSCLピンは入力としてTRIS設定
;       注3)SP1ADDの値、0,1,2はサポートされない
;
;   SSP1CON2    SSP制御レジスタ２
;       bit7    GCEN：ジェネラルコールイネーブルビット
;               1=SSP1SRでGCアドレス(00H)を受信した時の割込みを有効にする
;               0=GCアドレスを無効にする
;       bit6    ACKSTAT：肯定応答(ACK)ステータスビット
;               1=ACK受信した
;               0=ACK受信していない
;       bit5    ACKDT：ACKデータビット（受信モード）
;               1=ACKしない
;               0=ACKあり
;       bit4    ACKEN：ACKシーケンス イネーブルビット（マスタ受信モード）（注1）
;               1=ACKシーケンスを開始し、ACKDTビットを送信する
;               0=ACKシーケンスをアイドルにする
;       bit3    RCEN：受信イネーブルビット（マスターモードのみ）（注1）
;               1=受信モードを有効にする
;               0=受信をアイドルにする
;       bit2    PEN：ストップ条件イネーブルビット（注1）
;               SCK解放制御
;               1=ストップ条件を開始する、ハードウエアによって自動でクリアされる
;               0=ストップ条件をアイドルにする
;       bit1    RSEN：反復スタート条件イネーブルビット（注1）
;               1=反復スタート条件を開始する
;               　ハードウエアによって自動でクリアされる
;               0=反復スタート条件をアイドルにする
;       bit0    SEN：スタート条件イネーブルビット（注1）
;               マスターモードの場合
;               1=スタート条件を開始する、ハードウエアによって自動でクリアされる
;               0=スタート条件をアイドルにする
;
;       注1）I2Cモジュールがアイドルで無い場合、これらのビットはセットされず、
;            SSP1BUFに書き込まれない場合がある（SSP1BUFへの書込み無効）
;
;   SSP1CON3    SSP1制御レジスタ３
;       bit7    ACKTIM：肯定応答(ACK)タイムステータスビット（注1）
;               1=ACKシーケンスを実行中。
;               　SCLクロックの8番目の立下りエッジでセットされる
;               0=ACKシーケンスではない。
;               　SCLクロックの9番目の立上がりエッジでクリアされる
;       bit6    PCIE：ストップ条件割込みイネーブルビット
;               1=ストップ条件検出時の割込みを有効にする
;               0=ストップ条件検出時の割込みを無効にする
;       bit5    SCIE：スタート条件割込みイネーブルビット
;               1=スタート／リスタート条件検出時の割込みを有効にする
;               0=スタート条件検出時の割込みを無効にする
;       bit4    BOEN：バッファ上書きイネーブルビット
;               1=SSP1BUFは更新され、受信したアドレス／データバイトに対して
;               　ACK信号が生成される。
;               　BFビットが0の場合のみSSP1OVビットの状態を無視する。
;               0=SSP1OVがクリアされている時のみSSP1BUFが更新される
;               *マスタモードの場合、このビットは無視される
;       bit3    SDAHT：SDAホールド時間の選択ビット
;               1=SDAのホールド時間はSCLの立下りエッジから最小300ns
;               0=SDAのホールド時間はSCLの立下りエッジから最小100ns
;       bit2    SBCDE：スレーブモードのバスコリジョン検出イネーブルビット
;               1=スレーブバスコリジョン割込みを有効にする
;               0=スレーブバスコリジョン割込みを無効にする
;       bit1    AHEN：アドレスホールドイネーブルビット（スレーブモードのみ）
;               1=一致受信アドレスバイトのSCLの8番目の立下りエッジ後、SSP1CON1
;               　レジスタのCKPビットをクリアし、SCLがLOWに保持される
;               0=アドレスホールド機能を無効にする
;       bit0    DHEN：データホールドイネーブルビット（スレーブモードのみ）
;               1=受信データバイトのSCLの8番目の立下りエッジ後、スレーブハードウ
;               エアがSSP1CON1レジスタのCKPビットをクリアし、SCLがLOWに保持される
;               0=データホールド機能を無効にする
;       *注1）ACKTIMステータスビットがアクティブになるのは、AHENビットまたは、
;             DHENビットがセットされている場合のみ
;
;   SSP1MSK     SSP1マスクレジスタ
;       bit7-1  MSK：マスクビット
;               1=受信アドレスbitnをSSP1ADD(n)と比較して、I2Cアドレス一致を検出
;               0=受信アドレスbitnをI2Cアレス一致の検出に使わない
;       bit0    I2Cスレーブモードのマスクビット、10ビットアドレス
;               I2Cスレーブモード、10ビットアドレス（SSP1M3-0=0111または1111)
;               1=受信アドレスbit0をSSP1ADD(0)と比較して、I2Cアドレス一致を検出
;               0=受信アドレスbit0をI2Cアレス一致の検出に使わない
;               *スレーブモード、7ビットアドレスでは、このビットは無視される
;
;   SSP1ADD     MSSP1アドレス／ボーレートジェネレータ
;               マスターモードの場合
;       bit7-0  ADD：ボーレートクロック分周ビット（(ADD(7-0)+1)*4）/FOSC
;               スレーブモードの場合
;       bit7-1  ADD：7ビットのアドレス
;       bit0    未使用
;           *10ビットアドレスモードでの状態は割愛します
;
;   SSP1STAT    SSP1ステータスレジスタ
;       bit7    SMP：スルーレート制御
;               1=スルーレート制御の標準速度モード(100KHZ,1MHZ)を無効にする
;               0=スルーレート制御の高速モード(100KHZ)を有効にする
;       bit6    CKE：SMBus仕様互換入力
;               1=しきい値がSMBus仕様に準拠する入力
;               0=無効
;       bit5    D_NOT_A：データ/アドレスビット
;               1=最後に送受信したバイトがデータ
;               0=最後に送受信したバイトがアドレス
;       bit4    P：ストップビット
;               1=最後にストップビットが検出された事を示す
;               0=最後にストップビットが検出されなかった事を示す
;       bit3    S：スタートビット
;               1=最後にスタートビットが検出された事を示す
;               0=最後にスタートビットが検出されなかった事を示す
;       bit2    R_NOT_W：READ/WRITEビット情報
;               スレーブモード
;               1=読み出し
;               0=書込み
;               マスタモード
;               1=送信動作中
;               0=送信動作中で無い
;       *このビットとSEN,RSEN,PEN,RCEN,ACKENのどれかをORするとMSSP1がアイドル中
;        かどうかが判る
;       bit1    UA：交信アドレスビット（10ビットアドレスモードのみ）
;               1=アドレスの更新が必要
;               0=アドレスの更新が不要
;       bit0    BF：バッファフル ステータスビット
;               受信
;               1=受信が完了、SSP1BUFがフルである
;               0=受信が完了していない、SSP1BUFがエンプティ
;               送信
;               1=データ送信中(ACK及びｽﾄｯﾌﾟﾋﾞｯﾄを含まない)SSP1BUFはフル
;               0=データ送信完了(ACK及びｽﾄｯﾌﾟﾋﾞｯﾄを含まない)SSP1BUFはエンプティ
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

init
;			各レジスタ初期設定(PIC16F1823)
			movlb	0h			;BANK0
			movlw	000h		;00000000B
			movwf	INTCON		;全割込みOFF

;			システムクロック設定
			movlb	01h			;BANK１
			movlw	0f0h		;1111000B
			movwf	OSCCON		;内部発振器は8MHZに設定
								;4xPLL=ON

;			I/Oポート設定 (TRIS→BANK1、LAT→BANK2、ANSEL→BANK3)
			movlb	0h			;BANK0
			clrf	PORTA		;Init PORT
			clrf	PORTC
			movlb   02h         ;BANK2
			clrf    LATA
			clrf    LATC
			movlb	03h			;BANK3
			clrf	ANSELA		;RA0-5=デジタル
			clrf	ANSELC      ;RC0-5=デジタル
			movlb	01h			;BANK1
			movlw	0fh			;00001111B
			movwf	TRISA		;RA0-3入力、RA4-5出力
            movlw	03fh		;00111111B
            movwf	TRISC       ;RC0-5入力

			;TMR0およびプルアップ(BANK1)
			movlb	01h			;BANK1
			movlw	083H		;10000011b
			movwf	OPTION_REG	;プルアップOFF
								;割込みエッジ↓
								;クロックソース内部（Fosc/4）
								;TMR0カウントエッジ↓
								;プリスケーラ割当→TMR0
								;プリスケーラ分周1/16にセット

;			10ビットADC(BANK1)
;			movlw	020h		;0010000B
;			movwf	ADCON1		;左詰め、基準電圧VDD
								;ADCクロック　Fosc/32=1us(32MHZ)

;			FVR(BANK2)
;			movlb	02h			;BANK2
;			movlw	088h		;10001000B
;			movwf	FVRCON		;FVRイネーブル
								;DACとCPSに2.048V
								;ADCにはOFF

;			初期設定終了
			clrf	BSR
coldst
			movlw	07CH		;既定のI2Cアドレス
			movwf	I2C_ADR
			call	wait1s		;GLCDモジュール安定化待ち
			call	wait1s
			call	MSSP_MAS	;MSSP1起動、I2Cマスタアイドル

;			デモンストレーション
mloop
			movlw	02H			;16x8dot mode
			call	SET_DSP_MODE
;			デモ１
			movlw	LOW MSG01	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG01	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	0H			;0行目
			movwf	DSP_ADR
			call	PUTL		;"  GRAPHIC LCD"
			call	wait1s
;
			movlw	LOW MSG02	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG02	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	010H		;1行目
			movwf	DSP_ADR
			call	PUTL		;"CONTROLL BORD"
			call	wait1s
;
			movlw	LOW MSG03	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG03	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	020H		;2行目
			movwf	DSP_ADR
			call	PUTL		;"128x64RESOLUTION"
			call	wait1s
;
			movlw	LOW MSG04	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG04	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	030H		;3行目
			movwf	DSP_ADR
			call	PUTL		;"I2C INTERFACE"
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			movlw	010H		;ALL CLEAR
			call	CLR_PAGE
;			デモ２
			movlw	LOW MSG05	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG05	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	00H			;0行目
			movwf	DSP_ADR
			call	PUTL		;Program Ver 1.0"
			call	wait1s
;
			movlw	LOW MSG06	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG06	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1

			movlw	03H			;16x16dot mode
			call	SET_DSP_MODE
			movlw	08H			;1行目
			movwf	DSP_ADR
			call	PUTL		;"JA0QON"
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			movlw	010H		;ALL_CLR
			call	CLR_PAGE
;			デモ３
;	8×6dot		1行21文字
;		0行		00H-14H(0-20)
;		1行		15H-29H(21-41)
;		2行		2AH-3EH(42-62)
;		3行		3FH-53H(63-83)
;		4行		54H-68H(84-104)
;		5行		69H-7DH(105-125)
;		6行		7EH-92H(126-146)
;		7行		93H-A7H(147-167)

			movlw	00H			;8x6dot mode
			call	SET_DSP_MODE
			movlw	LOW MSG10	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG10	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	015H		;1行目
			movwf	DSP_ADR
			call	PUTL		;"8x6dot FONT MODEﾞ
			call	wait1s
			movlw	LOW MSG11	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG11	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	03FH		;3行目
			movwf	DSP_ADR
			call	PUTL		;"0123456789ABCDEFGHIJK"
			call	wait1s
			movlw	LOW MSG12	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG12	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	069H		;5行目
			movwf	DSP_ADR
			call	PUTL		;"ﾖｺ 21ﾓｼﾞ ﾋｮｳｼﾞﾃﾞｷﾏｽ"
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			movlw	010H		;ALL_CLR
			call	CLR_PAGE
;			デモ４
;	16×8dot
;		0行		00H-0FH(0-15)
;		1行		10H-1FH(16-31)
;		2行		20H-2FH(32-47)
;		3行		30H-3FH(48-63)
			movlw	02H			;8x6
			call	SET_DSP_MODE
			movlw	LOW MSG13	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG13	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	00H			;0行目
			movwf	DSP_ADR
			call	PUTL		;"16x8 FONT MODEﾞ
			call	wait1s
			movlw	LOW MSG14	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG14	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	020H		;2行目
			movwf	DSP_ADR
			call	PUTL		;"0123456789ABCDEF"
			call	wait1s
			movlw	LOW MSG15	;MSG01間接アドレス値下位8ビット
			movwf	MSAD0
			movlw	HIGH MSG15	;MDG01間接アドレス値上位8ビット
			movwf	MSAD1
			movlw	030H		;3行目
			movwf	DSP_ADR
			call	PUTL		;"ﾖｺ 16ﾓｼﾞ ﾋｮｳｼﾞ"
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			call	wait1s
			movlw	010H		;ALL_CLR
			call	CLR_PAGE
		
			goto	mloop


;文字コード データエリア
MSG01		DT		"  GRAPHIC LCD"
			DW		0
MSG02		DT		" CONTROLL BORD"
			DW		0
MSG03		DT		"128x64RESOLUTION"
			DW		0
MSG04		DT		" I2C INTERFACE"
			DW		0
MSG05		DT		" Program Ver 1.0"
			DW		0
MSG06		DT		"@@@@?@@@@@@@@@@@@JA0QON@"
			DW		0
MSG10		DT		"   8x6dot FONT MODE"
			DW		0
MSG11		DT		"0123456789ABCDEFGHIJK"
			DW		0
MSG12		DT		"ﾖｺ 21ﾓｼﾞ ﾋｮｳｼﾞﾃﾞｷﾏｽ"
			DW		0
MSG13		DT		"16x8dt FONT MODE"
			DW		0
MSG14		DT		"0123456789ABCDEF"
			DW		0
MSG15		DT		"ﾖｺ 16ﾓｼﾞ ﾋｮｳｼﾞ"
			DW		0


;
;		ＳＧ１２８６４　Ｉ２Ｃモジュール
;								Ver1.0
;		書込みサブルーチン群
;
;		ADR=7CH（ADR+WRITEﾋﾞｯﾄ）
;                   R/Wビットは常に0（WRITEのみ）
;		CMD_WORD	コマンドワード
;					CTRL+DATAの２バイトで構成
;
;		LCD_ADR		7CH				LCDスレーブ アドレス
;		DSP_ADR		00H-A7H			表示位置アドレス(VRAM)
;
;	コントロールバイト(CTRL)のビット構成
;
;	bit7	CO:連続送信、最終送信の指定
;			1= 連続コマンドワード
;			0= 最終コマンドワード
;	bit6	D/I:データの属性
;			1= データバイトはデータ
;			0= データバイトはコマンド
;	bit5	CPU：GLCD制御PICの動作
;			1= CPU描画制御(bit4-0はGPUコマンド)
;			0= ダイレクト描画制御(bit4-0はダイレクトモード)
;
;	ダイレクトモード(bit5=0の場合)
;	bit4	Reserved
;	bit3	Reserved
;	bit2	CS2
;			1= CS2イネーブル
;			0= CS2ディセーブル
;	bit1	CS1
;			1= CS1イネーブル
;			0= CS1ディセーブル
;	bit0	RESET
;			1=LCDリセット
;			0=通常動作
;
;	GPUコマンド(bit5=1の場合)
;	bit4-0	00H:NOP
;			01H	CLR_PAGE
;				DATA= 00H-07H 左０-７指定ページ
;				DATA= 08H-0FH 右０-７指定ページ
;				DATA= 10H 左右全ページ（オールクリア）
;				DATA= 11H 左全ページ
;				DATA= 12H 右全ページ
;			02H	SET_DSP_MODE
;				DATA=00H 8x6dot
;				DATA=01H 8x8dot
;				DATA=02H 16x8dot
;				DATA=03H 16x16dot
;			03H	SET_DSP_ADR（データはVRAMアドレス）
;				DATA=00H-A7H
;			04H	WRITE_CHAR（データは文字コード）
;				DATA=20H-DFH
;

;
;	既定のコマンドワード送信サブルーチン群
;
;	コマンドワード=CTRL+CMD_DATA
;

;		クリアページ
;	Wreg= 00H-07H 左０-７指定ページ
;	Wreg= 08H-0FH 右０-７指定ページ
;	Wreg= 10H 左右全ページ（オールクリア）
;	Wreg= 11H 左全ページ
;	Wreg= 12H 右全ページ
CLR_PAGE
;			I2Cアドレス送信
			bsf		PORTA,5		;LED_GRN
            movwf	icw0		;PUSH Wreg
			call	STARTCON	;スタートコンディション送信
			movf	I2C_ADR,W	;LCDアドレス+WRITE
			call	SEND_BYTE	;アドレス送信
;			CTRL+CMD_DATA送信
			movlw	021H		;C0=0、D/I=0、CPU=1、GPU=01
			call	SEND_BYTE	;コントロールバイト送信
			call	w10u
			movf	icw0,W		;CLR_MODE 00H-12H
			call	SEND_BYTE	;
			call	wait20m
			call	STOPCON
			bcf		PORTA,5
			return

;	ディスプレイモード設定
;
;	Wreg=00H 8x6dot
;		=01H 8x8dot
;		=02H 16x8dot
;		=03H 16x16dot
SET_DSP_MODE
;			I2Cアドレス送信
			bsf		PORTA,5		;LED_GRN
            movwf	icw0		;PUSH Wreg
			call	STARTCON	;スタートコンディション送信
			movf	I2C_ADR,W	;LCDアドレス+WRITE
			call	SEND_BYTE	;アドレス送信
;			CTRL+CMD_DATA送信
			movlw	022H		;C0=0、D/I=0、CPU=1、GPU=02
			call	SEND_BYTE	;コントロールバイト送信
			call	w10u
			movf	icw0,W		;DSP_MODE
			call	SEND_BYTE	;
			call	w10u
			call	STOPCON
			bcf		PORTA,5
			return
;
;	VRAMアドレスを送信
;	アドレス値はDSP_ADRに設定
;
SET_DSP_ADR
;			I2Cアドレス送信
			bsf		PORTA,5		;LED_GRN
			call	STARTCON	;スタートコンディション送信
			movf	I2C_ADR,W	;LCDアドレス+WRITE
			call	SEND_BYTE	;アドレス送信
;			CTRL+CMD_DATA送信
			movlw	023H		;C0=0、D/I=0、CPU=1、GPU=03
			call	SEND_BYTE	;コントロールバイト送信
			call	w10u
			movf	DSP_ADR,W	;DSP_ADR
			call	SEND_BYTE	;
			call	w10u
			call	STOPCON
			bcf		PORTA,5
			return
;
;			Wregの文字コードをGLCDに表示(実行）
;
WRITE_CHAR
;			I2Cアドレス送信
			bsf		PORTA,5		;LED_GRN
            movwf	icw0		;PUSH Wreg
			call	STARTCON	;スタートコンディション送信
			movf	I2C_ADR,W	;LCDアドレス+WRITE
			call	SEND_BYTE	;アドレス送信
;			CTRL+CMD_DATA送信
			movlw	024H		;C0=0、D/I=0、CPU=1、GPU=04
			call	SEND_BYTE	;コントロールバイト送信
			call	w10u
			movf	icw0,W		;文字コード
			call	SEND_BYTE	;
			call	wait100u
			call	wait100u
			call	wait100u
			call	wait100u
			call	STOPCON
			bcf		PORTA,5
			return

;
;   Ｗレジスタの「データ」を単発で書き込む
;
;		表示位置指定	DSP_ADR
;		事前にDSP_MODEの指定も必要
;
PUTW
			movwf	icw0
			call	SET_DSP_ADR
			movf	icw0,W
			call	WRITE_CHAR
			return

;
;	指定のデータを指定のVRAMアドレスからGLCDに連続書込み
;		MSAD0	指定データ格納アドレス下位8ビット
;		MSAD1	指定データ格納アドレス上位7ビット
;		DSP_ADR	書込み先頭VRAMアドレス、00H-A7H
;				文字列長のチェックは行わないので注意
;
PUTL
			movf	MSAD0,W
			movwf	FSR0L
			movf	MSAD1,W
			movwf	FSR0H

PTL01
			movf	INDF0,W		;MSGアドレスよりデータを取得
			iorlw	0h			;エンドコードチェック
			btfsc	STATUS,Z
			bra		PTL02		;end of msg
			call	PUTW		;1文字送信
			incf	FSR0L,F
			btfsc	STATUS,Z
			incf	FSR0H,F		;FSR0の桁上がり有
			incf	DSP_ADR,F
			movlw	0A8h		;データアドレス オーバー
			xorwf	DSP_ADR,W
			btfss	STATUS,Z
			bra		PTL01
PTL02		return				;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	ＰＩＣ１６Ｆ１ｘ ＭＳＳＰモジュール
;	Ｉ２Ｃマスターモード制御サブルーチン群
;
;									Ver0.2a JA0QON
;		履歴
;		マスタ送信のみ		Ver0.1
;		マスタ受信追加		Ver0.2
;		Ver0.2の小修正		Ver0.2a
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;
;   I2C　マスタモード初期化サブルーチン
;
;       RC0     SCL         I2Cクロック
;       RC1     SDA         I2Cデータ
;
MSSP_MAS
			movlb	04h
			movlw	028h        ;28H=00101000
			movwf	SSP1CON1    ;SSP1ﾏｽﾀｰﾓｰﾄﾞ ｲﾈｰﾌﾞﾙ
			movlw	04fh
			movwf	SSP1ADD		;100KHZボーレート
			clrf	BSR
            call	MSSP_IDLE	;
			return

;
;		MSSPアイドル待ち
;
;   R/WとSEN,RSEN,PEN,RCEN,ACKENのどれかとOR演算すると
;   MSSP1がアイドルかどうかが分かる
;
MSSP_IDLE
            movlb   04h
msid01      movf    SSP1CON2,W
            andlw   01fh        ;1FH=00011111B
            btfss	STATUS,Z
			bra		msid01		;MSSP not idle
            btfsc	SSP1STAT,R_NOT_W
            bra		$-1			;R/Wbit=1 not idle
            clrf    BSR
            return
;
;		MSSP STARTCON 送信
;
STARTCON
			bcf		PIR1,SSP1IF	;
			call	MSSP_IDLE	;アイドル待ち
            movlb   04h
            bcf SSP1CON1,WCOL   ;衝突フラグクリア
            bsf SSP1CON2,SEN    ;スタート出力
            btfsc   SSP1CON1,WCOL
            goto    STARTCON    ;スタート再出力
            btfsc   SSP1CON2,SEN
            bra     $-1         ;送信完了チェック
            clrf    BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
            return

;
;		MSSP反復スタート
;
RESTART
			bcf		PIR1,SSP1IF	;
            movlb   04h
            bsf SSP1CON2,RSEN	;リスタート出力
            btfsc   SSP1CON2,RSEN
            bra     $-1         ;送信完了チェック
            clrf    BSR
            return

;
;   マスターモード　1バイト送信
;   送信データはＷレジスタ
;
SEND_BYTE
;	SSP1CON2,SEN=1で、START条件の生成
;	START完了でﾊｰﾄﾞｳｴｱがSSP1IFをセット
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movwf	SSP1BUF		;送信開始、BF=1
			btfsc	SSP1STAT,BF	;BF=0で送信完了
			bra		$-1			;送信終了待ち
			btfsc   SSP1CON2,ACKSTAT
			bra		$-1			;ACK返信待ち
;	ACK確認終了で、SSP1IFがセットされる、STOP確認でもSSP1IFがセット
;	ｿﾌﾄｳｴｱでSSP1IFをクリアする
			clrf	BSR
			call    MSSP_IDLE   ;アイドル待ち（これをしないと送信失敗する）
			return

;
;   マスターモード　1バイト受信
;   受信データはＷレジスタ
;
RCV_BYTE
;	SSP1CON2,SEN=1で、START条件の生成
;	STARAT完了でﾊｰﾄﾞｳｴｱがSSP1IFをセット
;	ｿﾌﾄｳｴｱでSSP1IFをクリア
;	ｽﾚｰﾌﾞｱﾄﾞﾚｽ送信、R/W=1
;	ﾏｽﾀがｽﾚｰﾌﾞからの/ACKをACKSTATで確認
;	ACK確認終了で、SSP1IFがセットされる
;	ｿﾌﾄｳｴｱでSSP1IFをクリアする

			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb   04h
			bsf	SSP1CON2,RCEN	;ﾏｽﾀｰﾓｰﾄﾞ受信許可
			btfss SSP1STAT,BF	;BF=1で受信完了
			bra		$-1			;受信終了待ち
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movf	SSP1BUF,W	;受信データ読み出し、BF=0
			clrf	BSR
			movwf	wrk1		;受信データ一時保管

			movlb	04h
			bcf SSP1CON2,ACKDT	;ACK応答する、にセット
			bsf SSP1CON2,ACKEN	;ｽﾚｰﾌﾞにACK返送
			btfsc	SSP1CON2,ACKEN
			bra		$-1
			bcf SSP1CON1,SSPOV	;受信OFフラグリセット
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			movf	wrk1,W
			return
;
;   最終バイト受信
;
;		通常受信と違うのは、データ8bit受信後のACK応答
;		連続受信-ACK応答する
;		1バイト受信あるいは最終受信-ACK応答しない
;
LAST_RCV
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
            movlb   04h
            bsf SSP1CON2,RCEN   ;受信許可
            btfss   SSP1STAT,BF
            bra     $-1         ;受信終了待ち
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			movf	SSP1BUF,W	;受信データ読み出し、BF=0
			clrf	BSR
			movwf	wrk1		;受信データ一時保管

			movlb	04h
			bsf SSP1CON2,ACKDT	;NACK（ACK応答しない)にセット
			bsf SSP1CON2,ACKEN	;ｽﾚｰﾌﾞにACK返送
			btfsc	SSP1CON2,ACKEN
			bra		$-1
			clrf	BSR
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			movf	wrk1,W
			return
;
;		MSSP STOPCON送信
;
STOPCON
			bcf		PIR1,SSP1IF	;SSP1IFをクリア
			movlb	04h
			bsf		SSP1CON2,PEN
			btfsc	SSP1CON2,PEN
			bra		$-1
			clrf	BSR
			bcf		PIR1,SSP1IF	;ｿﾌﾄｳｴｱがSSP1IFをクリア
			call	MSSP_IDLE	;アイドル待ち
			return

;
;		16進8bitバイナリ数値を文字コードに変換
;
;		入力	Wreg:00H-FFH
;		出力	ASC0:下位4bit分のASCIIコード'0-9'、'A-F'
;			ASC1:上位4bit分のASCIIコード'0-9'、'A-F'
;
;		使用ワーク	wrk0,wrk1
;
NUTOASC
			movwf	wrk0		;Wreg退避
			andlw	0FH
			movwf	wrk1		;下位4bit分のみ
			movlw	0Ah
			subwf	wrk1,W		;W=F-W
			btfsc	STATUS,C	;/borrow
			bra		NUA1
NUA0		movf	wrk1,W
			addlw	030h
			movwf	ASC0
			bra		NUA2
NUA1;		下位4bit A-F
			movf	wrk1,W
			addlw	037h
			movwf	ASC0

NUA2		;上位4bitチェック
			swapf	wrk0,W
			andlw	0FH
			movwf	wrk1		;上位4bit分のみ
			movlw	0Ah
			subwf	wrk1,W		;W=F-W
			btfsc	STATUS,C	;/borrow
			bra		NUA4
NUA3		movf	wrk1,W
			addlw	030H
			movwf	ASC1
			return
NUA4;		上位4bit A-F
			movf	wrk1,W
			addlw	037H
			movwf	ASC1
			return

;
;		小数2位まで（8bit)演算
;
;		入力		Wreg	除算等によるバイナリ小数8bit
;		出力		Wreg
;				bit7-4	小数第1位の10進数値(0-9)
;				bit3-0	小数第2位の10進数値(0-9)
;		使用ワーク（破壊されます）
;		hex(0-3)、hexw(0-3)、DCM(0-2)
;
;	16進の小数点1位(小数点以下最初の4bit分)
;		これはXH/10H (X=0-F)
;		10進表記にすると、X/16 (X=0-15)
;		つまり、X/16を10進表示に変換すれば良い事になる
;	16進の小数点2位
;		同様にこれは、XH/100H (X=0-F)
;		10進表記で、X/256 (X=0-15)
;		つまり、X/256を10進表記に変換すれば良い事になる
;

DECM_8
			movwf	DCM0		;pushW
			swapf	DCM0,W		;上位4bit
			andlw	0fh			;bit7-4=0
			movwf	hex0
			clrf	hex1
			call	MLT16_X10
			call	MLT16_X10
			call	MLT16_X10	;1000倍
			call	DIV16_X16	;1/16
			movf	hex0,W		;上位4bit
			movwf	DCM1
			movf	hex1,W
			movwf	DCM2
;
			movf	DCM0,W
			andlw	0fh
			movwf	hex0
			clrf	hex1
			call	MLT16_X10
			call	MLT16_X10
			call	MLT16_X10	;1000倍
			call	DIV16_X16	;
			call	DIV16_X16	;1/256
			movf	DCM1,W		;上位4bit
			movwf	hexw0
			movf	DCM2,W
			movwf	hexw1
			call	ADD16B
			clrf	hex2
			clrf	hex3
			call	BCD
			movf	digit12,W	;下位4bitの十進数値
			movwf	DCM1		;小数点第2位、第3位
			movf	digit34,W	;上位4bitの十進数値
			movwf	DCM2		;小数点第1位
;			限定的四捨五入処理
			movf	DCM1,W
			andlw	0fh
			sublw	04h			;W=K-W
			btfsc	STATUS,C	;ボローチェック
			goto	DEM81		;四捨五入無
;			小数点2位が4の時だけ3位を四捨五入する
			swapf	DCM1,W
			andlw	0fh
			xorlw	04h			;2位が4かどうかのチェック
			btfss	STATUS,Z
			goto	DEM81		;処理しない
			movlw	010h
			addwf	DCM1,F		;小数点2位を桁上げ
;
DEM81		movlw	0fh
			swapf	DCM1,F
			andwf	DCM1,F		;小数点3位を切り捨て
			swapf	DCM2,W
			andlw	0f0h
			iorwf	DCM1,F		;小数点1位2位を合成
			movf	DCM1,W
			return


;
;		16bitバイナリ1/16
;
;		入出力hex(0-1)
;
DIV16_X16
			bcf		STATUS,C	;/2
			rrf		hex1,F
			rrf		hex0,F
			bcf		STATUS,C	;/4
			rrf		hex1,F
			rrf		hex0,F
			bcf		STATUS,C	;/8
			rrf		hex1,F
			rrf		hex0,F
			bcf		STATUS,C	;/16
			rrf		hex1,F
			rrf		hex0,F
			return

;
;			32ビットバイナリ10倍演算(符号無整数)
;
;       hex(0-3)=hex(0-3)*10
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;		hexw(0-1)は破壊される
;

MLT32_X10
;			データ保存
			movf	hex0,W
			movwf	hexw0
			movf	hex1,W
			movwf	hexw1
			movf	hex2,W
			movwf	hexw2
			movf	hex3,W
			movwf	hexw3

;			32ビットデータを8倍
			bcf		STATUS,C	;
			rlf		hex0,F		;2倍を3回実行する
			rlf		hex1,F
			rlf		hex2,F
			rlf		hex3,F
			bcf		STATUS,C	;
			rlf		hex0,F
			rlf		hex1,F
			rlf		hex2,F
			rlf		hex3,F
			bcf		STATUS,C
			rlf		hex0,F
			rlf		hex1,F
			rlf		hex2,F
			rlf		hex3,F
			btfsc	STATUS,C
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD32B		;元データを加算
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			call	ADD32B
			iorlw	0h
			btfss	STATUS,Z
			retlw	0FFh		;演算オーバーフロー発生
			retlw	0h			;演算正常終了

;
;       16ビットバイナリ　10倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*10
;		W=0の時、正常終了
;		W=FFHの時、エラー発生、演算結果は保障されない
;		hexw(0-1)は破壊される
;
MLT16_X10
			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		;演算オーバーフロー発生
			retlw	0h			;演算正常終了

;
;       16ビットバイナリ　16倍演算（符号無整数)
;
;       hex(0-1)=hex(0-1)*10
;		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			;演算正常終了

			
;
;			32ビット1/65536除算
;			小数点以下は8bitまで演算、それ以下は破棄
;
;			hex(0-3)+hexd0=hex(0-3)÷65536
;			hex(0-3)	整数部分
;			hexd		小数部分
DIV32_X65K
			bcf		STATUS,C	;/2
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/4
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/8
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/16
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/32
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/64
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/128
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/256
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/512
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/1024
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/2048
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/4096
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/8192
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/16384
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/32768
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/65536
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			return

;
;			32ビット1/4096除算
;			小数点以下は8bitまで演算、それ以下は破棄
;
;			hex(0-3)+hexd0=hex(0-3)÷4096
;			hex(0-3)	整数部分
;			hexd		小数部分
DIV32_X4K
			bcf		STATUS,C	;/2
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/4
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/8
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/16
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/32
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/64
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/128
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/256
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/512
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/1024
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/2048
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/4096
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			return


;
;			32ビット1/256除算
;			小数点以下は8bitまで演算、それ以下は破棄
;
;			hex(0-3)=hex(0-3)÷256
;			hex(0-3)	整数部分
;			hexd		小数部分
DIV32_X256
			bcf		STATUS,C	;/2
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/4
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/8
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/16
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/32
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/64
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/128
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			bcf		STATUS,C	;/256
			rrf		hex3,F		;32bitローテート
			rrf		hex2,F
			rrf		hex1,F
			rrf		hex0,F
			rrf		hexd,F
			return


;
;			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		;割る数の保存
			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.1(バグ修正版)
;		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	01h			;桁上がり発生、加算エラー終了
ad11		movf	hexw1,W		;W=hexw1
			addwf	hex1,F		;hex1=hex1+hexw1
			btfsc	STATUS,C
			retlw	0FFh		;キャリー発生、加算エラー終了
			retlw	0h			;加算正常終了


;		16ビットバイナリ減算
;		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	01h			;ボロー発生、減算エラー終了

sb11		movf	hexw1,W		;W=hexw1
			subwf	hex1,F		;hex1=hex1-hexw1
			btfss	STATUS,C
			retlw	0FFh		;ボロー発生、減算エラー終了
			retlw	0h			;減算正常終了


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		４バイトバイナリの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



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン	32MHZ用
;
;		1cycle	= 0.125us
;		使用レジスタ	= cnt2,cnt3
;		BSR		=0(BANK0)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u						;呼び出しも含めて、100us
								;call is 2cycles
			movlw	09h			;1
			movwf	cnt2		;1
			movlb	0h
			nop
			nop					;3
w100u		nop					;
			call	w10u		;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
			call	w10u
			call	w10u
			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
			movlb	0h
			movlw	05h
			movwf	cnt2
w5m			call	w1m
			decfsz	cnt2,F
			goto	w5m
			return

wait10m							; 10ms
			movlb	0h
			movlw	d'10'
			movwf	cnt2
w10m		call	w1m
			decfsz	cnt2,F
			goto	w10m
			return

wait20m							; 20ms
			movlb	0h
			movlw	d'20'
			movwf	cnt2
w20m		call	w1m
			decfsz	cnt2,F
			goto	w20m
			return
wait50m							; 50ms
			movlb	0h
			movlw	d'50'
			movwf	cnt2
w50m		call	w1m
			decfsz	cnt2,F
			goto	w50m
			return

wait100m						; 100ms
			movlb	0h
			movlw	d'100'
			movwf	cnt2
w100m		call	w1m
			decfsz	cnt2,F
			goto	w100m
			return

wait500m						; 500ms
			movlb	0h
			movlw	05h
			movwf	cnt3
w500m		call	wait100m
			decfsz	cnt3,F
			goto	w500m
			return

wait1s							; 1s
			movlb	0h
			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
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
w1m
			movlb	0h
			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サイクル消費する
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

w10u
			movlb	0h
			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

w05u
			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

w02u
			movlw	04h			;2us=0.125us*16cycles
			movwf	cnt0		;
w02u0		decfsz	cnt0,F		;2+3*3+2+1+2=16cycles
			goto	w02u0
			nop
			return				;
w01u
			nop					;1us=0.125us*8cycles
			nop					;2+4+2=8cycles
			nop
			nop
			return

			END

