;******************************************************************************
;Switch display unit via Loconet 
;PIC16F873A 
;copyright (c) 2015 名古屋電鉄　　http://www007.upp.so-net.ne.jp/nagoden/
;MDBMSW01.asm  2015/07/01 Ver1.00 
;******************************************************************************
;【概要】
;PIC16F873AのUSART機能を使いLOCONETに接続し、SwitchコマンドをLoconetから読み取り
;PICのポートに出力します。
;
;EEPROMには以下の情報を持ちます。
; 　1.Switchのオフセットアドレス
;	Switchコマンドのどのアドレスから開始するかを指定します。
;	動作は、ハードの制約から、オフセットアドレスから連続した８つの番号となります。
;
;	EEPROMの設定を容易にするためにセットアップモードを実装しています。
;	PIC16F873A　の14番ピン（RC3）がLowの時にセットアップモードとなり、スロットルのスイッチ番号
;　　　を指定して　ｔ　を押すことでEEPROMにスイッチ番号を書き込むようにします。
;
;------------------------------------------------------------------------------
;●USARTモードは以下の指定をしています 
;------------------------------------------------------------------------------
;   Mode : Asyncronous transfer mode only
;   Speed: 16K bps(12h 20Mhz) 
;   Bit  : startx1 datax8 stopx1
;　	※Loconetはボーレート16600bpsと特殊です。ここでは設定値から16447bpsにしています。
;------------------------------------------------------------------------------
;●PIC16F873A　ピンアサイン 
;------------------------------------------------------------------------------
;	RB0～RB7		オフセットアドレスから８つ連続した番号のスイッチ　	ｔでHigh　cでLow
;	RA0～RA3,5	オフセットアドレスから６つ連続した番号のスイッチ　	ｔでHigh　cでLow
; 	RC0～RC2　　	オフセットアドレスか７つ目と８つ目の番号のスイッチ　	ｔでHigh　cでLow		
; 	RA4 		状態表示用　ＬＥＤ(OC)
; 	RC3 		セットアップ用ジャンパーピン　
; 	RC4		未使用
; 	RC5		未使用		
; 	RC6 		TX（送信）　未使用
; 	RC7　		RX（受信）　Loconetより受信
;-------------------------------------------------------------------------------
;●LoconetのBDL168からくるコマンド
;-------------------------------------------------------------------------------
;  1.Switch のコマンド
;　       BC　aa bb cc　　
;		aa  0 A6 A5 A4　 A3  A2 A1 A0
;		bb  0  0 S1 S2  A10 A9 A8 A7 
;			A7～A0　Switchのアドレス
;			s1=0 Thrown 　s1=1 Close
;			s2=0　output off  S2=1 output 0n   
;		ｃｃ  check SUM;
;
;  4. Switch　の　ｔ　Or　C　を選択時のコマンド　（セットアップモードのみ）
;        B0　aa bb cc
;		aa  0 A6 A5 A4　 A3  A2 A1 A0
; 		bb  0  0 S1 S2  A10 A9 A8 A7 
;　			A7～A0　Switchのアドレス
;　			s1=0 Thrown 　s1=1 Close
;			s2=0　output off   S2=1 output on   
;  			ｃｃ  check SUM;
;        注：DCS50KとDT300で出力が違い　dt300では　ONと0FFを続けて出力するが、DCS50KではONのみを出力
;  　　　　　　　　 DCS50K   B0 00 30 7F → c      B0 00 10 5F → t
;
;---------------------------------------------------------------------------------
	list      p=16f873a
	#include <p16f873a.inc>

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF

;*****************************************************************************
;　EEPROMへのデータ定義（デフォルト値）
;*****************************************************************************
	org	0x2100
;-----　初期データ ---------説明----------------------
	de	0x00	;スイッチ番号の上位4ビット　ｘ　ｘ　ｘ　ｘ　A10 A9 A8 A7　
	de	0x00	;スイッチ番号の下位７ビット　ｘ　A6 A5 A4　 A3  A2 A1 A0
;*****************************************************************************
;変数定義
;*****************************************************************************
;割り込みルーチンで使用
w_temp		EQU	0x20 
status_temp	EQU	0x21
;１６ビットの減算ルーチンで使用
drawn_u		equ	0x22	;引かれる数(上位)
drawn_d		equ	0x23	;(下位)
draw_u		equ	0x24	;引く数(上位)
draw_d		equ	0x25	;(下位)
;スイッチ　ｔ　ｃ　のフラグ	
tc_flg		equ	0x26
;セットアップモード時の変数
S_MODE		EQU	0x27	;セットアップモード＝１
R_SWNO		EQU	0x28	;コマンド受信したスイッチ番号
;EEPROMからの値		
SWMSB		EQU	0x30	;スイッチ番号の上位4ビット(EEPROM値)
SWLSB		EQU	0x31	;スイッチ番号の下位７ビット(EEPROM値)
CMDMSB		EQU	0x32	;スイッチ番号の上位4ビット(コマンド値)
CMDLSB		EQU	0x33	;スイッチ番号の下位７ビット(コマンド値)
;内部処理変数
ADDR		EQU	0x34	;EEPROM アドレス
EE_DAT		EQU	0x35	;EEPROM データ
netcmd		EQU	0x37	;USART受信用
cmd_chk		EQU	0x38	;未使用
flg_d0		EQU	0x39	;コマンド受信フラグ
cmd_cnt		EQU	0x3A	;データ受信時のバイト数
cnt1		EQU	0x3E	;タイマーカウント
cnt2		EQU	0x3F	;タイマーカウント
cnt3		EQU	0x40	;タイマーカウント
;コマンド受信変数（受信して分解した結果）
R_BADRS		EQU	0x41	;受信ボードアドレス
R_SECT		EQU	0x43	;受信セクション番号
R_ADR1		EQU	0x44	;受信アドレス下位８ビット
R_ADR2		EQU	0x45	;受信アドレス上位８ビット
R_WK1		EQU	0x46	;コマンド編集用ワーク１
R_WK2		EQU	0x47	;コマンド編集用ワーク２
wk_data		EQU	0x48	;コマンド送信用ワーク
;コマンド受信　内部処理変数(間接アドレッシングで使用のためアドレス４Ａ~４Ｆまでは変更禁止)
cmd1		EQU	0x4A	;受信コマンド１バイト目
cmd2		EQU	0x4B	;受信コマンド２バイト目
cmd3		EQU	0x4C	;受信コマンド３バイト目
cmd4		EQU	0x4D	;受信コマンド４バイト目
cmd5		EQU	0x4E	;受信コマンド５バイト目
cmd6		EQU	0x4F	;受信コマンド６バイト目

;*****************************************************************************
;マクロ定義
;*****************************************************************************
;バンクの指定
BANK0	MACRO
	BCF	STATUS,RP0	;BANK 0に切替
	BCF	STATUS,RP1	;
	ENDM
BANK1	MACRO
	BSF	STATUS,RP0	;BANK 1に切替
	BCF	STATUS,RP1	;
	ENDM
BANK2	MACRO
	BCF	STATUS,RP0	;BANK 2に切替
	BSF	STATUS,RP1	;
	ENDM
BANK3	MACRO
	BSF	STATUS,RP0	;BANK 3に切替
	BSF	STATUS,RP1	;
	ENDM
;*****************************************************************************
;プログラムスタート
;*****************************************************************************
	ORG	0x000             
  	goto	init  				
	ORG	0x004			; 割り込みベクタ
	movwf	w_temp        	  	; ワークレジスタ退避
	movf	STATUS,w          	; ステータスレジスタをワークレジスタに
	movwf	status_temp       	; ワークレジスタ（ステータス）退避
				  	; ←ここに割り込みルーチン設定
	BANK0				; バンク０に切り替え	
	movf	status_temp,w     	;　退避ステータスのワークレジスタへ戻し
	movwf	STATUS            	; ワークレジスタからステータスへ戻し
	swapf	w_temp,f			;　ワークレジスタの戻し	
	swapf	w_temp,w          	; ワークレジスタの戻し
	retfie                    	; 割り込み終了
init
;*****************************************************************************
;ＰＩＣの入力ポートとUSARTの設定
;*****************************************************************************
	BANK1
	;ポートの設定
	movlw	0x06			;コレをしないとportＡのデジタル入力ができません
	movwf	ADCON1			;ADCON1に06Hを設定しポートＡをすべてデジタルに
	movlw	B'00000000'
	movwf	TRISA			; ポートAは全て出力端子　
	movlw	B'00000000'
	movwf	TRISB			; ポートBは全て出力端子
	movlw	0x80
	movwf	OPTION_REG		; ポートＢプルアップなし
	movlw	B'10001000'
	movwf	TRISC			; ポートCはRC7とRC3が入力端子　後は出力
	BANK0
	clrf	PORTA			; PORTクリア
	clrf	PORTB			; PORTクリア
	clrf	PORTC

	;USARTの設定 PIC12F873 20Mhｚ
	BANK1
	movlw	0x20			;↓でAsync mode　に設定 
	movwf	TXSTA			;TXSTAにセット
	movlw	d'18'			;18→ボーレート 16Kbps   16447.37=20Mhz/((18+1)*64)
	movwf	SPBRG			;SPBRGにボーレート設定		
	BANK0					;Bank 0に切り替え
	movlw	0x90			;↓でシリアルピン設定、継続受信許可　に設定 
	movwf	RCSTA			;RCSTAにセット
	
main_init
;*****************************************************************************
;ＥＥＰＲＯＭを読んで　スイッチのオフセット番号を取得
;ここで取得されるアドレスに従って制御する
;*****************************************************************************
	;BDL168ボードアドレス　（BADRS）
	movlw	0x00
	movwf	ADDR		
	call	eeprom_r	
	movwf	SWMSB	
	movlw	0x01
	movwf	ADDR		
	call	eeprom_r	
	movwf	SWLSB
main
;*****************************************************************************
;メインルーチン
;*****************************************************************************
mode_chk
	;セットアップモードチェック　(セットアップモードの時　S_MODE=1)
	clrf	S_MODE
	btfsc	PORTC,3			;RC3が０　ショートピンでショートしていた場合
	goto	mode_chkend		;０でない場合は通常モード
	movlw	d'1'
	movwf	S_MODE			;セットアップモード時は１
	goto	mode_chkend
mode_chkend

main_loop
	;コマンド受信
	call	rcv_usart
	goto	main_loop

;*****************************************************************************
;USART コマンド受信処理
;*****************************************************************************
rcv_usart
	;----------------------------------------------------------
	;受信したコマンドが該当（D0,BC,B2,B0)だったら受信フラグを立てて残りバイト受信
	;----------------------------------------------------------
	movlw	0x4A			;set buffer top address
	movwf	FSR				;間接アドレスポインタ初期化
	clrf	cmd_cnt
	clrf	flg_d0
lprcv
	;受信ステータスチェック
	btfss	PIR1,RCIF		;受信完了フラグのチェック
	goto	re_recv
	;エラーチェック
	btfsc	RCSTA,FERR		;FRAME エラー
	goto	frame_err
	btfsc	RCSTA,OERR		;オーバーラン　エラー
	goto	ovrun_err
	;データ受信
	bsf	PORTA,4			;LED on
 	movf	RCREG,W			;受信データ取得しワークエリアに
	movwf	netcmd			;ワークにある受信したデータをnetcmdにセット
	;D0受信フラグ（flg_d0）が０以外の場合コマンドチェックせず以降のコマンド受信
	movf	flg_d0,f
	btfss	STATUS,Z		;０かどうか判定
	goto	other_cmd		;0<>なら　D0受信フラグ＝1なのでother_cmdへ
	goto	tsp_cmd			;0= なら　１バイト目のコマンドチェック
frame_err
	movf	RCREG,W			;ダミーで読み取りフレームエラー解除
       	btfss	RCSTA,OERR
	goto	rcv_end
ovrun_err
	BCF		RCSTA,CREN		;crenのビットをリセットすることでｏｖｅｒRunエラー解除　　		
	BSF		RCSTA,CREN
	goto	rcv_end	
re_recv
	movf	flg_d0,f
	btfss	STATUS,Z		;０かどうか判定
	goto	lprcv			;0<>なら　D0受信フラグ＝1なので受信待ち
	goto	rcv_end			;０ならそのまま受信ループ終了
;------------------------------------------------------------------------------
;1バイト目のコマンドチェック
;コマンドに応じて　flg_d0　に値をセット　　D0->0 B2->1 BC->2 B0->3
;------------------------------------------------------------------------------
tsp_cmd
	;-------------------------------
	;コマンドがＤ０（Transponding）
	;-------------------------------
	movf	netcmd,w
	sublw	0xD0			;D0と受信したコマンドを引いて０かチェック
	btfss	STATUS,Z		;０かどうか判定
	goto	ctrl_cmd		;0<>なら次のコマンドチェック
	;D0だったら受信フラグに１を立てる
	movlw	d'1'			;受信フラグ＝１にセット
	movwf	flg_d0			;受信フラグ（flg_d0）に1セット
	movlw	d'6'
	movwf	cmd_cnt			;D0を受信時 6バイト受信
	goto	other_cmd		;
ctrl_cmd
	;-------------------------------
	;コマンドがＢ２（セクションＯＮ／ＯＦＦ）
	;-------------------------------
	movf	netcmd,w
	sublw	0xB2	
	btfss	STATUS,Z		;０かどうか判定
	goto	ctrl_cmd2		;0<>なら次のコマンドチェック
	;B2だったら受信フラグに２を立てる
	movlw	d'2'			;受信フラグ＝２にセット
	movwf	flg_d0			;受信フラグ（flg_d0）に2をセット
	movlw	d'4'
	movwf	cmd_cnt			;B2を受信時 4バイト受信
	goto	other_cmd		;
ctrl_cmd2
	;-------------------------------
	;コマンドがＢＣかチェック
	;-------------------------------
	movf	netcmd,w
	sublw	0xBC	
	btfss	STATUS,Z		;０かどうか判定
	goto	ctrl_cmd3		;0<>なら次のコマンドチェック
	;BCだったら受信フラグに３を立てる
	movlw	d'3'			;受信フラグ＝3にセット
	movwf	flg_d0			;受信フラグ（flg_d0）に３をセット
	movlw	d'4'
	movwf	cmd_cnt			;BCを受信時 4バイト受信
	goto	other_cmd		;
ctrl_cmd3
	;-------------------------------
	;コマンドがＢ０（スイッチコマンドのtｃ選択）かチェック
	;-------------------------------
	movf	netcmd,w
	sublw	0xB0	
	btfss	STATUS,Z		;０かどうか判定
	goto	rcv_end			;0<>ならrcv_endへ飛ぶ
	;B0だったら受信フラグに４を立てる
	movlw	d'4'			;受信フラグ＝4にセット
	movwf	flg_d0			;受信フラグ（flg_d0）に４をセット
	movlw	d'4'
	movwf	cmd_cnt			;B0を受信時 4バイト受信
	goto	other_cmd		;
;-------------------------------------------------------------------------------
;２バイト目以降のコマンド処理
;-------------------------------------------------------------------------------
other_cmd
	;受信フラグが１なら指定バイト数になるまで順次受信
	movf	netcmd,w		;ワークにある受信したデータをnetcmdにセット
	movwf	INDF			;save in buffer
	incf	FSR,F			;FSR+1
	decf	cmd_cnt,f		;cmd_cnt-1
	btfss	STATUS,Z		;０かどうか判定
	goto	lprcv			;既定のコマンド数に達しない場合は受信処理に戻り次コマンド受信

	;受信コマンド判別
	movf	flg_d0,w
	sublw	D'1'			;1->D0 2->B2 3->BC 4->B0
	btfsc	STATUS,Z		;０かどうか判定
	goto	cmd_D0			;D0(transponding）コマンドの処理へ
			
	movf	flg_d0,w
	sublw	D'2'			;1->D0 2->B2 3->BC 4->B0
	btfsc	STATUS,Z		;０かどうか判定
	goto	cmd_B2			;B2(Section　ON/OFF）コマンドの処理へ

	movf	flg_d0,w
	sublw	D'3'			;1->D0 2->B2 3->BC 4->B0
	btfsc	STATUS,Z		;０かどうか判定
	goto	cmd_BC			;BC(SWITCH）コマンドの処理へ

	movf	flg_d0,w
	sublw	D'4'			;1->D0 2->B2 3->BC 4->B0
	btfsc	STATUS,Z		;０かどうか判定
	goto	cmd_B0			;B0(スイッチ選択）コマンドの処理へ
	goto	rcv_end
						
;*****************************************************************************
;　コマンドＤ０（Ｔｒａｎｓｐｏｎｄｉｎｇ）の処理
;*****************************************************************************
cmd_D0
	;Transpondingの処理は割愛
	goto	rcv_end
;*****************************************************************************
;　コマンドＢ２（セクションＯＮ／ＯＦＦ）の処理
;*****************************************************************************
cmd_B2
	;ｾｸｼｮﾝの処理は割愛
	goto	rcv_end
;*****************************************************************************
;　コマンドＢＣ(スイッチ選択)の処理
;*****************************************************************************
cmd_BC
	;スイッチ選択の処理は割愛
	goto	rcv_end				

;*****************************************************************************
;　コマンドＢ０の処理(Switch切替コマンド)
;*****************************************************************************
cmd_B0
	;----------------------------------------------
	;	B0　aa bb cc　（ｔ　Or　C　を選択時）
	;		aa  0 A6 A5 A4　 A3  A2 A1 A0
	; 		bb  0  0 S1 S2  A10 A9 A8 A7 
	;　			A7～A0　Switchのアドレス
	;　			s1=0 Thrown 　s1=1 Close
	;			s2=0　output off  S2=1 output on   
	;  		ｃｃ  check SUM;
	;	tで　スイッチ番号を　EEPROMに書き込む
	;----------------------------------------------
;セットアップモードの確認
	movf	S_MODE,w
	sublw	d'1'	
	btfss	STATUS,Z		;1かどうか判定
	goto	cmd_proc		;S_MODE=0ならコマンド処理へ飛ぶ
	goto	setup_sta

;セットアップモードの処理
setup_sta
	btfsc	cmd3,5		;５ビット目でtかｃが押されたか判別　　０がｔ　１がｃ
	goto	cmd_b0end	;c(-)が押された
	btfss	cmd3,4		;ｔ(+)が押された
	goto	cmd_b0end	;S2=1 output 0ff の場合
	movf	cmd2,w
	andlw	b'01111111'	;アドレス以外のビット情報を取る			
	movwf	CMDLSB		;下位7ビットのSWITCHアドレスの情報
	movf	cmd3,w
	andlw	b'00001111'	;アドレス以外のビット情報を取る
	movwf	CMDMSB		;上位4ビットのSWITCHアドレスの情報


	;スイッチ番号をオフセットアドレスとしてEEPROMに保存
	movlw	0x00
	movwf	ADDR
	movf	CMDMSB,w	
	movwf	EE_DAT	
	call	eeprom_w
	movlw	0x01
	movwf	ADDR
	movf	CMDLSB,w	
	movwf	EE_DAT	
	call	eeprom_w	

setup_end
	;EEPROMに書き込んだらＬＥＤ点滅でループ
	bcf	PORTA,4		;LED off
	movlw	d'250'
	call	dly_Nm
	bsf	PORTA,4		;LED off
	movlw	d'250'
	call	dly_Nm
	goto	setup_end

;コマンド処理
cmd_proc
;	コマンドからくるアドレス　CMDMSB　CMDLSB
;	EEPROMのアドレス	SWMSB　　SWLSB
	btfss	cmd3,4			;output on　のコマンドのみ処理のため判別
	goto	cmd_b0end		;S2=1 output 0ff の場合
; 　ｔ　ｃ　の判別　t=1　c=0
	movlw	d'0'	
	movwf	tc_flg
	btfsc	cmd3,5			;５ビット目でtかｃが押されたか判別　　０がｔ　１がｃ
	goto	cmd_set			;c(-)が押された
	movlw	d'1'	
	movwf	tc_flg
cmd_set

;コマンドのアドレスをCMDMSB　CMDLSBにセット
	movf	cmd3,w
	andlw	b'00001111'		;アドレス以外のビット情報を取る
	movwf	CMDMSB			;上位4ビットのSWITCHアドレスの情報
	movf	cmd2,w
	andlw	b'01111111'		;アドレス以外のビット情報を取る			
	movwf	CMDLSB			;下位7ビットのSWITCHアドレスの情報
;EEPROMの値と引き算
	movf	CMDMSB,w
	movwf	drawn_u
	movf	CMDLSB,w
	movwf	drawn_d
	movf	SWMSB,w
	movwf	draw_u
	movf	SWLSB,w
	movwf	draw_d
	call 	sub16
;	結果はdrawn_u　と　drawn_dに返る
;	drawn_uが０でなければ対象外
	movf	drawn_u,f
	btfss	STATUS,Z
	goto	cmd_b0end
;　　　　　　drawn_dの値が0から15までにあれば出力範囲
	movf	tc_flg,f
	btfsc	STATUS,Z
	goto	cmd_poff1
cmd_pon1
	movf	drawn_d,w
	sublw	d'0'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon2
	bsf	PORTB,7
	goto	cmd_b0end
cmd_pon2 
	movf	drawn_d,w
	sublw	d'1'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon3
	bsf	PORTB,6
	goto	cmd_b0end
cmd_pon3
	movf	drawn_d,w
	sublw	d'2'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon4
	bsf	PORTB,5
	goto	cmd_b0end
cmd_pon4
	movf	drawn_d,w
	sublw	d'3'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon5
	bsf	PORTB,4
	goto	cmd_b0end
cmd_pon5
	movf	drawn_d,w
	sublw	d'4'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon6
	bsf	PORTB,3
	goto	cmd_b0end
cmd_pon6
	movf	drawn_d,w
	sublw	d'5'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon7
   	bsf	PORTB,2
	goto	cmd_b0end
cmd_pon7
	movf	drawn_d,w
	sublw	d'6'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon8
   	bsf	PORTB,1
	goto	cmd_b0end
cmd_pon8
	movf	drawn_d,w
	sublw	d'7'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon9
	bsf	PORTB,0
	goto	cmd_b0end
cmd_pon9
	movf	drawn_d,w
	sublw	d'8'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon10
	bsf	PORTA,0
	goto	cmd_b0end
cmd_pon10
	movf	drawn_d,w
	sublw	d'9'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon11
	bsf	PORTA,1
	goto	cmd_b0end
cmd_pon11
	movf	drawn_d,w
	sublw	d'10'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon12
	bsf	PORTA,2
	goto	cmd_b0end
cmd_pon12
	movf	drawn_d,w
	sublw	d'11'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon13
	bsf	PORTA,3
	goto	cmd_b0end
cmd_pon13
	movf	drawn_d,w
	sublw	d'12'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon14
	bsf	PORTA,5
	goto	cmd_b0end
cmd_pon14
	movf	drawn_d,w
	sublw	d'13'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon15
	bsf	PORTC,0
	goto	cmd_b0end
cmd_pon15
	movf	drawn_d,w
	sublw	d'14'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_pon16
	bsf	PORTC,1
	goto	cmd_b0end
cmd_pon16
	movf	drawn_d,w
	sublw	d'15'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_b0end
	bsf	PORTC,2
	goto	cmd_b0end
cmd_poff1
	movf	drawn_d,w
	sublw	d'0'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff2
	bcf	PORTB,7
	goto	cmd_b0end
cmd_poff2 
	movf	drawn_d,w
	sublw	d'1'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff3
	bcf	PORTB,6
	goto	cmd_b0end
cmd_poff3
	movf	drawn_d,w
	sublw	d'2'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff4
	bcf	PORTB,5
	goto	cmd_b0end
cmd_poff4
	movf	drawn_d,w
	sublw	d'3'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff5
	bcf	PORTB,4
	goto	cmd_b0end
cmd_poff5
	movf	drawn_d,w
	sublw	d'4'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff6
	bcf	PORTB,3
	goto	cmd_b0end
cmd_poff6
	movf	drawn_d,w
	sublw	d'5'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff7
	bcf	PORTB,2
	goto	cmd_b0end
cmd_poff7
	movf	drawn_d,w
	sublw	d'6'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff8
	bcf	PORTB,1
	goto	cmd_b0end
cmd_poff8
	movf	drawn_d,w
	sublw	d'7'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff9
	bcf	PORTB,0
	goto	cmd_b0end
cmd_poff9
	movf	drawn_d,w
	sublw	d'8'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff10
	bcf	PORTA,0
	goto	cmd_b0end
cmd_poff10
	movf	drawn_d,w
	sublw	d'9'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff11
	bcf	PORTA,1
	goto	cmd_b0end
cmd_poff11
	movf	drawn_d,w
	sublw	d'10'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff12
	bcf	PORTA,2
	goto	cmd_b0end
cmd_poff12
	movf	drawn_d,w
	sublw	d'11'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff13
	bcf	PORTA,3
	goto	cmd_b0end
cmd_poff13
	movf	drawn_d,w
	sublw	d'12'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff14
	bcf	PORTA,5
	goto	cmd_b0end
cmd_poff14
	movf	drawn_d,w
	sublw	d'13'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff15
	bcf	PORTC,0
	goto	cmd_b0end
cmd_poff15
	movf	drawn_d,w
	sublw	d'14'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_poff16
	bcf	PORTC,1
	goto	cmd_b0end
cmd_poff16
	movf	drawn_d,w
	sublw	d'15'
	btfss	STATUS,Z		;０かどうか判定
	goto	cmd_b0end
	bcf	PORTC,2
	goto	cmd_b0end
cmd_b0end
	goto	rcv_end				

;*****************************************************************************
;　コマンド処理終了によるフラグのクリア
;*****************************************************************************
rcv_end
	movlw	d'0'		;D0受信フラグ＝0にセット
	movwf	flg_d0		;D0受信フラグ（flg_d0）に0セット
	bcf	PORTA,4		;LED off
	RETURN
;*****************************************************************************
;ＥＥＰＲＯＭ読み書きルーチン
;*****************************************************************************
eeprom_r
	;EEPROM 読み出し
	BANK2
	movf 	ADDR,w		;呼び出すアドレス1セット
	movwf 	EEADR 		;EEADR(10Dh) アドレス呼び出し
        BANK3
	bcf	EECON1,EEPGD	;Point to Data memory
	bsf 	EECON1,RD	;EE Read(18Ch) readに設定 
	BANK2
	movf 	EEDATA,w 	;EEDATA(10Ch) 呼び出しデータをワークレジスタにセット:;
	BANK0
	return
eeprom_w
 	;EEPROMへの書き込み
	BANK2  
	movf	ADDR,w 		;EEPROMのアドレス指定  
	movwf	EEADR		;アドレスをEEADRへセット  
	movf 	EE_DAT,w	;内容をワークレジスタにセット  
	movwf 	EEDATA		;EEDATAにセット  
	BANK3
	bcf	EECON1,EEPGD	;Point to Data memory
	bsf 	EECON1,WREN 	;EEPROM書き込み許可  
	bcf	INTCON,GIE	;割り込み禁止
	movlw	0x55 		  
	movwf	EECON2 	  
	movlw	0xAA  
	movwf	EECON2  
	bsf	EECON1,WR 	;EEPROM書き込み開始
	bcf	EECON1,WREN 	;EEPROM書き込み禁止  
	bsf	INTCON,GIE	;割り込み許可
wr_wait    
 	btfsc 	EECON1,WR 	;EEPROM書き込み完了確認
 	goto 	wr_wait  
	BANK0
        return

;*****************************************************************************
;１６ビットの減算サブルーチン　sub16
;	引かれる数	drawn_u(上位),drawn_d(下位) 
;	引く数  　	draw_u(上位),drawn_d(下位)  
;	結果	drawn_u(上位),drawn_d(下位) 
;		   引く数の変数は変化しない。
;*****************************************************************************
sub16
	movf	draw_d,w
	subwf	drawn_d,f
	btfss	STATUS,0
	decf	drawn_u,f
	movf	draw_u,w
	subwf	drawn_u,f
	return
;*****************************************************************************
;時間遅延ルーチン クロック20MHz用
;*****************************************************************************
	;---------------------------------
	; 60マイクロ秒遅延
	; 1/16600bps　=　60.24μｓ　=60μｓ
	;---------------------------------
dly_60u	; 60uS
	movlw	d'60'
	movwf	cnt1
dly_60u1
	nop
	nop
	nop
	nop
	decfsz	cnt1,f
	goto	dly_60u1
	return
	;---------------------------------
	; 100マイクロ秒遅延
	;---------------------------------
dly_100u	; 100uS
	movlw	d'100'
	movwf	cnt2
dly_100u1
	nop
	nop
	nop
	nop
	decfsz	cnt2,f
	goto	dly_100u1
	return
	;---------------------------------
	; 600マイクロ秒遅延
	;---------------------------------
dly_600u	; 600uS
	movlw	d'6'
	movwf	cnt1
dly_600u1
	call 	dly_100u
	decfsz	cnt1,f
	goto	dly_600u1
	return
	;---------------------------------
	; nミリ秒遅延
	;call 前にワークにループ数をセット
	;例：movlw		d'10'
	;---------------------------------
dly_Nm	; NmS
	movwf	cnt1
dly_Nm1
	call	dly_1m
	decfsz	cnt1,f
	goto	dly_Nm1
	return
	;---------------------------------
	; 1ミリ秒遅延
	;---------------------------------
dly_1m	; 1ms
	movlw		d'4'
	movwf		cnt2
dly_1m1	
	movlw		d'250'
	movwf		cnt3
dly_1m2	; 250us
	nop
	nop
	nop
	nop
	decfsz		cnt3,f
	goto		dly_1m2
	decfsz		cnt2,f
	goto		dly_1m1
	return



	END