;***** LogicIC_CheckerII3.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. 3.00   2018/04/30  PIC16F874Aに変更
;	bugfix:  Ver. x.xx
;
;******************************************************* PicAsm 0246 ******

;	Device: PIC16F874A	Clock: 10MHz (セラロック)

#ifdef comment

 <機能概要>
　　この簡易ロジックＩＣチェッカ II  (Logic IC Checker II)は、「各種スイッチ入力, 
　ＬＣＤ表示部」（以下、Ｕ１という。）、「各種ロジックＩＣチェック, 結果表示部」
　（以下、Ｕ２という。）および「各種ロジックＩＣチェック補助制御部」（以下、Ｕ３と
　いう。）の三部からなっている。

　　Ｕ３では、ひたすらＵ２からの拡張チェックデータである、補助制御指令入力(j2: 
　from U2) の受信を待つ。オープンコレクタや３ステートなどの拡張チェックがある場合
　に送られてくる。

　　拡張チェックデータを受信すると、Ｕ３では、そのデータをもとに指定のビットをプル
　アップ、またはプルダウン設定を行い、終わるとＵ２に補助制御完了出力(j3: to U2) を
　送信して完了を知らせる。

　　Ｕ２ではその補助制御完了(j3: from U3)を待って、被試験ＩＣの出力が正しいかどうか
　を拡張チェックデータに基づいてチェックをする。

#endif

;	PIC16F877A/PIC16F874A のピンと用途

;	 (1) MCLR:マスター・クリア入力		(40) RB7:  8 ピン入出力制御
;	 (2) RA0: 予備				(39) RB6:  7 ピン入出力制御
;	 (3) RA1: 予備		　		(38) RB5:  6 ピン入出力制御
;	 (4) RA2: 予備				(37) RB4:  5 ピン入出力制御
;	 (5) RA3: 補助制御完了出力(j3: to U3)	(36) RB3:  4 ピン入出力制御
;	 (6) RA4: 補助制御指令入力(j2: from U2)	(35) RB2:  3 ピン入出力制御
;	 (7) RA5: デバイス番号入力		(34) RB1:  2 ピン入出力制御
;　	 (8) RE0: 予備				(33) RB0:  1 ピン入出力制御
;	 (9) RE1: 予備				(32) VDD: 電源 +5V DC
;	(10) RE2: 予備				(31) VSS: 電源 GND
;	(11) VDD: 電源 +5V DC			(30) RD7: 予備
;	(12) VSS: 電源 GND			(29) RD6: 予備
;	(13) OSC1:オシレータ水晶入力		(28) RD5: 23 ピン入出力制御
;	(14) OSC2:オシレータ水晶入力		(27) RD4: 22 ピン入出力制御
;	(15) RC0:  9 ピン入出力制御		(26) RC7: 17 ピン入出力制御
;	(16) RC1: 10 ピン入出力制御		(25) RC6: 16 ピン入出力制御
;	(17) RC2: 11 ピン入出力制御		(24) RC5: 15 ピン入出力制御
;	(18) RC3: 13 ピン入出力制御		(23) RC4: 14 ピン入出力制御
;	(19) RD0: 18 ピン入出力制御		(22) RD3: 21 ピン入出力制御
;	(20) RD1: 19 ピン入出力制御		(21) RD2: 20 ピン入出力制御

;==========================================================================

	list		p=pic16f874a	;デバイス情報
	include		p16f874a.inc	;インクルードファイル
	errorlevel	-302		;Eliminate bank warning

;==========================================================================
;		コンフィギュレーションの設定
;==========================================================================

	__config _CP_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC

;==========================================================================
;		変数の定義とレジスタ割付け
;==========================================================================

		radix	dec

j2		equ	4		;RA4: 補助制御指令入力(j2: from U2)
j3		equ	3		;RA3: 補助制御完了出力(j3: to U2)
					;(注: jx, Ux は回路図中の記号に対応)

bit0		equ	0		;フラグの ON ビット
pul7		equ	7		;1:PULL-UP/0:PULL-DOWN 指定ビット

		cblock  h'20'
lpcnt					;受信ビット用ループカウンタ
rcv_flag				;拡張チェックデータ受信フラグ
ck_dat_rb				;拡張チェックデータ RB
ck_dat_rc				;拡張チェックデータ RC
ck_dat_rd				;拡張チェックデータ RD
wt1cnt					;ウェイト用ループカウンタ
wt2cnt					;ウェイト用ループカウンタ
wt3cnt					;ウェイト用ループカウンタ
		endc

		cblock	h'70'
w_save					;W レジスタの保存用（割り込み処理で使用）
s_save					;STATUS レジスタの保存用（割り込み処理で使用）
		endc

;==========================================================================
;		プログラム開始
;==========================================================================

		org	0		;リセットベクタ
		goto	init
		org	4		;割り込みベクタ
		goto	interrupt

;==========================================================================
;		初期化処理
;==========================================================================

init
		bcf	STATUS,RP1	;バンク 0
		bcf	STATUS,RP0
		clrf	ADCON0		;ADCON0 の設定, A/D 未使用

;		bcf	STATUS,RP1	;バンク 1
		bsf	STATUS,RP0
		movlw	h'06'		;ポートA, E を ディジタルモード
		movwf	ADCON1		;ADCON1 の設定
		movlw	b'00110111'	;RA5-4,2-0: 入力, RA3: 出力
		movwf	TRISA		;TRISA の設定
		movlw	b'11111111'
		movwf	TRISB		;RB7-0: 入力 の設定
		movwf	TRISC		;RC7-0: 入力 の設定
		movwf	TRISD		;RD7-0: 入力 の設定
		movwf	TRISE		;RE2-0: 入力 の設定(予備)
		movlw	h'80'		;プルアップ抵抗を使用しない
		movwf	OPTION_REG	;OPTION_REG の設定

;		bcf	STATUS,RP1	;バンク 0
		bcf	STATUS,RP0
		movlw	b'00001000'	;RA3=1: 補助制御完了出力(j3: to U2) = disable
		movwf	PORTA		;ポートA に初期値を出力
		bcf	INTCON,GIE	;GIE 全割り込み禁止

;==========================================================================
;		メイン・ルーチン
;==========================================================================

main
		call	rx_data		;チェックデータの受信
		btfsc	rcv_flag,bit0	;チェックデータを受信したか？
		call	ck_data_out	;Yes. チェックデータの出力
		goto	main

;==========================================================================
; 拡張チェックデータを「各種ロジックＩＣチェック, 結果表示部」より受信
;
; 出力:	rcv_flag = 1:                    拡張チェックデータ受信フラグ
;	ck_dat_rb, ck_dat_rc, ck_dat_rd: 拡張チェックデータ(有効)
;	rcv_flag = 0:
;	ck_dat_rb, ck_dat_rc, ck_dat_rd: 拡張チェックデータ(無効)
;==========================================================================

; スタートビット(1) + データ RD(8) + データ RC(8) + データ RB(8) + ストップビット(1)

;	         Start                                  　　　　 Stop 
;	￣￣￣￣＿＿＿＿￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣ ￣￣￣￣￣￣

;	       ￤2m￤  4m  ↑  4m  ↑     ...     ↑  4m  ↑  4m  ￤
;	                   01      02     ...     23      24

;	           ￤            ( 8 x 3 = 24 )           ￤

rx_data
		bcf	rcv_flag,bit0	;デバイス番号受信フラグをクリア
		btfsc	PORTA,j2	;スタートビット受信か？
		goto	rxd02		;No

		call	wait_2ms	;2m 秒 ウェイト
		movlw	8 * 3		;8 ビット x 3 バイト
		movwf	lpcnt		;受信ビット用ループカウンタに設定

rxd01		call	wait_4ms	;4m 秒 ウェイト
		rlf	ck_dat_rb,F	;全ビット左シフト
		rlf	ck_dat_rc,F	;キャリー経由全ビット左シフト
		rlf	ck_dat_rd,F	;　　〃
		bsf	ck_dat_rb,0	;最下位ビットに 1 をセット
		btfss	PORTA,j2	;入力ビット = 1 か？
		bcf	ck_dat_rb,0	;Np. 最下位ビットに 0 を再セット
		decfsz	lpcnt,F		;ループカウンタ - 1 = 0 か？
		goto	rxd01		;No

		call	wait_4ms	;ストップビットをスキップ
		bsf	rcv_flag,bit0	;デバイス番号受信フラグを設定

rxd02		return

;==========================================================================
;		チェックデータの各ポート出力
;==========================================================================

ck_data_out
		; Ｉ／Ｏポートの設定

		movf	ck_dat_rb,W	;ピンのＩ／Ｏ割当 RB を
		xorlw	h'ff'		;反転して
		bsf	STATUS,RP0	;バンク 1
		movwf	TRISB		;ポート B に設定
		bcf	STATUS,RP0	;バンク 0
		movf	ck_dat_rc,W	;ピンのＩ／Ｏ割当 RC を
		xorlw	h'ff'		;反転して
		bsf	STATUS,RP0	;バンク 1
		movwf	TRISC		;ポート C に設定
		bcf	STATUS,RP0	;バンク 0
		movf	ck_dat_rd,W	;ピンのＩ／Ｏ割当 RD を
		andlw	h'7f'		;PULL-UP/DOWN 指定ビットを削除
		xorlw	h'ff'		;反転して
		bsf	STATUS,RP0	;バンク 1
		movwf	TRISD		;ポート D に設定
		bcf	STATUS,RP0	;バンク 0
		call	wait_100us	;100μ秒 ウェイト

		; 被試験ＩＣへのチェックデータ出力

		clrf	PORTB		;ポートB をクリア	( PULL-DOWN 指定 )
		clrf	PORTC		;ポートC をクリア
		clrf	PORTD		;ポートD をクリア

		btfss	ck_dat_rd,pul7	;1:PULL-UP/0:PULL-DOWN 指定ビット = ON か？
		goto	dvck01		;No

		movf	ck_dat_rb,W	;チェックデータ RB を	( PULL-UP 指定 )
		movwf	PORTB		;ポートB に出力
		movf	ck_dat_rc,W	;チェックデータ RC を
		movwf	PORTC		;ポートC に出力
		movf	ck_dat_rd,W	;チェックデータ RD を
		andlw	h'7f'		;PULL-UP/DOWN 指定ビットを削除
		movwf	PORTD		;ポートD に出力

dvck01		call	wait_100us	;100μ秒 ウェイト
		bcf	PORTA,j3	;RA3=0: 補助制御完了出力(j3: to U2) = enable
		call	wait_4ms	;4m 秒 ウェイト
		bsf	PORTA,j3	;RA3=1: 補助制御完了出力(j3: to U2) = disable

		; Ｉ／Ｏポートの再設定

		bsf	STATUS,RP0	;バンク 1
		movlw	b'11111111'
		movwf	TRISB		;RB7-0: 入力 の設定
		movwf	TRISC		;RC7-0: 入力 の設定
		movwf	TRISD		;RD7-0: 入力 の設定
		bcf	STATUS,RP0	;バンク 0
		return

;==========================================================================
;		ウェイト・ルーチン (10 MHz)
;==========================================================================

		; 10μ秒 ウェイトルーチン

wait_10us
		movlw	5		;1
w10u01		movwf	wt1cnt		;1
		nop			;1
		nop			;1
w10u02		nop			;1
		decfsz	wt1cnt,F	;1,2
		goto	w10u02		;2,0	1+1+1+1+(1+1+2)*4+(1+2+0)=23
		return			;2	23+2=25
					;Total	25/10MHz*4 = 0.00001 S = 10 μS

		; 100μ秒 ウェイトルーチン

wait_100us
		movlw	60		;1
		goto	w10u01		;2	1+2+(1+1+1+(1+1+2)*59+(1+2+0)+2)=247
					;Total	247/10MHz*4 = 0.0000988 S = 98.8 μS
;		movlw	59		;1
;		goto	w10u01		;2	1+2+(1+1+1+(1+1+2)*58+(1+2+0)+2)=243
;					;Total	243/10MHz*4 = 0.0000972 S = 97.2 μS

		; 1m 秒 x W ウェイトルーチン

wait_w1ms
		movwf	wt3cnt		;1
w1m01		movlw	10		;1
		movwf	wt2cnt		;1
		goto	$+1		;2
		goto	$+1		;2
w1m02		nop			;1
		call	wait_100us	;245	2+243
		decfsz	wt2cnt,F	;1,2
		goto	w1m02		;2,0	(1+245+1+2)*9+(1+245+2+0)=2489

		decfsz	wt3cnt,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 = 999.2*W + 0.8 μS

		; 2m 秒 ウェイトルーチン

wait_2ms
		movlw	2		;
		goto	wait_w1ms	;	1+2+(2498*2+2)=5001
					;Total	5001/10MHz*4 = 2000.4 μS = 2 mS

		; 4m 秒 ウェイトルーチン

wait_4ms
		movlw	4		;
		goto	wait_w1ms	;	1+2+(2498*4+2)=9997
					;Total	9997/10MHz*4 = 3998.8 μS = 4 mS

		; 100m 秒 ウェイトルーチン

wait_100ms
		movlw	100		;
		goto	wait_w1ms	;	1+2+(2498*100+2)=249805
					;Total	249805/10MHz*4 = 99922 μS = 99.922 mS

;==========================================================================
;		タイマー割り込み処理（未使用）
;==========================================================================

interrupt
		; レジスタの保存

		movwf	w_save		;W レジスタの保存
		movf	STATUS,W
		movwf	s_save		;STATUS レジスタの保存

		bcf	STATUS,RP0	;バンク 0
		bcf	STATUS,RP1
		btfss	INTCON,T0IF	;タイマ０オーバフロー か？
		goto	init		;No. Reset(Illegal interrupt)

		; タイムアウト割り込み処理

		bcf	INTCON,T0IF	;タイマオーバフロー解除
		clrf	TMR0		;TMR0 = 0 (256カウント) の設定
;		decfsz	tmoutcnt,F	;タイムアウトカウンタ - 1 = 0 か？
		goto	int01		;No



		; レジスタの復帰

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			;プログラムの終了
	