;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			ＰＩＣ１６Ｆ６４８Ａ　　実験用８桁７セグＬＥＤ基板
;
;			シリアルデータ入力表示プログラム　その３
;
;			7seg_test2（その２）との相違点
;			受信データは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	1	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		;ドット点燈処理ワーク
;

			ORG			0h
			goto		init
			ORG			04h
			goto		init

			org			05h
			
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			ＢＣＤからLEDセグメントへの変換　Ver2
;
;	注意			このルーチンのアドレス範囲の設定が必要
;				PCLATHにその上位アドレスを入れること
;	入力			Wレジスタに表示16進バイナリデータを入れてコール
;				ドットも表示させる時は、ビット4=1にする
;	出力			Wレジスタに8ビットポート出力データを入れてリターン
;	使用ワーク		tmp1
;	ELD512 anodo common	PORT=0　then　seg=on
;
;		a				RB0=a	RB4=e
;	f		b			RB1=b	RB5=f
;		g				RB2=c	RB6=g
;	e		c			RB3=d	RB7=Dp
;		d		dp		
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

get_7seg
			andlw		01fh		;下位5ビット取り出し
			addwf		PCL,F
			retlw		B'11000000'	;Code 0 abcdef
			retlw		B'11111001'	;Code 1 bc
			retlw		B'10100100'	;Code 2 abdeg
			retlw		B'10110000'	;Code 3 abcdg
			retlw		B'10011001'	;Code 4 bcfg
			retlw		B'10010010'	;Code 5 acdfg
			retlw		B'10000010'	;Code 6 cdefg
			retlw		B'11111000'	;Code 7 abc
			retlw		B'10000000'	;Code 8 abcdefg
			retlw		B'10011000'	;Code 9 abcfg

			retlw		B'10001000'	;Code A abcefg
			retlw		B'10000011'	;Code B cdefg
			retlw		B'11000110'	;Code C adef
			retlw		B'10100001'	;Code D bcdeg
			retlw		B'10000110'	;Code E adefg
			retlw		B'10001110'	;Code F aefg

			retlw		B'01000000'	;Code 0. abcdef
			retlw		B'01111001'	;Code 1. bc
			retlw		B'00100100'	;Code 2. abdeg
			retlw		B'00110000'	;Code 3. abcdg
			retlw		B'00011001'	;Code 4. bcfg
			retlw		B'00010010'	;Code 5. acdfg
			retlw		B'00000010'	;Code 6. cdefg
			retlw		B'01111000'	;Code 7. abc
			retlw		B'00000000'	;Code 8. abcdefg
			retlw		B'00011000'	;Code 9. abcfg

			retlw		B'00001000'	;Code A. abcefg
			retlw		B'00000011'	;Code B. cdefg
			retlw		B'01000110'	;Code C. adef
			retlw		B'00100001'	;Code D. bcdeg
			retlw		B'00000110'	;Code E. adefg
			retlw		B'00001110'	;Code F. aefg


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		初期設定
;
;			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=1	RBPU	POTRBプルアップOFF
;							1=diabled,0=inabled
;			bit6=1	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	GIE		全割込制御
;						1許可、0禁止
;		bit6	PEIE	周辺割込制御
;						1許可、0禁止
;		bit5	T0IE	タイマ0割込許可制御
;						1許可、0禁止
;		bit4	INTE	RB0外部割込許可制御
;						1許可、0禁止
;		bit3	RBIE	RBポート状態変化割込許可制御
;						1許可、0禁止	
;		bit2	T0IF	タイマ0オーバーフロー割込みフラグ
;						1オーバーフロー、0オーバーフローなし(#1)
;		bit1	INTF	RB0外部割込みフラグ(#1)
;						1割込み発生、0割込み発生なし
;		bit0	RBIF	RB4-7ポート状態変化割込フラグ(#1)
;						1割込発生、0割込無
;
;		#1)ソフトウエアでリセット必要
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




init
			movlw		07h
			movwf		CMCON		;アナログポート→デジタル
			bsf			STATUS,RP0	;バンク１に切替
			bcf			STATUS,RP1
			movlw		030h		;00110000b
			movwf		TRISA		;RA0-RA3出力、RA4-RA5入力モード
			clrf    	TRISB		;RBポート全出力モード
			bcf			STATUS,RP0	;バンク０に切替
			call		wait100u
			bcf			PORTA,3		;RA3(RX)=0
;			goto		main_dbg



			

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		メインプログラム
;
;		4バイト16進数をシリアル受信、それを１０進８桁に変換表示
;
;
;		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


main
			call		rx_data
			call		bcd
			call		setmode
			call		disp_all
mlp0
			goto		main



;
;		デバッグモード
;
main_dbg
			movlw		0ah
			movwf		cary1
			call		rx_data
dbg0		call		disp_8hn
			decfsz		cary1,F
			goto		dbg0
			goto		main_dbg



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			シリアルデータ受信サブルーチン
;
;		出力			hex0	16進バイナリ24ビット
;					hex1
;					hex2
;					hex3
;					flg		制御フラグ
;		ステータス		W=0	受信成功
;					W=1	受信失敗
;					W=2　送信未準備
;
;
;		データ線	DATA	RA4		1bit width = 100us
;		制御線	RX（送信）	RA3	=0	受信不可
;						RA3	=1	受信可
;				TX（受信）	RA5 =0	送信不可
;						RA5 =1	送信可
;
;		使用ワーク	bsyc0
;
;	TX format
;
;	RX_検出	→	スタートビットL	→	データビット		→	ストップビットH(この後そのまま放置)
;
;			0us	100us		0us	100us		0us	100us
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

rx_data
;
;		送信ステータスチェック
;
		call		wait50u
		btfss		PORTA,5			;TX 受信チェック
		goto		rxer0			;not ready
		call		wait50u
		btfsc		PORTA,5			;TX check
		goto		rstat			;送信可
rxer0	call		wait50u			;送信未準備
		retlw		02h
		
;
;		受信可能ステータス送出
;
;		RA3	RX送出
;		RA4	DATA受信
;
rstat	movlw		028h			;40ビット分
		movwf		shift			;シフトカウンタ
		bsf			PORTA,3			;RX_ON送出、受信準備OK
		call		wait50u
		btfss		PORTA,4			;スタートビット(0)確認
		goto		rloop			;データ受信開始
		call		wait50u
		bcf			PORTA,3			;RX_OFF　送信
		retlw		01h				;受信失敗
		

;
;		40bitシリアルデータ受信開始
;
;		１ループに付き、100us間隔でデータ取込
;

rloop
		call		wait50u			;90us delay
		call		d10u
		call		d10u
		call		d10u
		call		d10u
rlp0	rlf			flg,F			;
		rlf			hex0,F			;全ビット左シフト
		rlf			hex1,F			;
		rlf			hex2,F
		rlf			hex3,F			;
		bcf			flg,0			;最下位に0をセット
		btfsc		PORTA,4			;入力データを取得
		bsf			flg,0			;最下位に1にセット
		nop
		movlw		04h				;時間調整
		movwf		bsyc0			;2+3*3+2=13cycles
rlp1	decfsz		bsyc0,F
		goto		rlp1

		decfsz		shift,F			;40ビット受信完了か
		GOTO		rloop			;90+(9+3+13)*0.4=100usec

		call		wait100u		;
		btfss		PORTA,4			;ストップビット確認
		goto		rlp2
		goto		rlp3
rlp2	call		wait100u
		bcf			PORTA,3			;RX OFF
		
		bcf			PORTB,7			;error
		call		wait100m
		bsf			PORTB,7
		
		retlw		01h				;受信失敗

rlp3	call		wait100u
		bcf			PORTA,3			;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




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			動作モードセット設定
;
;
;		受信指令ワーク
;				2桁表示モード		flg=xxxx0001
;				4桁表示モード		flg=xxxx0011
;				6桁表示モード		flg=xxxx0101
;				8桁表示モード		flg=xxxx0111
;								bit3 予約
;				ドット表示位置		flg=x111xxxx
;								bit4=1	2,5桁点燈
;								bit5=1	3,6桁点燈
;								bit6=1	4,7桁点燈
;				オーバーフロー		flg=1xxxxxxx
;
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

setmode
			movf		flg,W
			andlw		07h
			movwf		colum
;			btfss		flg,7
;			goto		stmd1
;			bcf			PORTA,4		;LED ON
;			return
;
;stmd1		bsf			PORTA,4		;LED OFF
			return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			現在位置でドットを表示するか否かの判定ルーチン
;
;		入力	Wレジスタ	0-Fのバイナリデータ
;			colum	現在の桁位置
;
;		出力	Wレジスタ	ドット点燈補正した0-Fのバイナリデータ
;					これをそのままget_7segサブルーチンに送る
;
;		使用ワーク
;			adtw0
;
;				ドット表示位置		flg=x111xxxx
;								bit4=1	2,5桁点燈
;								bit5=1	3,6桁点燈
;								bit6=1	4,7桁点燈
;				オーバーフロー		flg=1xxxxxxx
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

addot		;2,5桁点燈指令チェック
			movwf		adtw0		;Wのデータを保存
			btfss		flg,4		;2,5点燈指令か？
			goto		adt2		;違うので次ビットチェック
			;2桁目点燈処理
			movlw		01h			;colum=1の時2桁目
			subwf		colum,W		;現在2桁目か？
			btfss		STATUS,Z
			goto		adt1		;違うので5桁目へGO
			bsf			adtw0,4		;2桁目ドット点燈データ加算
			movf		adtw0,W
			return
			
adt1		;5桁目点燈処理
			movlw		04h			;
			subwf		colum,W		;現在5桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bsf			adtw0,4		;5桁目ドット点燈データ加算
			movf		adtw0,W
			return

adt2		;3,6桁点燈指令チェック
			btfss		flg,5		;3,6点燈指令か？
			goto		adt4		;違うので次ビットチェック

			;3桁目点燈処理
			movlw		02h			;
			subwf		colum,W		;現在3桁目か？
			btfss		STATUS,Z
			goto		adt3		;違うので6桁目へGO
			bsf			adtw0,4		;3桁目ドット点燈データ加算
			movf		adtw0,W
			return
			
adt3		;6桁目点燈処理
			movlw		05h			;
			subwf		colum,W		;現在6桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bsf			adtw0,4		;6桁目ドット点燈データ加算
			movf		adtw0,W
			return

adt4		;4,7桁点燈指令チェック			
			btfss		flg,6		;4,7点燈指令か？
			return					;違うので終了

			;4桁点燈処理
			movlw		03h			;
			subwf		colum,W		;現在4桁目か？
			btfss		STATUS,Z
			goto		adt5		;違うので7桁目へGO
			bsf			adtw0,4		;4桁目ドット点燈データ加算
			movf		adtw0,W
			return
			
adt5		;7桁目点燈処理
			movlw		06h			;
			subwf		colum,W		;現在7桁目か？
			btfss		STATUS,Z
			goto		adt6		;違うので終了
			bsf			adtw0,4		;7桁目ドット点燈データ加算
			movf		adtw0,W
			return

adt6		;何もせずリターン
			movf		adtw0,W
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			10進8桁LED表示出力サブルーチン　
;　
;		入力		BCD4バイト8桁分	digit12,34,56,78
;							digit9Aは無視される
;				colum	桁位置データ
;				PORTA0-2：桁制御
;				PORTB0-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		addot		;ドット表示チェック
			call		get_7seg	;セグメントデータに変換
			movwf		PORTB		;ポートBへ出力
			movf		colum,W		;桁位置取り出し
			movwf		PORTA		;桁位置出力
			decf		colum,F		;次の桁へシフト
			call		wait2m		;Wait 2msec
			movlw		0ffh
			movwf		PORTB		;桁表示クリア

			movf		tmp0,W		;下位取り出し
			andlw		0fh			;
			call		addot		;ドット表示チェック
			call		get_7seg	;セグメントへ変換
			movwf		PORTB		;ポートBへ出力
			movf		colum,W		;
			movwf		PORTA		;桁位置出力
			
			movf		colum,W
			iorlw		0h
			btfsc		STATUS,Z
			goto		disp21
			
			decf		colum,F		;次の桁へシフト
			call		wait2m
			movlw		0ffh
			movwf		PORTB		;桁表示クリア
			retlw		0h			;続き有り

disp21		;表示終了
			call		wait2m
			movlw		0ffh
			movwf		PORTB		;桁表示クリア
			retlw		01h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			１６進8桁LED表示出力サブルーチン　(ドット無)
;　
;		入力		16進バイナリ4バイト8桁分　hex0-hex3
;				PORTA0-2：桁制御
;				PORTB0-7：セグメント制御
;		使用ワーク	colum,tmp0,tmp1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

disp_8hn
			clrf		flg		
			movlw		07h
			movwf		colum		;6桁目から開始
			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			
			return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;			１６進6桁LED表示出力サブルーチン　(ドット有)
;			1桁目だけドットも点燈
;　
;		入力		16進バイナリ3バイト6桁分　hex0-2
;				PORTA0-2：桁制御
;				PORTB0-7：セグメント制御
;		使用ワーク	colum,tmp0,tmp1
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

disp_6hd
			clrf		flg
			movlw		05h
			movwf		colum		;6桁目から開始
			movf		hex2,w		;5,6桁目16進表示データ
			call		disp2c
			movf		hex1,w		;3,4
			call		disp2c
			movf		hex0,w		;1,2

			movwf		tmp0
			swapf		tmp0,W		;上位下位入れ替え
			andlw		0fh			;上位取り出し
			call		get_7seg	;セグメントデータに変換
			movwf		PORTB		;ポートBへ出力
			movf		colum,w		;桁位置取り出し
			movwf		PORTA		;桁位置出力
			decf		colum,f		;次の桁へシフト
			call		wait5m		;Wait 5msec
			movlw		0ffh
			movwf		PORTB		;桁表示クリア

			movf		tmp0,w		;下位取り出し
			andlw		0fh			;
			iorlw		010h		;ドット点燈分加算
			call		get_7seg	;セグメントへ変換
			movwf		PORTB		;ポートBへ出力
			movf		colum,w		;
			movwf		PORTA		;桁位置出力
			decf		colum,f		;次の桁へシフト
			call		wait5m
			movlw		0ffh
			movwf		PORTB		;桁表示クリア
			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

wait2m								;2msec
			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
			
