;************************************************************************************
;DS51K用ポイントマシンブースタプログラム　（PIC12F629)
;２つの入力スイッチによってＦＥＴを駆動し、ポイントを駆動する
;EEPROMに切り替え位置を記憶することで電源再投入後も直前の位置がリセットされないように対応
;(EEPROMを使用しない場合はソース中のコメント参照)
;
;FILE:pmboost4v103.ASM   Ver1.03
; Ver1.01　初版
; Ver1.02 2010/06/12 サブルーチンのリターンを　retlw　0　→　return に修正
; Ver1.03 2011/12/23 電源投入時の暴走対策　WDT追加 ブラウンアウト　OFF→ON
;
;参考文献　やさしいPICマイコンプログラミング入門
;	     PIC12F629 Dataseet (DS41190F)　　　　　　　　
;copyright(c) 2010　名古屋電鉄		http://www007.upp.so-net.ne.jp/nagoden/
;************************************************************************************

	list	p=12f629
	#include	<p12f629.inc>

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_ON & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 

#define		LEDL	GPIO,0
#define		LEDR	GPIO,1
#define		PMR		GPIO,2
#define		ADDR1	00h		;EEPROM への書き込みアドレス
#define		ADDR2	01h		;EEPROM への書き込みアドレス(未使用）

DIR			EQU	0x20	;方向フラグ
DIR2		EQU	0x21	;方向フラグワーク
CNT1		EQU	0x22	;タイマー用
CNT2		EQU	0x23	;タイマー用
EE_DAT		EQU 0x26	;EEPROM 書き込み用
EE_ADRS		EQU 0x27	;EEPROM アドレス用


		ORG		0x000
		goto	main
		ORG		0x004
		retfie
main
		;内部クロック補正
		bsf		STATUS,RP0 ; bank=1
		call	0x3ff
		movwf	OSCCAL
		bcf		STATUS,RP0 ; bank=0
		;割り込みを禁止
		clrf		INTCON
		;コンパレータ使用禁止
		movlw	0x07
		movwf	CMCON
		;GPIO 0,1,2,3を出力、4,5を入力
		bsf		STATUS,RP0 ;bank=1
		bcf		TRISIO,0
		bcf		TRISIO,1
		bcf		TRISIO,2
		bcf		TRISIO,3
		bsf		TRISIO,4
		bsf		TRISIO,5
		bcf		STATUS,RP0 ;bank=0
		;タイマークロックを内部、T1をオフ
		bcf		T1CON,T1OSCEN
		bcf		T1CON,TMR1CS
		bcf		T1CON,TMR1ON
		; WDT にプリスケーラを割当
		clrf	TMR0		; TMR0 をクリア
		bsf		STATUS, RP0	; バンク1に切り替え
		clrwdt				; WDT とプリスケーラのクリア
		movlw	b'00001111'	; 最終的に設定するプリスケール値 (1:128)を設定する
		movwf	OPTION_REG	;
		bcf		STATUS, RP0	; バンク0に切り替え


		;出力ポート初期化（０にする）
		bcf		PMR
		bcf		LEDL
		bcf		LEDR
		;EEPEOMを使用しない場合は下記の４行の；をはずす
		;movlw		d'0'
		;movwf		DIR
		;bsf		LEDL
		;bsf		PMR
		;goto		main_loop

		;EEPROM 読み出し
		bsf 		STATUS,RP0 	;bank 1
		movlw 		ADDR1 		;呼び出すアドレス1セット
		movwf 		EEADR 		;EEADR(9Bh) アドレス呼び出し
		bsf 		EECON1,RD 	;EE Read(9Ch) readに設定 
		movf 		EEDATA,W 	;EEDATA(9Dh) 呼び出しデータをワークレジスタにセット
		movwf		DIR     	;読み取ったワークレジスタの内容をDIRにセット
		bcf 		STATUS,RP0 	;bank 0


set_defalt
		;ＥＥＰＲＯＭデータ（ＤＩＲ方向）が０かチェックして、起動時の位置をセットし
		;ＬＥＤ及び出力の制御を行う
		movf		DIR,f
		btfss		STATUS,Z	;DIRが０かチェック
        goto 		set_lval
		bsf			LEDL
		bcf			PMR
		goto		main_loop
set_lval
		;DIRが０以外の時は　DIRを１にセット
		movlw		d'1'
		movwf		DIR
		bsf			LEDR
		bsf			PMR

main_loop
		;ウオッチドッグタイマクリア
		clrwdt				; WDT　クリア

		;スイッチ押下チェック
		btfsc		GPIO,4		;GP4が０かチェック
		goto		chk_nxt 	;1だったら（押されてなければ）GP5チェック
		goto		set_right
chk_nxt
		btfsc		GPIO,5		;GP5が０かチェック
		goto		main_loop 	;1だったら（押されてなければ）戻る
		goto		set_left

set_left	;左方向にセット
		movf		DIR,w		;dirをDIR2にコピーする
		movwf		DIR2
		movlw		d'0'		;dirを０にセットする
		movwf		DIR
		;DIR2が１だったらEEPROMへ０を書き込み
		movf		DIR2,f		;ファイルレジスタにセット（値チェックのため）
		btfss		STATUS,Z	;Ｚフラグが立っている（dirが０）かチェック
        CALL		set_eprom	;DIRが1→0にかわったのでEEPROMにDIRの値を書き込み
		goto		set_lled
set_lled
		;左側のＬＥＤをセット
		bcf			LEDR
		bsf			LEDL
		bcf			PMR
		goto		main_loop

set_right ;右方向にセット
		movf		DIR,w		;dirをDIR2にコピーする
		movwf		DIR2
		movlw		d'1'		;dirを１にセットする
		movwf		DIR
		movf		DIR2,f		;ファイルレジスタにセット（値チェックのため）
		btfss		STATUS,Z	;Ｚフラグが立っている（dirが０）かチェック
		goto		set_rled		
        CALL		set_eprom	;DIRが0→1にかわったのでEEPROMにDIRの値を書き込み
set_rled
		;右側のＬＥＤをセット
		bcf			LEDL
		bsf			LEDR
        bsf			PMR
		goto		main_loop


dly_n	;タイマールーチン
        ;ｃａｌｌ前にワークレジスタに値をセットしておくこと
		;NmS
		movwf		CNT1
dlp1	; 			1mS
		movlw		d'200'
		movwf		CNT2
dlp2
		nop
		nop
		decfsz		CNT2,f
		goto		dlp2
		decfsz		CNT1,f
		goto		dlp1

		return

set_eprom
		;ＤＩＲを方向の記憶のためにEEPROMへ書き込みとLEDの切り替えを行う
		movf		DIR,w
		movwf		EE_DAT		;EE_DAT にDIRをセット
        movf		ADDR1,w  	;書き込みアドレス１をセット
		movwf		EE_ADRS
		call		eeprom_w	;EEPROMへ書き込み
		return

eeprom_w
		;EEPEOMを使用しない場合はすぐ下の行の；を取る
		;return
 		;EEPROMへの書き込みルーチン
		bsf STATUS,RP0 	;Bank 1  
		movf EE_ADRS,w 	;EEPROMのアドレス指定  
		movwf EEADR 	;アドレスをEEADRへセット  
		movf EE_DAT,W	;内容をワークレジスタにセット  
		movwf EEDATA 	;EEDATAにセット  
		bsf EECON1,WREN ;EEPROM書き込み許可  
 		movlw 55H 		;  
		movwf EECON2 	;  
 		movlw 0AAH  
 		movwf EECON2  
 		bsf EECON1,WR 	;EEPROM書き込み開始  
wr_wait    
 		btfsc EECON1,WR ;EEPROM書き込み完了確認
 		goto wr_wait  
 		bcf STATUS,RP0 	;Bank 0  

        return

		END