;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			ＰＩＣ１６Ｆ６４８Ａ　10MHZ　汎用８桁７セグＬＥＤ表示基板
;
;			シリアルデータ入力表示プログラム(ハンドシェイク版)
;
;			データ入力はRA5入力
;			受信データは5バイト(40ビット)
;			カウントデータは32ビット
;			制御フラグに対応
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


		LIST	P=PIC16F648A
		INCLUDE	P16F648A.inc
		
;	
;		
;CONFIGURATION WORD(ADDRESS:2007H)
;					設定
;bit13		CP		1	プログラムメモリプロテクション　0セット　
;						1=無効,0=有効
;bit12-9	Unimplemented
;bit8		CPD		1	データメモリプロテクション　0セット
;						1=無効,0=有効
;bit7		LPV		0	低電圧プログラミング設定
;						1=有効,0=無効
;bit6		BODEN	0	ブラウンアウト設定
;						1=有効,0=無効
;bit5		MCLRE	0	RA5/MCLRピン選択ビット
;						1=MCLR有効,0=RA5有効(Digital input)
;bit3		PWRTE	0	power_up timer　
;						1=無効,0=有効
;bit2		WDTE	0	Watchdog Timer
;						1=有効,0=無効
;bit4,1-0	FOSC	010	発振器選択ビット
;						111=RC:RA7でRC発振、RA6はCLKOUT、I/O不可
;						110=RCIO:　〃　RA6I/O可
;						101=INTOSC:内部発振、RA6はCLKOUT、RA7I/O可
;						100=INTOSC:内部発振、RA6-7I/O可
;						011=EC:RA7外部クロック入力、RA6I/O可
;						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  1  0  0  0  0  1  0  0  0  0  0  0  1  0
;
;

		__CONFIG	B'0010000100000010'

	

;		ワークエリア定義
;
;		使用していないのもあります
;

hex0		equ			020h		;カウンタからの32ビット16進バイナリデータ
hex1		equ			021h
hex2		equ			022h
hex3		equ			023h
digit12		equ			024h		;BCDデータワーク1,2桁
digit34		equ			025h		;BCDデータワーク3,4桁
digit56		equ			026h		;BCDデータワーク5,6桁
digit78		equ			027h		;BCDデータワーク7,8桁
digit9A		equ			028h		;BCDデータワーク9,10桁
colum		equ			029h		;現在の桁位置
cnt0		equ			02ah		;時間待ち用ワーク
cnt1		equ			02bh
cnt2		equ			02ch
cnt3		equ			02dh
tmp0		equ			02eh		;雑用ワーク
tmp1		equ			02fh
bcdw0		equ			030h		;BCD補正処理ワーク
bcdw1		equ			031h
cary1		equ			032h
cary2		equ			033h
cary3		equ			034h
shift		equ			035h		;シリアルデータ受信カウンタ
work1		equ			036h
work2		equ			037h
bsyc0		equ			038h
bsyc1		equ			039h
hexw0		equ			03ah		;16進バイナリ保存用
hexw1		equ			03bh
hexw2		equ			03ch
hexw3		equ			03dh
flg			equ			03eh		;カウンタよりの制御フラグ
adtw0		equ			03fh		;ドット点燈処理ワーク
wtmp		equ			040h		;ワークレジスタ退避用
stmp		equ			041h		;ステータスレジスタ退避用
hexb0		equ			042h		;カウントデータ受信バッファ
hexb1		equ			043h
hexb2		equ			044h
hexb3		equ			045h
flgb		equ			046h		;制御フラグ受信バッファ
bitc		equ			047h		;受信ビットカウンタ
icnt0		equ			048h		;割込み内ウエイト用
icnt1		equ			049h		;割込み内ウエイト用
blk			equ			04ah		;ゼロブランキング制御ワーク
;

			ORG			0h
			goto		init
			ORG			04h
			goto		init

			org			05h
			
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			ＢＣＤからLEDセグメントデータへの変換
;
;	注意			このルーチンのアドレス範囲の設定が必要
;				PCLATHにその上位アドレスを入れること
;	入力			Wレジスタに表示16進バイナリデータを入れてコール
;				ドット制御データは無い
;	出力			Wレジスタに8ビットポート出力データを入れてリターン
;				必要に応じてblkフラグリセット
;				blkフラグは7セグ表示1サーチのみ有効
;	blk			ビット0=0	ゼロブランキングしない
;				ビット0=1	ゼロブランキングする
;				ビット1=0	停止中
;				ビット1=1	動作中
;
;	ELD432 anodo common	PORT=0　then　seg=on
;
;		a				RB1=a	RB5=e
;	f		b			RB2=b	RB6=f
;		g				RB3=c	RB7=g
;	e		c			RB4=d	RA4=Dp
;		d		dp		
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

get_7seg
			btfss		blk,0		;ブランク制御フラグチェック
			goto		g7s0		;制御要求なし
			andlw		0fh			;データチェック
			btfsc		STATUS,Z	;
			goto		g7s1
			bcf			blk,0		;一度ゼロ以外のデータが来るとフラグリセット
			bcf			blk,1
			
g7s0		andlw		0fh			;下位4ビット取り出し
			addwf		PCL,F
			retlw		B'10000000'	;Code 0 abcdef
			retlw		B'11110010'	;Code 1 bc
			retlw		B'01001000'	;Code 2 abdeg
			retlw		B'01100000'	;Code 3 abcdg
			retlw		B'00110010'	;Code 4 bcfg
			retlw		B'00100100'	;Code 5 acdfg
			retlw		B'00000100'	;Code 6 acdefg
			retlw		B'11110000'	;Code 7 abc
			retlw		B'00000000'	;Code 8 abcdefg
			retlw		B'00110000'	;Code 9 abcfg

			retlw		B'00010000'	;Code A abcefg
			retlw		B'00000110'	;Code B cdefg
			retlw		B'10001100'	;Code C adef
			retlw		B'01000010'	;Code D bcdeg
			retlw		B'00001100'	;Code E adefg
			retlw		B'00011100'	;Code F aefg

g7s1		bsf			blk,1		;ゼロブランキング動作中
			movf		colum,W
			iorlw		0h
			btfss		STATUS,Z	;桁位置が0かどうかチェック
			retlw		0feh		;ブランク返し
			retlw		B'10000000'	;0表示返し



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		初期設定
;
;			PIC16F648A　イニシャライズ			
;
;		CMCON_REG
;			bit7	C2OUT	コンパレータ2出力ビット
;			bit6	C1OUT	コンパレータ１出力ビット
;			bit5	C2INV	コンパレータ2出力反転ビット
;			bit4	C1INV	コンパレータ１出力反転ビット
;			bit3	CIS		コンパレータ入力スイッチビット
;			bit2-0	CM		コンパレータモード	111	Off
;										入力はデジタル
;										他モードは使用しない
;
;		TRISA_REG	1=input mode,0=output mode
;			bit7=0	RA7	I/O	設定条件あり、コンフィグレーションワード参照
;			bit6=0	RA6　I/O	設定条件あり、　〃
;			bit5=1	RA5	Inputのみ
;			bit4=0	RA4	I/O
;			bit3=0	RA3	I/O
;			bit2=0	RA2	I/O
;			bit1=0	RA1	I/O
;			bit0=0	RA0	I/O
;
;		TRISB_REG	1=input mode,0=output mode
;			bit7=0	RB7	I/O
;			bit6=0	RB6	I/O
;			bit5=0	RB5	I/O
;			bit4=0	RB4	I/O
;			bit3=0	RB3	I/O
;			bit2=0	RB2	I/O
;			bit1=0	RB1	I/O
;			bit0=0	RB0	I/O	外部割込み入力ピン
;
;		OPTION_REG
;			bit7=0	RBPU	POTRBプルアップON
;							1=diabled,0=inabled
;			bit6=0	INTEGE	RB0_INT割り込み信号エッジ
;							1=↑,0=↓
;			bit5=0	T0CS	TMR0クロックは外部
;							1=外部入力RA4,0=内部
;			bit4=0	T0SE	TMR0カウントエッジ↑
;							1=↓,0=↑,
;			bit3=1	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レジスタ
;			bit7=1	GIE		全割込制御
;							1許可、0禁止
;			bit6=0	PEIE	周辺割込制御
;							1許可、0禁止
;			bit5=0	T0IE	タイマ0割込許可制御
;							1許可、0禁止
;			bit4=1	INTE	RB0外部割込許可制御
;							1許可、0禁止
;			bit3=0	RBIE	RBポート状態変化割込許可制御
;							1許可、0禁止	
;			bit2=0	T0IF	タイマ0オーバーフロー割込みフラグ
;							1オーバーフロー、0オーバーフローなし(#1)
;			bit1=0	INTF	RB0外部割込みフラグ(#1)
;							1割込み発生、0割込み発生なし
;			bit0=0	RBIF	RB4-7ポート状態変化割込フラグ(#1)
;							1割込発生、0割込無
;
;							#1)ソフトウエアでリセット必要
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;
;		初期設定
;

init
			clrf		INTCON		;割り込み禁止
			movlw		07h
			movwf		CMCON		;アナログポート→デジタル
			bsf			STATUS,RP0	;バンク１に切替
			bcf			STATUS,RP1
			movlw		020h		;00100000b
			movwf		TRISA		;RA0-RA4出力、RA5入力モード
			clrf    	TRISB		;RBポート全出力モード
			bcf			STATUS,RP0	;バンク０に切替
			call		wait100u
			bcf			PORTB,0		;RB0=0(RX_BUSY)

;			goto		main_dbg
;			goto		check

;
;		メインプログラム
;

			
main
			call		bcd
			call		setmode
			call		disp_all
			goto		main


;
;		デバッグモード
;
main_dbg
dbg0		call		disp_8hn
			goto		main_dbg

;
;		ハードウエアチェックモード
;
;		全LEDをおよびセグメントを下桁から順に点燈
;		使用ワークエリア		tmp0
;

check		bcf			INTCON,GIE	;割込み禁止
			movlw		0h
			movwf		colum		;桁位置ワークへリセットデータ
			movlw		08h
			movwf		tmp0		;繰り返しカウンタ値
			movlw		0feh
			movwf		PORTB		;LED消灯
			bsf			PORTA,3		;ドット消灯
			nop
			bsf			PORTA,4		;O.F LED
			call		wait500m
			clrf		digit12
			clrf		digit34
			clrf		digit56
			clrf		digit78
init0
			movf		PORTA,W	    ;xxxxx000b 11111000b=F8H
			andlw		B'11111000'
			addwf		colum,W		;一桁ずつ点燈
			movwf		PORTA		;桁位置出力
			movlw		0			;
			movwf		PORTB		;全セグ点燈500ms
			bcf			PORTA,3
			nop
			bcf			PORTA,4		
			call		wait500m
			movlw		0feh		;
			movwf		PORTB		;全セグ消灯
			bsf			PORTA,3
			nop
			bsf			PORTA,4		
			incf		colum,f
			decfsz		tmp0,f
			goto		init0
			goto		check



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			シリアルデータ、ハンドシェイク受信サブルーチン(時間短縮版)
;
;		出力バッファ		hex0	16進バイナリ32ビット
;					hex1
;					hex2
;					hex3
;					flg	制御フラグ
;		ステータス		W=0	受信成功
;					W=1	受信失敗
;					W=2　送信未準備
;
;
;		データ線	DATA	RB0		1bit width = 50us
;
;		使用ワーク	bsyc0,shift
;
;	TX format
;
;	通常(H)→準備OK(L)待機→　スタートビット(L)→データビット→ストップビット(H)→通常(H)
;
;						50us		各50us	50us
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


rxs_data
;
;		受信チェック
;
;		RA5ポートDATA線兼TX線(Lにて送信準備OK）
;		RB0ポートRX線制御
;
		btfss		PORTA,5			;TX 受信チェック
		goto		rsst
		retlw		01h				;送信未準備
		
;
;		受信可能ステータス送出
;
;		RB0	RX送出、アクティブH
;		RA5	DATA受信
;
rsst	movlw		028h			;40ビット分
		movwf		shift			;シフトカウンタ
		bsf			PORTB,0			;RX_ON送出、受信準備OK
		call		wait25u
		btfss		PORTA,5			;スタートビット(0)確認
		goto		rsloop			;データ受信開始
		call		wait25u
		bcf			PORTB,0			;RX_OFF　送信
		retlw		01h				;受信失敗
		

;
;		40bitシリアルデータ受信開始
;
;		１ループに付き、50us間隔でデータ取込
;

rsloop
		call		d10u
		call		d10u
		call		d10u
		call		d10u
rslp0	rlf			flg,F			;
		rlf			hex0,F			;全ビット左シフト
		rlf			hex1,F			;
		rlf			hex2,F
		rlf			hex3,F			;
		bcf			flg,0			;最下位に0をセット
		btfsc		PORTA,5			;入力データを取得
		bsf			flg,0			;最下位に1にセット
		nop
		movlw		04h				;時間調整
		movwf		bsyc0			;2+3*3+2=13cycles
rslp1	decfsz		bsyc0,F
		goto		rslp1

		decfsz		shift,F			;40ビット受信完了か
		GOTO		rsloop			;40+(9+3+13)*0.4=50usec

		call		wait50u			;
		btfss		PORTA,5			;ストップビット確認
		goto		rslp2
		goto		rslp3
rslp2	call		wait50u
		bcf			PORTB,0			;RX OFF
		
		bcf			PORTA,4			;error
		call		wait100m
		bsf			PORTA,4
		
		retlw		03h				;受信失敗

rslp3	call		wait50u
		bcf			PORTB,0			;RX OFF
		retlw		0h				;受信完了





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		４バイトバイナリの８桁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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			動作モードセット設定(非割込み用)
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

setmode
			movf		flg,W
			andlw		07h
			
			iorlw		0h
			btfsc		STATUS,Z
			movlw		07h
			movwf		colum

			clrf		blk
			btfss		flg,3		;ゼロブランキング制御フラグ
			goto		stmd0
			movlw		01h
			movwf		blk

stmd0		btfss		flg,7		;オーバーフローLED制御
			goto		stmd1
			bcf			PORTA,4		;LED ON
			return

stmd1		bsf			PORTA,4		;LED OFF
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			現在位置でドットを表示するか否かの判定ルーチン
;
;		入力	flg		
;			colum	現在の桁位置
;
;		出力	RA3		ドット点燈制御
;
;		flg
;			ドット表示位置		flg=x111xxxx
;							bit4=1	2,5桁点燈
;							bit5=1	3,6桁点燈
;							bit6=1	4,7桁点燈
;			オーバーフロー		flg=1xxxxxxx
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

addot
			btfsc		blk,1
			goto		adt6		;ゼロブランキング動作中

			;2,5桁点燈指令チェック

			btfss		flg,4		;2,5点燈指令か？
			goto		adt2		;違うので次ビットチェック
			;2桁目点燈処理
			movf		colum,W		;colum=1の時2桁目
			sublw		01h			;現在2桁目か？
			btfss		STATUS,Z
			goto		adt1		;違うので5桁目へGO
			bcf			PORTA,3		;2桁目ドット点燈
			return
adt1		;5桁目点燈処理
			movf		colum,W		;
			sublw		04h			;現在5桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bcf			PORTA,3		;5桁目ドット点燈
			return

adt2		;3,6桁点燈指令チェック

			btfss		flg,5		;3,6点燈指令か？
			goto		adt4		;違うので次ビットチェック
			;3桁目点燈処理
			movf		colum,W		;
			sublw		02h			;現在3桁目か？
			btfss		STATUS,Z
			goto		adt3		;違うので6桁目へGO
			bcf			PORTA,3		;3桁目ドット点燈
			return
adt3		;6桁目点燈処理
			movf		colum,W		;
			sublw		05h			;現在6桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bcf			PORTA,3		;6桁目ドット点燈
			return

adt4		;4,7桁点燈指令チェック			
			btfss		flg,6		;4,7点燈指令か？
			goto		adt6		;違うので終了

			;4桁点燈処理
			movf		colum,W		;
			sublw		03h			;現在4桁目か？
			btfss		STATUS,Z
			goto		adt5		;違うので7桁目へGO
			bcf			PORTA,3		;4桁目ドット点燈
			return
			
adt5		;7桁目点燈処理
			movf		colum,W		;
			sublw		06h			;現在7桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bcf			PORTA,3		;7桁目ドット点燈
			return

adt6		;消灯リターン
			bsf			PORTA,3
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10進8桁LED表示出力サブルーチン　
;　
;		入力		BCD4バイト8桁分	digit12,34,56,78
;							digit9Aは無視される
;				colum	桁位置データ 0-7
;				PORTA0-2：桁制御
;				PORTA3  :ドット制御
;				PORTB1-7：セグメント制御
;		使用ワーク	colum,tmp0,tmp1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

disp_all		
			;指定桁目から表示開始
			movf		digit78,W	;7,8桁目BCD表示データ
			call		disp2c
			iorlw		0h
			btfss		STATUS,Z
			return
			
			movf		digit56,W	;5,6
			call		disp2c
			iorlw		0h
			btfss		STATUS,Z
			return

			movf		digit34,W	;3,4
			call		disp2c
			iorlw		0h
			btfss		STATUS,Z
			return

			movf		digit12,W	;1,2
			call		disp2c			
			return

;
;			LED2桁表示サブルーチン
;
;		入力　wレジスタに表示データ１バイト２桁分
;		columに表示桁位置
;		出力　columに次の表示桁位置セット（上位桁から下位桁に移行する）
;

disp2c		
			movwf		tmp0		;表示データ保存
			swapf		tmp0,W		;上位下位入れ替え
			andlw		0fh			;上位取り出し
			call		get_7seg	;セグメントデータに変換
			movwf		PORTB		;ポートBへ出力
			call		addot		;ドット表示チェック
			
			movf		PORTA,W		;ポート現在情報
			andlw		0f8h		;bit3-7保存
			iorwf		colum,W		;桁位置合成
			movwf		PORTA		;桁位置出力

			decf		colum,F		;次の桁へシフト
			call		wait2m		;Wait 2msec
			movlw		0feh
			movwf		PORTB		;桁表示クリア
			bsf			PORTA,3		;ドットクリア

			movf		tmp0,W		;下位取り出し
			andlw		0fh			;
			call		get_7seg	;セグメントへ変換
			movwf		PORTB		;ポートBへ出力
			call		addot		;ドット表示チェック

			movf		PORTA,W		;ポート現在情報
			andlw		0f8h		;bit3-7保存
			iorwf		colum,W		;桁位置合成
			movwf		PORTA		;桁位置出力
			
			movf		colum,W
			iorlw		0h
			btfsc		STATUS,Z
			goto		disp21
			
			decf		colum,F		;次の桁へシフト
			call		wait2m
			movlw		0feh
			movwf		PORTB		;桁表示クリア
			bsf			PORTA,3		;ドットクリア
			retlw		0h			;続き有り

disp21		;表示終了
			call		rxs_data	;DATA受信
			iorlw		0h
			btfss		STATUS,Z
			call		wait2m
			movlw		0feh
			movwf		PORTB		;桁表示クリア
			bsf			PORTA,3		;ドットクリア
			retlw		01h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			１６進8桁LED表示出力サブルーチン　(ドット無)
;　
;		入力		16進バイナリ4バイト8桁分　hex0-hex3
;				PORTA0-2：桁制御
;				PORTB0-7：セグメント制御
;		使用ワーク	colum,tmp0,tmp1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

disp_8hn
			call		setmode			
			movlw		080h
			movwf		shift
			
ds8h0		movlw		07h
			movwf		colum		;
			movf		hex3,W		;7,8桁目16進表示データ
			call		disp2c
			movf		hex2,W		;5,6桁目16進表示データ
			call		disp2c
			movf		hex1,W		;3,4
			call		disp2c
			movf		hex0,W		;1,2
			call		disp2c		
			decfsz		shift,F
			goto		ds8h0
			
			movlw		080h
			movwf		shift
			
ds8h1		movlw		05h
			movwf		colum
			movlw		0fdh
			call		disp2c
			movlw		0h
			call		disp2c
			movf		flg,W
			call		disp2c
			decfsz		shift,F
			goto		ds8h1
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			遅延時間サブルーチン
;
;		clock = 10MHz(0.1usec)
;		use work reg = cnt0,cnt1,cnt2,cnt3
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wait100u							;呼び出しも含めて、100usec
									;call is 2cycles
			movlw		08h			;1
			movwf		cnt2		;1
w1u			nop						;
			nop						;
			call		d10u		;10*8=80usec(ここだけ命令ステップを数えない）
			decfsz		cnt2,F		;5*8+4=44cycles
			goto		w1u
			return					;2+44+4=50cycles=20usec

wait50u								;呼び出しも含めて、50usec
									;call is 2cycles
			movlw		04h			;1
			movwf		cnt2		;1
w05u		nop						;
			call		d10u		;10*4=40usec(ここだけ命令ステップを数えない）
			decfsz		cnt2,F		;4*4+3=19cycles
			goto		w05u
			return					;2+19+4=25cycles=10usec

wait25u
			call		d10u
			call		d10u
			
			movlw		02h			;1
			movwf		cnt2		;1
w02u		decfsz		cnt2,F		;2+3+2+1=8cycles
			goto		w02u
			return					;2+8+2=12cycles=4.8usec

wait2m
			movlw		02h
			movwf		cnt2
w2m			call		d1m
			decfsz		cnt2,F
			goto		w2m
			return

wait5m								; 5msec delay
			movlw		05h
			movwf		cnt2
w5m			call		d1m
			decfsz		cnt2,F
			goto		w5m
			return

wait10m								; 10msec delay
			movlw		d'10'
			movwf		cnt2
w10m		call		d1m
			decfsz		cnt2,F
			goto		w10m
			return

wait20m								; 20msec delay
			movlw		d'20'
			movwf		cnt2
w20m		call		d1m
			decfsz		cnt2,F
			goto		w20m
			return

wait50m								; 50msec delay
			movlw		d'50'
			movwf		cnt2
w50m		call		d1m
			decfsz		cnt2,F
			goto		w50m
			return

wait100m							; 100msec delay
			movlw		d'100'
			movwf		cnt2
w100m		call		d1m
			decfsz		cnt2,F
			goto		w100m
			return

wait500m							; 500msec delay
			movlw		05h
			movwf		cnt3
w500m		call		wait100m
			decfsz		cnt3,F
			goto		w500m
			return

wait1s								; 1sec delay
			movlw		d'10'
			movwf		cnt3
w1s			call		wait100m
			decfsz		cnt3,F
			goto		w1s
			return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			1msec Base delay 
;
;		clock = 10MHz(0.1usec)
;		1cycle = 0.4usec
;		1msec = 0.4usec * 2500cycles
;
;		# goto and call and return - 2cycles
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d1m
			movlw		02h
			movwf		cnt0		;loop0 2times
d1m0		movlw		d'249'		;
			movwf		cnt1		;loop1 249times

d1m1		nop						;5cycles*cnt1
			nop						;5*249=1245
			decfsz		cnt1,F		;
			goto		d1m1		;

			decfsz		cnt0,F		;(d1m1-1+3)*cnt0
			goto		d1m0		;(1245-1+5)*2=2498cycles
			return					;other=3cycles
									;Total 2501*0.4usec=1msec

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10usec Base delay
;			呼び出しも含めて、10usecとなる。
;
;		clock = 10MHZ(0.1usec)
;		1cycle = 0.4usec
;		10usec = 0.4usec * 25cycles
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

									;"call" inst = 2cycles
d10u
			movlw		05h			;1
			movwf		cnt0		;1
d10u0		nop						;4*4+3=19
			decfsz		cnt0,F		;
			goto		d10u0		;
			return					;2+1+1+19+2=25cycles
;
			END
			
