;***** LogicIC_CheckerII1.asm *********************************************
;
;	簡易ロジックＩＣチェッカ II (Logic IC Checker II)
;     * 各種スイッチ入力, ＬＣＤ表示部（Ｕ１）*
;
;	Copyright (C) 2006-2018   by M.Yamamoto. All rights reserved.
;
;     ( coding:  Ver. 0.00   2006/04/21  by M.Yamamoto )
;	coding:  Ver. 1.00   2006/06/05  初期バージョン
;	update:  Ver. 2.10   2010/10/02  チャッタリング処理の改善
;	update:  Ver. 3.00   2018/04/30  CPUの変更と表示をLCDに変更
;	bugfix:  
;
;******************************************************* PicAsm 0244 ******

;	Device: PIC16F873A	Clock: 10MHz (セラロック)

;	Ver. 2.10 までは CPU に PIC16F628A を使用していたが、今回 (Ver. 3.00)、表示
;	をＬＣＤ化するに当たって 18 ピンでは入出力ポート数が少なく、それを補うため
;	に私が使い慣れている PIC16F87XA シリーズの内で 28 ピンの PIC16F873A に変更
;	をした。                                                     (2018/04/30)

#ifdef comment

 <機能概要>
　　この簡易ロジックＩＣチェッカ II  (Logic IC Checker II)は、「各種スイッチ入力, 
　ＬＣＤ表示部」（以下、Ｕ１という。）、「各種ロジックＩＣチェック, 結果表示部」
　（以下、Ｕ２という。）、および「各種ロジックＩＣチェック補助制御部」（以下、Ｕ３と
　いう。）の三部からなっている。

　　Ｕ１では、電源投入直後に十数秒間、スタートメッセージをＬＣＤに表示する。その後、
　"［００００］" をＬＣＤに表示して 、Ｕ２からＵ４経由でスイッチ入力イネーブル
　(j0: from U4) 信号を受け取ると待機状態になり、Ｕ１はＬＣＤのデバイス番号入力エリ
　ア内の "００００" をブリンク表示とし、各スイッチ入力の受け付けが可能となる。

　　デバイス番号の指定は、SW1: 1 位 ～ SW4: 1000 位の各桁スイッチ、および udsw: UP/
　DOWN スイッチで行い、７４シリーズでは７４を除いた数値を、前側を０の右づめで指定
　する(７４１３８→０１３８)。４０００・４５００シリーズではそのまま４桁を指定する。

　　その後、setsw: SET スイッチを押すと、Ｕ２にデバイス番号(j1: to U2)を送信し、
　Ｕ２では登録されているデバイス番号かどうかをチェックして、その結果をＯＫ／ＮＧ 
　ＬＥＤ表示、およびブザー音（"ポッ"／"ブー"）で知らせるとともに、Ｕ１にもそのチェ
　ック結果応答(j7: to U1) を返してくる。

　　デバイス番の登録チェックがＮＧであった場合には、入力エリアの右側に "Ｎｏｎｅ！" 
　と約３秒間表示し、その間、番号の確認が良くできるように一時的に番号入力エリア内の 
　"ｘｘｘｘ" は点灯しきりとなるが、３秒が経過して "Ｎｏｎｅ！" 表示が消えるとともに
　再び "ｘｘｘｘ" をブリンク表示として、入力番号が未だ確定されていないことを表して
　正しいデバイス番号の入力を促す。なおこの状態では cksw: CHECK スイッチを受け付けない。

　　デバイス番号登録チェックがＯＫであった場合には、Ｕ１ではＬＣＤのデバイス番号入
　力エリアのブリンク表示が点灯しきりとなって入力番号が確定されたことを表し、入力エ
　リアの右側に新たに正規のデバイス番号（名）が表示され、指定されたデバイス番号が登
　録されていることを知らせる。

　　デバイス番号登録チェックがＯＫであった場合、次に cksw: CHECK スイッチを押すと、
　チェック開始指令出力(j4: to U2)をＵ２に送信し、各デバイス別のデバイス機能チェッ
　クが開始される。チェック中は、各スイッチ入力を受け付けなくなる。また、チェック結
　果はＵ２ではデバイス番号登録チェックのときと同様に、ＯＫ／ＮＧ ＬＥＤ表示、および
　ブザー音（"ポッ"／"ブー"）で知らせるらせるとともに、Ｕ１にもそのチェック結果応答
　(j7: to U1) を返してくる。Ｕ１では正規のデバイス番号（名）の右側に"ＯＫ"／"ＮＧ"
　が表示される。

　　Ｕ２でのチェックが終了すると、Ｕ２からＵ４経由でのスイッチ入力イネーブル(j0: 
　from U4) 信号が再び送られ、Ｕ１では各スイッチ入力を受け付けるようになる。ただし、
　ＬＣＤの表示は今までの一連の過程が残ったままであるが、SW1: 1 位 ～ SW4: 1000 位
　の各桁スイッチのどれかを操作すると、それらがすべてクリアされ "［ｘｘｘｘ］" に
　戻って再びデバイス番号入力エリア "ｘｘｘｘ" をブリンク表示とする。

　また、この一連の過程が確認できる状態のときには入力番号が既に確定されているので、
　同じデバイス番号の被試験ＩＣを別のものに取り換えては CHECK スイッチを押すことを繰
　り返せば、 同番の被試験ＩＣが複数個ある場合にどんどんデバイス機能チェックだけを行
　っていくことができる。

 <デバイス番号の例外入力>
　被試験 ＩＣの電源（Vcc, GND）ピンが対角線上に配置されている一般的なデバイスの場合
　には、上記のようなデバイス番号の入力方法とその結果である正規のデバイス番号（名）の
　表示がされるが、電源ピンが対角線上に配置されていない特殊な電源ピン配置のデバイスの
　場合には、汎用の 24 pin ゼロプレッシャー・ソケットの使用ができないため、16 pin の
　補助ソケット、もしくは 特殊電源ピン・ソケットアダプタ を使用する必要がある。

　そのためにデバイス番号の入力方法も上記の例とは異なり、16 pin の補助ソケットを使用
　する場合は、７４・４０００・４５００シリーズのすべてにおいて先頭は "１" で、続く後
　の３桁は 前側を "０" の右づめ３桁で指定をする（例．７４７３→１０７３）。また、特
　殊電源ピン・ソケットアダプタを使用する場合は、同様にすべてのシリーズにおいて先頭は
　"９" で、 続く後の３桁は前側を"０"の右づめ３桁で指定をする（例．７４７３→９０７３、
　４０４９→９０４９）。

　このようにしてデバイス番号が入力された後に setsw : SET スイッチを押すと、上記と同
　様にＵ２にデバイス番号（j1 : to U2）を送信し、Ｕ２では登録されているデバイス番号か
　どうかを チェックして、その結果をＯＫ／ＮＧ ＬＥＤ表示、およびブザー音（"ポッ"／
　"ブー"）で知らせるとともに、Ｕ１にもそのチェック結果応答 (j7: to U1) を返してくる。
　もし、このデバイス番号登録チェックがＮＧであった場合には、入力エリアの右側に 
　"Ｎｏｎｅ！" と約３秒間表示されるのは上記の場合と同様である。

　デバイス番号登録チェックがＯＫであった場合には、Ｕ２では一般の電源ピン配置の場合と
　区別をするために、ＯＫ(緑)ＬＥＤ点灯と "ポッ" のブザー音を３回づつ繰り返し、ユーザ
　の注意喚起を促す。Ｕ１では正規のデバイス番号（名）の表示の前に "＊"／"＋" 記号を追
　加表示する。"＊" はデバイス番号の先頭を "１" で入力したときで補助ソケットを使用す
　ることを表し、"＋" はデバイス番号の先頭を "９" で入力したときで　ソケットアダプタ
　を使用することを表している。

 <ポーズ動作モード>
　通常のときの動作モードに対して、電源投入時に PAUSE スイッチを押しながら電源スイッ
　チをＯＮ した場合を "ポーズ動作モード" という。なお、詳細は pausw : PAUSE スイッチ
　と "Ｕ２：各種ロジックＩＣチェック, 結果表示部 の機能" を参照のこと。

　Ｕ１での通常の動作モードのときとの違いはデバイス機能チェックのときで、複数の機能チ
　ェックデータ項目の内の１つが終了するごとに本機はポーズ状態となり、何番目のチェック
　データの結果が ＯＫ／ＮＧであったかをＬＣＤに表示するので、ユーザーはそれを確認す
　ることができる。次に、PAUSE スイッチを押すことによってポーズ状態が解除され、次のチ
　ェックデータでのチェックが開始される。

　やがて、すべてのチェックデータによる機能チェックが終了したときか、または、BREAK ス
　イッチによってチェックを強制的に中断をしたときには、現在表示されている個別の結果表
　示を消して、改めて総合的な結果表示を通常の動作モードのときと同様な形式位置で表示し
　直す。

 <各スイッチの機能と操作法>
　　本機では、スイッチ入力イネーブル(j0: from U4) 信号が有効な場合のみ、次の各スイッ
　チ入力を受け付ける。ただし、udsw: UP/DOWN/BREAK スイッチを BREAK スイッチとして機
　能させる場合を除く。

・SW1: 1 位の桁スイッチ
　　４桁のデバイス番号の内、 1 位の桁を指定する場合に用いる。
　　１回押すごとに１づつカウントアップされ、対応する 1 位の桁のＬＣＤのデバイス番号
　入力エリアに表示される。なお、このときに udsw: UP/DOWN スイッチと併用した場合は、
　１づつカウントダウンされる。 
　　( 0, 1, …… 8, 9, 0, 1, …… / 9, 8, …… 2, 1, 0, 9, …… )

・SW2: 10 位の桁スイッチ
　　４桁のデバイス番号の内、10 位の桁を指定する場合に用いる。
　　１回押すごとに１づつカウントアップされ、対応する 10 位の桁のＬＣＤのデバイス番
　号入力エリアに表示される。なお、このときに udsw: UP/DOWN スイッチと併用した場合は、
　１づつカウントダウンされる。 
　　( 0, 1, …… 8, 9, 0, 1, …… / 9, 8, …… 2, 1, 0, 9, …… )

・SW3: 100 位の桁スイッチ
　　４桁のデバイス番号の内、100 位の桁を指定する場合に用いる。
　　１回押すごとに１づつカウントアップされ、対応する 100 位の桁のＬＣＤのデバイス番
　号入力エリアに表示される。なお、このときに udsw: UP/DOWN スイッチと併用した場合は、
　１づつカウントダウンされる。 
　　( 0, 1, …… 8, 9, 0, 1, …… / 9, 8, …… 2, 1, 0, 9, …… )

・SW4: 1000 位の桁スイッチ
　　４桁のデバイス番号の内、1000 位の桁を指定する場合に用いる。
　　１回押すごとに１づつカウントアップされ、対応する 1000 位の桁のＬＣＤのデバイス
　番号入力エリアに表示される。なお、このときに udsw: UP/DOWN スイッチと併用した場合
　は、１づつカウントダウンされる。 
　　( 0, 1, …… 8, 9, 0, 1, …… / 9, 8, …… 2, 1, 0, 9, …… )

・udsw: UP/DOWN/BREAK スイッチ
　　SW1: 1 位の桁 ～ SW4: 1000 位の桁スイッチとともに使用し、udsw: UP/DOWN スイッチ
　を押しながら各桁スイッチを押した場合には、各桁が１づつカウントダウンされる。
　　また、被試験ＩＣのデバイス機能チェック時で休止(PAUSE)状態になったときに、このス
　イッチを押下することでデバイスチェックを中断（BREAK）することができる。

・setsw: SET スイッチ
　　入力された４桁のデバイス番号を、次のデータ形式でＵ２に送信(j1: to U2)する。
 "スタートビット(1) + 1000 位(4) + 100 位(4) + 10 位(4) + 1 位(4) + ストップビット(1)"
　　なお、このときに udsw: UP/DOWN スイッチと併用した場合は、デバイス番号の送信は行
　われず、ＬＣＤの 1 位の桁 ～ 1000 位の桁の４桁のすべて、即ち、デバイス番号入力エリ
　アが "００００" にクリアされる。

・cksw: CHECK スイッチ
　　チェック開始指令(j4: to U2)出力を有効とし、Ｕ２に送信をする。

・pausw: PAUSE スイッチ
　　このスイッチだけはＵ２で管理をしており "ポーズ動作モード" の場合に有効となって、
　デバイス番号登録チェックのときには、入力された４桁のデバイス番号をブザー音の数で知
　らせたり、また被試験ＩＣのデバイス機能チェックのときには、各チェックデータごとに結
　果を表示した後、休止(PAUSE)状態になったのをこのスイッチの押下で解除することができる。
　なお、この "ポーズ動作モード" 中であるかどうかはＵ１側でも把握する必要があるため、
　Ｕ１の入力ポートにも接続をして電源投入時に検出をしている。

 <ＬＣＤの表示機能>
　　SW1: 1 位の桁 ～ SW4: 1000 位の各桁スイッチで入力指定されたデバイス番号を、ＬＣＤ
　左側先頭位置に表示の "［　　　　］" 内の入力エリア４桁 "ｘｘｘｘ" で表示する。各桁
　スイッチで入力中、または setsw: SET スイッチ押下でのデバイス番号登録チェックの結果
　がＮＧだった場合には、ブリンク表示となりデバイス番号がまだ確定できていない状態を表
　す。なお、デバイス番号登録チェックの結果がＮＧだった場合には、入力エリアの右側に 
　"Ｎｏｎｅ！" と約３秒間表示される。

　　また、デバイス番号登録チェックの結果がＯＫだった場合には、ブリンク表示から点灯し
　きりとなりデバイス番号が確定状態であることを表すとともに、入力エリアの右側に新たに
　正規のデバイス番号（名）が表示され、指定されたデバイス番号が登録されていることを知
　らせる。

　　このデバイス番号が確定状態のときに cksw: CHECK スイッチを押下すると、各デバイス別
　のデバイス機能チェックが開始され、そのチェックの結果が正規のデバイス番号（名）の右
　側に "ＯＫ" ／"ＮＧ" で表示される。

　　なお、cksw: CHECK スイッチ押下でのデバイス機能チェックの終了後もこの表示状態は持
　続するが、一旦各桁スイッチのどれかを押下すると、確定状態が解除されＬＣＤの入力エリ
　アは再びブリンク表示となるとともに、表示されていた正規のデバイス番号（名）やチェッ
　ク結果もクリアされる。

　　被試験ＩＣのデバイス機能チェック中でポーズ指定がされている場合には、被試験ＩＣご
　とに指定された複数のチェックデータの内の１つが終了するごとに本機はポーズ状態になり、
　そのチェックの結果が正規のデバイス番号（名）の右側に "ＯＫ" ／ "ＮＧ" で表示される
　とともに、何番目のチェックデータかを "ｘｘ" と２桁で表示して知らせる。やがて、設定
　されているすべてのチェックデータが終了するか、または途中で udsw: UP/DOWN/BREAK ス
　イッチで強制的に終了させた場合には、総合的なチェック結果を "ＯＫ" ／ "ＮＧ" で表示
　する。

#endif

;	PIC16F873A のピンと用途

;	 (1) MCLR:マスター・クリア入力				 (28) RB7: LCD DB7 出力
;	 (2) RA0: 予備						 (27) RB6: LCD DB6 出力
;	 (3) RA1: デバイス番号(j1)出力／チェック結果応答(j7)入力 (26) RB5: LCD DB5 出力
;	 (4) RA2: ポーズ信号(j6)入力				 (25) RB4: LCD DB4 出力
;	 (5) RA3: チェック開始／中断指令(j4)出力		 (24) RB3: LCD RS 出力
;	 (6) RA4: 予備						 (23) RB2: LCD R/W 出力
;	 (7) RA5: スイッチ入力イネーブル(j0)入力		 (22) RB1: LCD E 出力
;　	 (8) VSS: 電源 GND					 (21) RB0: 予備
;	 (9) OSC1:オシレータ水晶入力				 (20) VDD: 電源 +5V DC
;	(10) OSC2:オシレータ水晶入力				 (19) VSS: 電源 GND
;	(11) RC0:    1 位スイッチ入力				 (18) RC7: チェック結果応答(j7)入力
;	(12) RC1:   10 位スイッチ入力				 (17) RC6: CHECK スイッチ入力
;	(13) RC2:  100 位スイッチ入力				 (16) RC5:   SET スイッチ入力
;	(14) RC3: 1000 位スイッチ入力				 (15) RC4: UP/DOWN/BREAK スイッチ入力

;	*注.  RA4 の出力はオープンドレインのため、外部抵抗でプルアップしないと、High が
;	      出力されない。

;==========================================================================

	list		p=pic16f873A		;デバイス情報
	include		p16f873A.inc		;インクルードファイル
	errorlevel	-302			;Eliminate bank warning

;==========================================================================
;		コンフィギュレーションの設定
;==========================================================================
 
	__config _CP_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC

;==========================================================================
;		定数、変数の定義とレジスタ割付け
;==========================================================================

#define 	ver_no	"3.00"
#define 	wait_xxms	wait_w1ms

		radix	dec

j0		equ	5		;RA5: スイッチ入力イネーブル入力(j0: from U4)
j1		equ	1		;RA1: デバイス番号出力(j1: to U2)
j4		equ	3		;RA3: チェック開始／中断指令出力(j4: to U2)
j6		equ	2		;RA2: ポーズ信号入力(j6: from U2)
j7		equ	1		;RA1: チェック結果応答入力(j7: from U2) 
					;(注: jx, Ux は回路図中の記号に対応)
 
sw1		equ	0		;RC0:    1 位の桁スイッチ
sw2		equ	1		;RC1:   10 位の桁スイッチ
sw3		equ	2		;RC2:  100 位の桁スイッチ
sw4		equ	3		;RC3: 1000 位の桁スイッチ
udsw		equ	4		;RC4: UP/DOWN/BREAK スイッチ
setsw		equ	5		;RC5:   SET スイッチ
cksw		equ	6		;RC6: CHECK スイッチ
pausw		equ	7		;RC7: PAUSE スイッチ

LCD		equ	PORTB		;LCD 制御用ポート
TRIS_LCD	equ	TRISB		;LCD 制御用ポートの入出力切り替え
_E		equ	1		;LCD E:   動作起動信号
_RW		equ	2		;LCD R/W: 読み出し／書き込み選択信号
_RS		equ	3		;LCD RS:  レジスタ選択信号
_BF		equ	7		;LCD ビジーフラグ

bit0		equ	0		;フラグのビット0
bit1		equ	1		;フラグのビット1
bit2		equ	2		;フラグのビット2

cntdat		equ	65535 - 5000	;TMR1 にセットする初期値（割り込み周期）(4/10Mz*5000=2msec)
tm_adj		equ	250		;タイムアウトスキップ回数 (2msec x 250 = 500msec)
none_time	equ	6		;"None!" 表示時間 (500msec x 6 = 3 sec)
chatt		equ	100		;チャッタリング吸収用ウエイト時間 (2msec x 100 = 200msec)

		cblock  h'20'
digit4					;1000 位カウンタ
digit3					; 100 位カウンタ
digit2					;  10 位カウンタ
digit1					;   1 位カウンタ
digit43					;デバイス番号 1000 位 + 100 位
digit21					;デバイス番号   10 位 +   1 位
paucnt2					;ポーズ番号カウンタ 10 位
paucnt1					;ポーズ番号カウンタ  1 位
tmoutcnt				;タイムアウトカウンタ
nonecnt					;"None!" LCD 表示時間カウンタ
chatcnt					;チャッタリング吸収カウンタ
updwnflg				;UP/DOWN フラグ
blinkflg				;LCD 点滅フラグ
blinkmem				;blinkflg の状態を記憶
disp_cnt				;LCD 表示で使用するカウンタ
updtflg					;LCD 表示更新フラグ(0),(1)
					;(bit0:入力デバイス番号の表示更新 / bit1:クリア後に"[    ]"新規表示)
sendflg					;デバイス番号送信フラグ(0),(1)
					;(bit0:デバイス番号送信済み / bit1:デバイス番号チェックOK)
dvckflg					;被試験ＩＣのデバイスチェックフラグ(0),(1)
					;(bit0:デバイスチェック開始指令 / bit1:デバイスチェック済み)
pauseflg				;ポーズ信号フラグ
resckflg				;応答信号チェックフラグ
pau_flag				;休止スイッチ有効フラグ
sdtemp					;送信バイトの一時保存
lpcnt					;送信ビット用ループカウンタ
wtcnt1					;ウェイト用ループカウンタ
wtcnt2					;ウェイト用ループカウンタ
wtcnt3					;ウェイト用ループカウンタ
wtcnt4					;ウェイト用ループカウンタ

addr_high	;(LCD.subで使用)	;読み出すデータの high アドレス
addr_low	;(LCD.subで使用)	;読み出すデータの low アドレス
lcdtmp		;(LCD.subで使用)	;LCD への入出力データの一時保存
		endc

		cblock  h'70'
w_save					;W レジスタの退避用
s_save					;STATUS レジスタの退避用
		endc

;==========================================================================
;		マクロ命令定義
;==========================================================================

;		LCD メッセージデータ表示マクロ

Disp_Lcd	macro	@com,@msg,@x
		movlw	@com
		call	Lcd_Cmd		;LCD へコマンドを出力
	#if 	@x == 0
	#else
		movlw	high @msg	;メッセージデータの先頭アドレスの high アドレス
		movwf	addr_high	;
		movlw	low @msg	;メッセージデータの先頭アドレスの low アドレス
		movwf	addr_low	;
	#endif
		call	Lcd_Disp	;メッセージデータ１行表示
		endm

;==========================================================================
;		プログラム開始
;==========================================================================

		org	0		;リセットベクタ
		goto	init
		org	4		;割り込みベクタ
		goto	interrupt

;==========================================================================
;		サブルーチンファイルのインクルード
;==========================================================================

		org	8

		include		C:\Data\Project\PIC\_sub\LCD.sub

;==========================================================================
;		初期化処理
;==========================================================================

init
		bcf	STATUS,RP1	;バンク 0
		bcf	STATUS,RP0
		clrf	ADCON0		;ADCON0 の設定, A/D 未使用

;		bcf	STATUS,RP1	;バンク 1
		bsf	STATUS,RP0
		movlw	h'06'		;PCFG=0110: すべてデジタルポート指定
		movwf	ADCON1

		movlw	h'80'		;PBPU=1: プルアップ抵抗を使用しない
		movwf	OPTION_REG

		movlw	b'00110111'	;RA5-4,2-0: 入力, RA3: 出力
		movwf	TRISA		;ポートA の I/O 設定
		movlw	b'00000001'	;RB7-1: 出力, RB0: 入力
		movwf	TRISB		;ポートB の I/O 設定
		movlw	b'11111111'	;RC7-0: 入力
		movwf	TRISC		;ポートC の I/O 設定

		bsf	PIE1,TMR1IE	;タイマー１割り込みを許可

;		bcf	STATUS,RP1	;バンク 0
		bcf	STATUS,RP0

		movlw	b'00000001'	;bit7-6: 未使用
					;bit5-4(T1CKPS1,0 )=00: プリスケーラのスケール値 1:1
					;bit3(T1OSCEN)=0: 専用の発振器を使う場合に指定
					;bit2(T1SYNC)=0: 外部入力クロック指定時に有効
					;bit1(TMR1CS)=0: 内部クロックを使う
					;bit0(TMR1ON)=1: タイマー１を動作
		movwf	T1CON

		bsf	PORTA,j4	;RA3=1: チェック開始指令出力(j4: to U2) = disable

		movlw	high cntdat
		movwf	TMR1H		;TMR1H に設定
		movlw	low cntdat	;
		movwf	TMR1L		;TMR1L に設定

		bcf	INTCON,PEIE	;PEIE: 周辺機器割り込み禁止
		bsf	INTCON,GIE	;GIE: 全割り込み許可

		clrf	pau_flag	;休止スイッチ有効フラグ = OFF
		btfss	PORTC,pausw	;休止解除スイッチ = ON か？
		bsf	pau_flag,bit0	;Yes. 休止スイッチ有効フラグ = ON

		clrf	digit4		;1000 位カウンタの初期設定
		clrf	digit3		; 100 位カウンタの初期設定
		clrf	digit2		;  10 位カウンタの初期設定
		clrf	digit1		;   1 位カウンタの初期設定

		clrf	chatcnt		;チャッタリング吸収カウンタの初期設定
		clrf	updtflg		;LCD 表示更新フラグ(0),(1)の初期設定
		clrf	sendflg		;デバイス番号送信フラグ(0),(1)の初期設定
		clrf	dvckflg		;被試験ＩＣデバイスチェックフラグ(0),(1)の初期設定
		clrf	blinkflg	;点滅フラグの初期設定
		clrf	blinkmem	;blinkflg の状態記憶の初期設定

		; DMC16117A(LCD) 初期設定, スタートメッセージの表示

		clrf	LCD		;LCD 制御用ポート
		call	Lcd_Init	;LCD 初期設定 

		movlw	b'00001100'	;表示ON
		call	Lcd_Cmd		;LCD へコマンドを出力

		movlw	1	;3
		movwf	disp_cnt	;スタートメッセージの表示回数
ini01
;		dt	"Logic IC",0," Checker",0	を表示
		Disp_Lcd	b'00000010',start_msg,1	;カーソルホーム
		Disp_Lcd	b'11000000',         ,0	;DDRAM アドレスセット
		call	wait_1sec
		call	wait_500ms

;		dt	"    Ver.",0," x.xx   ",0	を表示
		Disp_Lcd	b'00000010',         ,0	;カーソルホーム
		Disp_Lcd	b'11000000',         ,0	;DDRAM アドレスセット
		call	wait_1sec
		call	wait_500ms

;		dt	"  by m.y",0,"amamoto ",0	を表示
		Disp_Lcd	b'00000010',         ,0	;カーソルホーム
		Disp_Lcd	b'11000000',         ,0	;DDRAM アドレスセット
		call	wait_1sec
		call	wait_500ms
		decfsz	disp_cnt,F
		goto	ini01

		bsf	updtflg,bit1	;LCD 表示新規フラグ = ON
		bsf	updtflg,bit0	;LCD 表示更新フラグ = ON
		bsf	INTCON,PEIE	;PEIE タイマー１割り込み許可
		goto	main

		; スタートメッセージ

start_msg	dt	"Logic IC",0," Checker",0
		dt	"    Ver.",0," ",ver_no,"   ",0
		dt	"  by m.y",0,"amamoto ",0
		;	 01234567     89ABCDEF

in_area		dt	"[    ]",0

;==========================================================================
;		メイン・ルーチン
;==========================================================================

;updtflg:  LCD 表示更新フラグ               (bit0=1:入力デバイス番号の表示更新 / bit1=1:クリア後に"[    ]"新規表示)
;blinkflg: LCD デバイス番号点滅フラグ       (bit0=0:デバイス番号点表示 / bit0=1:デバイス番号滅表示)
;sendflg:  デバイス番号送信フラグ           (bit0=1:デバイス番号送信済み / bit1=1:デバイス番号チェックOK)
;dvckflg:  被試験ＩＣデバイスチェックフラグ (bit0=1:デバイスチェック開始指令 / bit1=1:デバイスチェック済み)

		; 入力デバイス番号の LCD 表示
main
		btfss	updtflg,bit1	;LCD 表示更新フラグ(1) = ON か？
		goto	main01		;No

		bcf	updtflg,bit1	;LCD 表示更新フラグ(1)のクリア
		Disp_Lcd	b'00000001',in_area,1	;表示クリア（カーソルをホーム位置に戻す）
		movlw	b'00001100'	;表示オン／オフコントロール
		call	Lcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

main01		btfss	updtflg,bit0	;LCD 表示更新フラグ(0) = ON か？
		goto	main02		;No

		bcf	updtflg,bit0	;LCD 表示更新フラグ(0)のクリア
		bcf	blinkflg,bit0	;点滅フラグのクリア
		bcf	blinkmem,bit0	;blinkflg の状態を記憶
		goto	main03

main02		movf	blinkflg,W
		xorwf	blinkmem,W
		btfsc	STATUS,Z	;blinkflg = blinkmem か？
		goto	main07		;Yes

		movf	blinkflg,W
		movwf	blinkmem	;blinkflg の状態を記憶

		btfsc	blinkflg,bit0	;点滅フラグ = ON か？
		goto	main05		;Yes

main03		; LCD 点滅の点を表示
		movlw	b'10000001'	;DDRAM アドレスセット
		call	Lcd_Cmd		;LCD へコマンドを出力
		movlw	4
		movwf	disp_cnt	;表示文字数カウンタ
		movlw	digit4		;1000 位カウンタ
		movwf	FSR		;間接アドレスの先頭番地の初期設定

main04		movf	INDF,W		;各位カウンタデータ
		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力

		incf	FSR,F		;間接アドレスの更新
		decfsz	disp_cnt,F
		goto	main04
		goto	main07

main05		; LCD 点滅の滅を表示
		btfsc	sendflg,bit1	;デバイス番号送信フラグ(1) = ON か？
		goto	main07		;Yes

		movlw	b'10000001'	;DDRAMアドレスセット
		call	Lcd_Cmd		;LCD へコマンドを出力
		movlw	4
		movwf	disp_cnt	;表示文字数カウンタ

main06		movlw	' '
		call	Lcd_Data	;LCD へデータを１文字出力
		decfsz	disp_cnt,F
		goto	main06

		; 各種スイッチのチェック

main07		btfsc	PORTA,j0	;スイッチ入力イネーブル(j0: from U4) か？
		goto	main08		;No

		bsf	INTCON,PEIE	;PEIE タイマー１割り込み許可
		movf	chatcnt,F
		btfss	STATUS,Z	;チャッタリング吸収カウンタ = 0 か？
		goto	main		;No

		btfss	PORTC,udsw	;UP/DOWN/BREAK スイッチ = ON か？
		call	udsw_on		;Yes
		btfsc	PORTC,udsw	;UP/DOWN/BREAK スイッチ = OFF か？
		call	udsw_off	;Yes

		btfss	PORTC,sw1	;   1 位の桁スイッチ = ON か？
		call	sw1_on		;Yes
		btfss	PORTC,sw2	;  10 位の桁スイッチ = ON か？
		call	sw2_on		;Yes
		btfss	PORTC,sw3	; 100 位の桁スイッチ = ON か？
		call	sw3_on		;Yes
		btfss	PORTC,sw4	;1000 位の桁スイッチ = ON か？
		call	sw4_on		;Yes

		btfss	PORTC,setsw	;SET スイッチ = ON か？
		call	setsw_on	;Yes. デバイス番号の送信(j1: to U2)
		btfss	PORTC,cksw	;CHECK スイッチ = ON か？
		call	cksw_on		;Yes. チェック開始指令出力(j4: to U2) 

		; デバイス番号チェックの結果受信

		btfss	sendflg,bit0	;デバイス番号送信フラグ(0) = ON か？
		goto	main		;No.	(bit0=1: デバイス番号送信済み)

		btfss	sendflg,bit1	;デバイス番号送信フラグ(1) = ON か？
					;	(bit1=1: デバイス番号チェックOK)
		call	check_respons	;No. デバイス番号チェックの結果受信
		goto	main

		; 被試験ＩＣのデバイスチェックの結果受信

main08		bcf	INTCON,PEIE	;PEIE タイマー１割り込み禁止

		btfss	dvckflg,bit0	;被試験ＩＣのデバイスチェックフラグ(0) = ON か？
		goto	main		;No.	(bit0=1:デバイスチェック開始指令)

		btfsc	dvckflg,bit1	;被試験ＩＣのデバイスチェックフラグ(1) = OFF か？
		goto	main		;No.	(bit1=1:デバイスチェック済み)

		btfsc	pau_flag,bit0	;休止スイッチ有効フラグ = ON か？
		goto	main09		;Yes

		call	check_respons	;No. デバイスチェックの結果受信
		goto	main

main09		call	pause_dvck	;休止スイッチ有効フラグ = ON のとき
		goto	main

;==========================================================================
;		休止スイッチ有効フラグ = ON のときの処理
;==========================================================================

;pauseflg: ポーズ信号フラグ   bit0=0/1:デバイスチェックの結果受信可/不可
;			      bit1=0/1:ポーズ番号カウンタ更新可/不可
;			      bit2=0/1:デバイスチェックのエラー無し/有り

pause_dvck
		clrf	pauseflg	;ポーズ信号フラグ(0),(1),(2)の初期設定
	;;	bcf	pauseflg,bit0	;ポーズ信号フラグ(0) = OFF: bit0=0:デバイスチェックの結果受信可
		bsf	pauseflg,bit1	;ポーズ信号フラグ(1) = ON:  bit1=1:ポーズ番号カウンタ更新不可
	;;	bcf	pauseflg,bit2	;ポーズ信号フラグ(2) = OFF: bit2=0:デバイスチェックのエラー無し
		clrf	paucnt1		;ポーズ番号カウンタ  1 位の桁の初期設定
		clrf	paucnt2		;ポーズ番号カウンタ 10 位の桁の初期設定

pau01		btfss	PORTA,j6	;ポーズ信号入力(j6: from U2) = "H" か？
		goto	pau02		;No

		btfsc	pauseflg,bit0	;ポーズ信号フラグ(0) = OFF か？
		goto	pau04		;No

		call	check_respons	;デバイスチェックの結果受信
		bsf	pauseflg,bit0	;ポーズ信号フラグ(0) = ON
		bcf	pauseflg,bit1	;ポーズ信号フラグ(1) = OFF
		goto	pau04

pau02		btfsc	pauseflg,bit1	;ポーズ信号フラグ(1) = OFF か？
		goto	pau04		;No

		incf	paucnt1,F	;ポーズ番号カウンタ 1 位の桁を +1 更新
		movf	paucnt1,W
		sublw	9
		btfsc	STATUS,C	;ポーズ番号カウンタ 1 位の桁 > 9 か？
		goto	pau03		;No

		incf	paucnt2,F	;Yes. ポーズ番号カウンタ 10 位の桁を +1 更新
		clrf	paucnt1		;ポーズ番号カウンタ 1 位の桁 = 0

pau03		movlw	h'c6'		;チェック結果の先頭表示位置
		call	Lcd_Cmd		;LCD へコマンドを出力

		movf	paucnt2,W	;ポーズ番号カウンタ 10 位 
		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力

		movf	paucnt1,W	;ポーズ番号カウンタ 1 位 
		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力
		bcf	pauseflg,bit0	;ポーズ信号フラグ(0) = OFF
		bsf	pauseflg,bit1	;ポーズ信号フラグ(1) = ON

		; UP/DOWN/BREAK スイッチ (チェック中断) のチェック

pau04		btfss	PORTA,j0	;スイッチ入力イネーブル(j0: from U4) か？
		goto	pau05		;Yes. チェック終了

		btfsc	PORTC,udsw	;UP/DOWN/BREAK スイッチ = ON か？
		goto	pau01		;No
;;
		call	udsw_on		;Yes. チェック中断指令出力(j4: to U2)
		bsf	pauseflg,bit2	;ポーズ信号フラグ(2) = ON: デバイスチェックのエラー有り表示

		; 総合結果の表示

pau05		movlw	h'c4'		;Yes. チェック結果の先頭表示位置
		call	Lcd_Cmd		;LCD へコマンドを出力
		movlw	' '
		call	Lcd_Data	;LCD へデータを１文字出力

		btfsc	pauseflg,bit2	;ポーズ信号フラグ(2): デバイスチェックのエラー無し か？
		goto	pau06		;No

		movlw	'O'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	'K'
		call	Lcd_Data	;LCD へデータを１文字出力
		goto	pau07

pau06		movlw	'N'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	'G'
		call	Lcd_Data	;LCD へデータを１文字出力

pau07		movlw	' '
		call	Lcd_Data	;LCD へデータを１文字出力
		return

;==========================================================================
;		udsw: UP/DOWN/BREAK スイッチ = ON の処理
;==========================================================================

udsw_on
		btfsc	PORTA,j0	;RA5=0: スイッチ入力イネーブル(j0: from U4) = "L" か？
		goto	udon01		;No

		btfsc	updwnflg,bit0	;UP/DOWN フラグ = ON か？
		goto	udon03		;Yes

		bsf	updwnflg,bit0	;UP/DOWN フラグ = ON
		goto	udon02

udon01		bcf	PORTA,j4	;RA3=0: チェック中断指令出力(j4: to U2) = enable
		call	wait_4ms	;4m 秒 ウェイト
		bsf	PORTA,j4	;RA3=1: チェック中断指令出力(j4: to U2) = disable

udon02		movlw	chatt		;チャッタリング吸収用ウエイト時間を
		movwf	chatcnt		;チャッタリング吸収カウンタに設定

udon03		return

;==========================================================================
;		udsw: UP/DOWN/BREAK スイッチ = OFF の処理
;==========================================================================

udsw_off
		btfss	updwnflg,bit0	;UP/DOWN フラグ = OFF か？
		goto	udof01		;Yes

		bcf	updwnflg,bit0	;UP/DOWN フラグ = OFF

		movlw	chatt		;チャッタリング吸収用ウエイト時間を
		movwf	chatcnt		;チャッタリング吸収カウンタに設定

udof01		return

;==========================================================================
;		SW1: 1 位の桁スイッチ = ON の処理
;==========================================================================

sw1_on
		btfsc	updwnflg,bit0	;UP/DOWN フラグ = 0(OFF) か？
		goto	s1on01		;No

		incf	digit1,F	;1 位カウンタの +1 更新
		movlw	10
		subwf	digit1,W	;digit1 >= 10 か？
		btfsc	STATUS,C
		clrf	digit1		;Yes. 1 位カウンタ = 0 に設定
		goto	s1on02

s1on01		movlw	1
		subwf	digit1,F	;1 位カウンタの -1 更新
		movlw	9
		btfss	STATUS,C	;digit1 >= 0 か？
		movwf	digit1		;No. 1 位カウンタ = 9 に設定

s1on02		call	flag_set	;各フラグの設定
		return

;--------------------------------------------------------------------------

		; 各フラグの設定

flag_set
		btfsc	sendflg,bit1	;デバイス番号送信フラグ(1) = ON か？
		bsf	updtflg,bit1	;Yes. LCD 表示更新フラグ(1) = ON
		bsf	updtflg,bit0	;LCD 表示更新フラグ(0) = ON
		clrf	sendflg		;デバイス番号送信フラグ(0),(1)のクリア
		clrf	dvckflg		;被試験ＩＣのデバイスチェックフラグ(0),(1)のクリア

		movlw	chatt		;チャッタリング吸収用ウエイト時間を
		movwf	chatcnt		;チャッタリング吸収カウンタに設定
		return

;==========================================================================
;		SW2: 10 位の桁スイッチ = ON の処理
;==========================================================================

sw2_on
		btfsc	updwnflg,bit0	;UP/DOWN フラグ = 0(OFF) か？
		goto	s2on01		;No

		incf	digit2,F	;10 位カウンタの +1 更新
		movlw	10
		subwf	digit2,W	;digit2 >= 10 か？
		btfsc	STATUS,C
		clrf	digit2		;Yes. 10 位カウンタ = 0 に設定
		goto	s2on02

s2on01		movlw	1
		subwf	digit2,F	;10 位カウンタの -1 更新
		movlw	9
		btfss	STATUS,C	;digit2 >= 0 か？
		movwf	digit2		;No. 10 位カウンタ = 9 に設定

s2on02		call	flag_set	;各フラグの設定
		return

;==========================================================================
;		SW3: 100 位の桁スイッチ = ON の処理
;==========================================================================

sw3_on
		btfsc	updwnflg,bit0	;UP/DOWN フラグ = 0(OFF) か？
		goto	s3on01		;No

		incf	digit3,F	;100 位カウンタの +1 更新
		movlw	10
		subwf	digit3,W	;digit3 >= 10 か？
		btfsc	STATUS,C
		clrf	digit3		;Yes, 100 位カウンタ = 0 に設定
		goto	s3on02

s3on01		movlw	1
		subwf	digit3,F	;100 位カウンタの -1 更新
		movlw	9
		btfss	STATUS,C	;digit3 >= 0 か？
		movwf	digit3		;No. 100 位カウンタ = 9 に設定

s3on02		call	flag_set	;各フラグの設定
		return

;==========================================================================
;		SW4: 1000 位の桁スイッチ = ON の処理
;==========================================================================

sw4_on
		btfsc	updwnflg,bit0	;UP/DOWN フラグ = 0(OFF) か？
		goto	s4on01		;No

		incf	digit4,F	;1000 位カウンタの +1 更新
		movlw	10
		subwf	digit4,W	;digit4 >= 10 か？
		btfsc	STATUS,C
		clrf	digit4		;Yes, 1000 位カウンタ = 0 に設定
		goto	s4on02

s4on01		movlw	1
		subwf	digit4,F	;1000 位カウンタの -1 更新
		movlw	9
		btfss	STATUS,C	;digit4 >= 0 か？
		movwf	digit4		;No. 1000 位カウンタ = 9 に設定

s4on02		call	flag_set	;各フラグの設定
		return

;==========================================================================
;		setsw: SET スイッチ = ON の処理
;==========================================================================

setsw_on
		btfsc	updwnflg,bit0	;UP/DOWN フラグ = ON か？
		goto	sson01		;Yes

		movf	nonecnt,W	;					;;
		btfss	STATUS,Z	;"None!" LCD 表示時間カウンタ = 0 か？	;;setsw を連続で押した
		goto	sson02		;No					;;（押しっぱなしにした）
										;;ときのために必要
		movlw	10		;					;;
		call	wait_w1ms	;10m 秒 ウェイト			;;

		call	tx_data		;デバイス番号を送信(j1: to U2)
		bsf	sendflg,bit0	;デバイス番号送信フラグ(0) = ON
					;	(bit0=1: デバイス番号送信済み = ON)
		bcf	sendflg,bit1	;デバイス番号送信フラグ(1) = OFF
					;	(bit1=0: デバイス番号チェックOK = OFF)
		clrf	dvckflg		;被試験ＩＣのデバイスチェックフラグ(0),(1)のクリア
		movlw	chatt		;チャッタリング吸収用ウエイト時間を
		movwf	chatcnt		;チャッタリング吸収カウンタに設定
		goto	sson02

sson01		clrf	digit4		;1000 位の桁カウンタのクリア
		clrf	digit3		; 100 位の桁カウンタのクリア
		clrf	digit2		;  10 位の桁カウンタのクリア
		clrf	digit1		;   1 位の桁カウンタのクリア
		call	flag_set	;各フラグの設定

sson02		return

;==========================================================================
;		cksw: CHECK スイッチ = ON の処理
;==========================================================================

cksw_on
		btfss	sendflg,bit1	;デバイス番号送信フラグ(1) = ON か？
		goto	cson01		;No

		movlw	h'c5'		;チェック結果の先頭表示位置	;;
		call	Lcd_Cmd		;LCD へコマンドを出力		;;
		movlw	' '						;;cksw の後、また cksw を
		call	Lcd_Data	;LCD へデータを１文字出力	;;押したときのために必要
		movlw	' '						;;
		call	Lcd_Data	;LCD へデータを１文字出力	;;

		bcf	PORTA,j4	;RA3=0: チェック開始指令出力(j4: to U2) = enable
		call	wait_4ms	;4m 秒 ウェイト
		bsf	PORTA,j4	;RA3=1: チェック開始指令出力(j4: to U2) = disable

		bsf	dvckflg,bit0	;被試験ＩＣのデバイスチェックフラグ(0) = ON
					;	(bit0=1:デバイスチェック開始指令 = ON)
		bcf	dvckflg,bit1	;被試験ＩＣのデバイスチェックフラグ(1) = OFF
					;	(bit1=0:デバイスチェック済み = OFF)
		movlw	chatt		;チャッタリング吸収用ウエイト時間を
		movwf	chatcnt		;チャッタリング吸収カウンタに設定

cson01		return

;==========================================================================
;	デバイス番号を「各種ロジックＩＣチェック, 結果表示部」に送信
;==========================================================================

; スタートビット(1) + 1000 位(4) + 100 位(4) + 10 位(4) + 1 位(4) + ストップビット(1)

tx_data
		swapf	digit4,W	;上位と下位を入れ替え
		iorwf	digit3,W	;
		movwf	digit43		;デバイス番号 1000 位 + 100 位
		swapf	digit2,W	;上位と下位を入れ替え
		iorwf	digit1,W	;
		movwf	digit21		;デバイス番号   10 位 +   1 位

		bcf	INTCON,PEIE	;PEIE タイマー１割り込み禁止
		bsf	STATUS,RP0	;バンク 1
		bcf	TRISA,j1	;I/0 出力設定
		bcf	STATUS,RP0	;バンク 0

		bcf	PORTA,j1	;スタートビット送出
		call	wait_4ms	;4m 秒 ウェイト

		movf	digit43,W
		call	tx_byte		;デバイス番号 1000 位 + 100 位を送出
		movf	digit21,W
		call	tx_byte		;デバイス番号   10 位 +   1 位を送出

		bsf	PORTA,j1	;ストップビット送出
		call	wait_4ms	;4m 秒 ウェイト

		bsf	STATUS,RP0	;バンク 1
		bsf	TRISA,j1	;I/0 入力設定
		bcf	STATUS,RP0	;バンク 0
		bsf	INTCON,PEIE	;PEIE タイマー１割り込み許可
		return

		; １バイト転送
tx_byte
		movwf	sdtemp		;送信バイトワークに保存
		movlw	8
		movwf	lpcnt		;送信ビット用ループカウンタに設定

txb01		rlf	sdtemp,F	;1 ビット左にシフト
		btfsc	STATUS,C
		goto	txb02

		bcf	PORTA,j1	;'0' ビット送出
		goto	txb03

txb02		bsf	PORTA,j1	;'1' ビット送出
		nop
txb03		call	wait_4ms	;4m 秒 ウェイト

		decfsz	lpcnt,F		;ループカウンタ - 1 = 0 か？
		goto	txb01		;No

		return

;==========================================================================
;	デバイス番号チェック／被試験ＩＣのデバイスチェックの結果受信
;==========================================================================

;	(from U2 ... OK: 50m 秒間,  NG: 5m 秒間 "L"パルス信号出力)

;	           OK                               NG 
;	￣￣￣￣＿＿＿＿￣￣￣￣￣ ￣ ￣ ￣￣￣￣￣＿＿￣￣￣￣￣￣

;	       ￤ 50mS ￤                         ￤5m￤

check_respons
;;		btfsc	PORTA,j7	;RA1: チェック結果応答(j7: from U2) = "L" か？
;;		goto	$ - 1		;No		      アクティブ "L"

		btfss	PORTA,j7	;RA1: チェック結果応答(j7: from U2) = "H" か？
		goto	crp01		;No

		btfss	pau_flag,bit0	;休止スイッチ有効フラグ = ON か？
		goto	check_respons	;No

		btfss	dvckflg,bit0	;被試験ＩＣのデバイスチェックフラグ(0) = ON か？
		goto	check_respons	;No

		btfss	PORTA,j0	;スイッチ入力イネーブル(j0: from U4) か？
		goto	crp05		;Yes. チェック終了
		goto	check_respons	;No

crp01		movlw	25
		call	wait_w1ms	;25m 秒 ウェイト

		bsf	resckflg,bit0	;OK: 応答信号チェックフラグ = ON
		btfsc	PORTA,j7	;RA1: 再チェック結果応答(j7: from U2) = "L" か？
		bcf	resckflg,bit0	;NG: 応答信号チェックフラグ = OFF

		btfsc	PORTA,j0	;スイッチ入力イネーブル(j0: from U4) = "L" か？
		goto	crp03		;No

		; デバイス番号チェック結果

		movlw	h'c5'		;チェック結果の先頭表示位置	;;
		call	Lcd_Cmd		;LCD へコマンドを出力		;;
		movlw	' '						;;cksw の後、すぐに setsw を
		call	Lcd_Data	;LCD へデータを１文字出力	;;押したときのために必要
		movlw	' '						;;
		call	Lcd_Data	;LCD へデータを１文字出力	;;

		bsf	updtflg,bit0	;LCD 表示更新フラグ(0) = ON
		btfss	resckflg,bit0	;応答信号チェックフラグ = ON か？
		goto	crp02		;No

		bsf	sendflg,bit1	;OK: デバイス番号送信フラグ(1) = ON
					;	(bit1: デバイス番号チェックOK = ON)
		call	dev_no_disp	;正規デバイス番号の表示
		goto	crp05

crp02		Disp_Lcd	b'11000000',none,1	;DDRAM アドレスセット

		clrf	sendflg		;NG: デバイス番号送信フラグ(0),(1)  = OFF
					;	(bit0: デバイス番号送信済み  = OFF)
		movlw	none_time	;"None!" 表示時間 (500msec x none_time = 3 sec)
		movwf	nonecnt		;"None!" LCD 表示時間カウンタに設定
		goto	crp05

none		dt	"None!",0

		; 被試験ＩＣデバイスチェック結果

crp03		bsf	dvckflg,bit1	;被試験ＩＣのデバイスチェックフラグ(1) = ON
					;	(bit1=1:デバイスチェック済み = ON)
		movlw	h'c5'		;チェック結果の先頭表示位置
		btfsc	pau_flag,bit0	;休止スイッチ有効フラグ = ON か？
		movlw	h'c4'		;Yes. チェック結果の先頭表示位置
		call	Lcd_Cmd		;LCD へコマンドを出力

		btfss	resckflg,bit0	;応答信号チェックフラグ = ON か？
		goto	crp04		;No

		movlw	'O'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	'K'
		call	Lcd_Data	;LCD へデータを１文字出力
		goto	crp05

crp04		movlw	'N'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	'G'
		call	Lcd_Data	;LCD へデータを１文字出力
		bsf	pauseflg,bit2	;休止スイッチ有効フラグ = ON のときに必要
					;ポーズ信号フラグ(2) = ON: デバイスチェックのエラー有り表示
crp05		return

;--------------------------------------------------------------------------

		; 正規デバイス番号の表示

dev_no_disp
		movlw	h'87'		;正規デバイス番号の先頭表示位置
		call	Lcd_Cmd		;LCD へコマンドを出力

		movf	digit43,W	;デバイス番号 1000 位 + 100 位 チェック
		sublw	h'90'
		btfss	STATUS,Z	;digit43 = h'90' か？
		goto	dndsp01		;No

		movf	digit21,W	;デバイス番号 10 位 + 1 位 チェック
		sublw	h'49'
		btfsc	STATUS,Z	;digit21 = h'49' か？
		goto	dndsp02		;Yes

		movf	digit21,W	;デバイス番号 10 位 + 1 位 チェック
		sublw	h'50'
		btfsc	STATUS,Z	;digit21 = h'50' か？
		goto	dndsp02		;Yes

dndsp01		movf	digit4,W	;1000 位 チェック
		sublw	4
		btfsc	STATUS,Z	;digit4 = 4 か？
		goto	dndsp02		;Yes

		; 74 シリーズ
		movlw	'7'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	h'c0'		;
		call	Lcd_Cmd		;LCD へコマンドを出力
		movlw	'4'
		goto	dndsp04

		; 40/45 シリーズ
dndsp02		movlw	'4'
		call	Lcd_Data	;LCD へデータを１文字出力
		movlw	h'c0'		;
		call	Lcd_Cmd		;LCD へコマンドを出力

		movf	digit3,W	;100 位 チェック
		sublw	5
		movlw	'5'
		btfss	STATUS,Z	;digit3 = 5 か？
		movlw	'0'		;No

		; 74/40/45 シリーズ共通
dndsp04		call	Lcd_Data	;LCD へデータを１文字出力

		movf	digit43,W	;デバイス番号 1000 位 + 100 位 チェック
		sublw	h'45'
		btfsc	STATUS,Z	;digit43 = h'45' か？
		goto	dndsp05		;Yes

		movf	digit3,W	;100 位 チェック
		btfsc	STATUS,Z	;digit3 = 0 か？
		goto	dndsp05		;Yes

		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力

dndsp05		movf	digit2,W	;10 位 
		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力

		movf	digit1,W	;1 位 
		addlw	h'30'
		call	Lcd_Data	;LCD へデータを１文字出力

		; 例外入力の表示　（1: * 補助ソケット使用、9: + ソケットアダプタ使用）
		movf	digit4,W	;1000 位 チェック
		btfsc	STATUS,Z	;digit4 = 0 か？
		goto	dndsp06		;Yes

		sublw	4
		btfsc	STATUS,Z	;digit4 = 4 か？
		goto	dndsp06		;Yes

		movlw	h'86'		;注意喚起記号の表示位置
		call	Lcd_Cmd		;LCD へコマンドを出力

		movf	digit4,W	;1000 位 チェック
		sublw	9
		movlw	'*'		;注意喚起: 補助ソケット使用
		btfsc	STATUS,Z	;digit4 = 9 か？
		movlw	'+'		;Yes. 注意喚起: ソケットアダプタ使用
		call	Lcd_Data	;LCD へデータを１文字出力

dndsp06		return

;==========================================================================
;		ウェイト・ルーチン (10 MHz)
;==========================================================================

		; 100μ秒 ウェイトルーチン
wait_100us
		movlw	60		;1
		movwf	wtcnt1		;1

w100u01		nop			;1
		decfsz	wtcnt1,F	;1,2
		goto	w100u01		;2,0	1+1+(1+1+2)*59+(1+2+0)=241
		return			;2	241+2=243
					;Total	243/10MHz*4 = 0.0000972 S = 97.2 μS

		; 1m 秒 x W ウェイトルーチン
wait_w1ms
		movwf	wtcnt3		;1
w1m01		movlw	10		;1
		movwf	wtcnt2		;1
		goto	$+1		;2
		goto	$+1		;2

w1m02		nop			;1
		call	wait_100us	;245	2+243
		decfsz	wtcnt2,F	;1,2
		goto	w1m02		;2,0	(1+245+1+2)*9+(1+245+2+0)=2489

		decfsz	wtcnt3,F	;1,2
		goto	w1m01		;2,0	(1+1+2+2+2489+1+2)*(W-1)+(1+1+2+2+2489+2+0)=2498*W-1
		return			;2	1+(2498*W-1)+2=2498*W+2
					;Total	(2498*W+2)/10MHz*4 = 0.9992*W mS + 0.8 μS

		; 4m 秒 ウェイトルーチン
wait_4ms
		movlw	4		;1
		goto	wait_w1ms	;2	1+2+(2498*4+2)=9997
					;Total	9997/10MHz*4 = 3.9988 mS = 4 mS

		; 100m 秒 ウェイトルーチン
wait_100ms
		movlw	100		;1
		goto	wait_w1ms	;2	1+2+(2498*100+2)=249805
					;Total	249805/10MHz*4 = 99.922 mS = 100 mS

		; 500m 秒 ウェイトルーチン
wait_500ms
		movlw	5		;1
		goto	w1s01		;2	1+2+1+((249807+1+2)*4+(249807+2+0)+2)=1249055
					;Total	1249055/10MHz*4 = 499.622 mS = 500 mS

		; 1 秒 ウェイトルーチン
wait_1sec
		movlw	10		;1
w1s01		movwf	wtcnt4		;1

w1s02		call	wait_100ms	;249807	2+249805
		decfsz	wtcnt4,F	;1,2
		goto	w1s02		;2,0	(249807+1+2)*9+(249807+2+0)=2498099
		return			;2	1+1+2498099+2=2498103
					;Total	2498103/10MHz*4 = 0.9992412 S = 1 S

;==========================================================================
;		割り込み処理
;==========================================================================

interrupt
		movwf	w_save		;W レジスタの保存
		movf	STATUS,W
		movwf	s_save		;STATUS レジスタの保存
		bcf	STATUS,RP0	;バンク 0
		btfss	PIR1,TMR1IF	;タイマー１オーバフロー か？
		goto	init		;No. Reset(Illegal interrupt)

		; タイマー１オーバフロー割り込み（ 2 mS 毎に割り込み ）

		bcf	PIR1,TMR1IF	;タイマー１オーバフロー解除
		movlw	high cntdat
		movwf	TMR1H		;TMR1H に設定
		movlw	low cntdat	;
		movwf	TMR1L		;TMR1L に設定

		movf	chatcnt,W
		btfss	STATUS,Z	;チャッタリング吸収カウンタ = 0 か？
		decf	chatcnt,F	;No. チャッタリング吸収カウンタ - 1 更新

		decfsz	tmoutcnt,F	;タイムアウトカウンタ - 1 = 0 か？
		goto	int01		;No

		movlw	tm_adj		;タイムアウトスキップ回数 (2msec x tm_adj)
		movwf	tmoutcnt	;タイムアウトカウンタに設定
		movlw	b'00000001'
		xorwf	blinkflg,F	;点滅フラグの更新

		movf	nonecnt,W
		btfsc	STATUS,Z	;"None!" LCD 表示時間カウンタ = 0 か？
		goto	int01		;Yes

		bsf	updtflg,bit0	;LCD 表示更新フラグ = ON
		decfsz	nonecnt,F	;"None!" LCD 表示時間カウンタ - 1 = 0 か？
		goto	int01		;No

		bsf	updtflg,bit1	;LCD 新規表示フラグ = ON

int01		movf	s_save,W
		movwf	STATUS		;STATUS レジスタの復帰
		swapf	w_save,F
		swapf	w_save,W	;W レジスタの復帰

		retfie			;割り込みからの復帰

;==========================================================================
;		EEPROM エリア
;==========================================================================

		org	h'2100'

eep_st		de	"Copyright (C) 2010-2018 by M.Yamamoto"

;==========================================================================

		end			;プログラムの終了
