;	list p=PIC16F628
#include <P16F628.INC>
;
; Signal unit version 2.01
; (c) Sugihara Toshio.
; All rights reserved.
; PIC16F628
; Clock=4.19MHz osc=XT
; WDT=off PowerupTimer=on
; Protect=off BrownoutDetect=off
; LowVoltageProg=off MCLR=Disable

; Memory for Bank 0
;時間カウント関係
tcountl	equ	H'20'	;1/16sずつ更新
tcountq	equ	H'21'	;1/4秒ずつ更新
tcounts	equ	H'22'	;1秒ずつ更新
;ブザー制御関係
beepa	equ	H'23'	;短いのの回数
beepb	equ	H'24'	;短いのの回数
beepc	equ	H'25'	;長いのの長さ(7で3/4秒程度)
beepw	equ	H'26'	;休憩の長さ(2で3/8秒程度)
isbeep	equ	H'27'	;使用中かのフラグ
;表示関係
bufa		equ	H'28'
bufb		equ	H'29'
tenmetu	equ	H'2a';6=BR,5=BY,4=BWG,2=AR,1=AY,0=AWG
				;6=B2,5=B4,4=B7,2=A1,1=A2,0=B1
;動作状態
runpos	equ	H'2b'	;現在の実行位置
secleft	equ	H'2c'	;現在のままいられる残り秒数(0=無限)
tadr		equ	H'2d'	;時間を入れるアドレスを格納
alarm	equ	H'2e'	;bit0がブザーの状態(1:On 0:Off)
runstatus	equ	H'2f'	;bit0=ボタン3の通常許可ビット(1=許可0=禁止)

;リモコン関係
rileft	equ	H'30'	;残りビット数 0-32くらい
rit		equ	H'31'	;タイマ値用
ritb		equ	H'32'	;タイマ値バックアップ用
rix		equ	H'33'	;タイマ値計算用
rv0		equ	H'34'	;読み取り値用(ベンダ上位)
rv1		equ	H'35'	;(ベンダ下位)
rv2		equ	H'36'	;(値本体:1-3)
rv3		equ	H'37'	;(値本体反転)

;編集中の設定値
evsel	equ	H'38'	;編集中の番号(0-9)
ev00		equ	H'39'
ev01		equ	H'3a'
ev02		equ	H'3b'
ev03		equ	H'3c'
ev04		equ	H'3d'
ev05		equ	H'3e'
ev06		equ	H'3f'
ev07		equ	H'40'
ev08		equ	H'41'
ev09		equ	H'42'

ev00bak	equ	H'4e'	;動作モードのバックアップ(初期はH'ff')
;テンポラリな値
tmp1		equ	H'4f'

;時間関係のデータ
tm00		equ	H'50'
tm01		equ	H'51'
tm02		equ	H'52'
tm03		equ	H'53'
tm04		equ	H'54'	;Aが赤になってからBが青になるまで
tm05		equ	H'55'
tm06		equ	H'56'
tm07		equ	H'57'
tm08		equ	H'58'
tm09		equ	H'59'
tm0a		equ	H'5a'
tm0b		equ	H'5b'
tm0c		equ	H'5c'

;EEPROM制御関係(バンク1)
eebuf		equ	H'a0'


;プログラムの開始点
boot
	org	H'0'
	goto start
warukomi
	org H'4'
	goto start

start
	;I/Oなどの初期化
	clrf INTCON
	clrf STATUS
	movlw H'10'
	movwf PORTA
	clrf PORTB
	movlw B'00111000'	;Select Bank 1
	movwf STATUS
	movlw B'11010111'	;TMR0 overflows per 1/16s
	movwf OPTION_REG
	movlw B'11100000'	;A5だけ入力。ほかは出力
	movwf TRISA
	clrf TRISB		;Bは全て出力
	bcf STATUS,RP0	;Select Bank 0
	movlw B'00000111'	;コンパレータを使わない
	movwf CMCON
	movlw H'10'		;ブザーは鳴らない。消灯
	movwf PORTA
	clrf PORTB		;消灯。
	;タイマの初期化
	clrf TMR0		;値を初期化
	bcf INTCON,T0IF	;あふれフラグを下げる	
	;状態の変数を初期化
	clrf tcountl
	clrf tcountq
	clrf tcounts
	clrf bufa
	clrf bufb
	clrf tenmetu
	clrf tadr
	clrf alarm		;最初は鳴っていない
	clrf evsel		;設定対象の選択は先頭から
	clrf runpos		;初期の動作位置(すぐ後で更新される)
	clrf runstatus	;初期状態
	movlw H'ff'		;初期の
	movwf ev00bak	;動作モード(読み込み時に更新を促す)

	;設定データのロードと初期化
	call loadev		;EEPROMに保存したデータをevXXにロードする
	call setfromev	;evXXの値に従い変数を初期化する
	clrf ev09		;ev09は起動時は「0:セーブ」に固定。

	;起動音を鳴らす
	;3回、2回、0.75s、の間ブザーを鳴らす
	movlw D'3'
	movwf beepa
	movlw D'2'
	movwf beepb
	movlw D'7'
	movwf beepc
	movlw D'1'
	movwf isbeep
	movwf beepw

	;メインループ(リモコン待ちは初期状態)
mainloop
	btfsc INTCON,T0IF		;タイマあふれの
	call inctimer		;検出

	;消灯状態となるまでmainloopをくり返す
	btfss PORTA,5
	goto mainloop

	;消灯状態から
mainloopd
	btfsc INTCON,T0IF		;タイマあふれの
	call inctimer		;検出

	;点灯状態となるまで待つ
	btfsc PORTA,5
	goto mainloopd

	;リーダコード消灯待ち
	movf TMR0,W
	movwf rit	;タイマ値を保存
mainloopr1
	btfsc INTCON,T0IF
	call inctimer
	btfsc PORTA,5	;消灯？
	goto mainloopr2	;はい。
					;いいえ。
	;消灯しない場合
	;11ms以上であきらめる(46以上上がった場合)
	movf rit,W
	subwf TMR0,W	; W = 経過時間
	sublw D'45'	;W = 45 - W
	btfss STATUS,C	;W(経過時間) > 45?
	goto mainloop	;はい。長すぎるのでメインに戻る。
	goto mainloopr1	;いいえ。まだ続ける。

	;消灯した場合
mainloopr2
	movf rit,W
	subwf TMR0,W	;W=経過時間
	;(6.84ms)28未満であきらめる
	sublw D'27'	;W = 27 - W
	btfsc STATUS,C	;W(経過時間)>27?
	goto mainloop	;いいえ。短すぎるのでメインに戻る。
					;はい。

	;タイマ値をバックアップ
	movf TMR0,W
	movwf rit
	;再び点灯を待つ
mainloopr3
	btfss PORTA,	5	;点灯した？
	goto mainloopr4	;はい。
					;いいえ。
	;6.5ms(27)以上たっていたらあきらめる
	movf rit,W
	subwf TMR0,W	;W=経過時間
	sublw D'26'	;W = 26 - W
	btfss STATUS,C	;W(経過時間) > 26?
	goto mainloop	;はい。長すぎるのでメインに戻る。
	goto mainloopr3	;いいえ。ループを続ける。

	;点灯した
mainloopr4
	;タイミングを記録
	movf TMR0,W
	movwf ritb	;ritbに点灯したタイミングを入れる。
	;2.5ms(10)未満だったらあきらめる
	subwf rit,W	;W=マイナスの経過時間
	addlw D'9'
	btfsc STATUS,C	;くりあがった？
	goto mainloop	;はい。2.5ms未満なのでメインに戻る。
					;いいえ。
	;読みたいのは32ビット
	movlw D'32'
	movwf rileft

	;再び消灯を待つ
mainloopr5
	;タイマ繰り上がチェック
	btfsc INTCON,T0IF
	call inctimer
	;1ms以内に消えるか
	movlw D'210'
	movwf rix
mainloopr6
	btfsc PORTA,5	;消灯した？
	goto mainloopr7	;はい。
					;いいえ。
	decfsz rix,F
	goto mainloopr6
	goto mainloop	;1msたっても消えないので戻る。

	;再び点灯を待つ
mainloopr7
	btfss PORTA,5	;点灯した？
	goto mainloopr8	;はい。
					;いいえ。
	;13以上動いていたら戻る
	movf ritb,W
	subwf TMR0,W	;W=経過時間
	sublw D'12'	;W=12-経過時間
	btfsc STATUS,C
	goto mainloopr7	;経過時間<=12
	goto mainloop	;経過時間>12。周期が長すぎ
	;点灯した。
mainloopr8
	;現在のタイミングを保存
	movf TMR0,W
	movwf rit	;新しいのはritに。
	movf ritb,W	;1つ前のがritbに入っている。
	subwf rit,W	;W = 経過(rit-ritb)
	movwf rix	;rix = 経過時間
	;1以下だったら失敗
	andlw B'11111110'
	btfsc STATUS,Z
	goto mainloop
	;7だったらエラー
	movf rix,W
	xorlw D'7'
	btfsc STATUS,Z
	goto mainloop
	;13以上だったらエラー
	movf rix,W
	sublw D'12'	;W=12-経過時間	
	btfss STATUS,C	;経過時間>12?
	goto mainloop	;はい。
					;いいえ。
	;2-6=0 8-12=1
	;右シフト
	rrf rv3,F
	rrf rv2,F
	rrf rv1,F
	rrf rv0,F
	;経過時間に応じて値を最上位側に入れる。
	bcf rv3,7	;とりあえず0を入れる。
	btfsc rix,3	;8の位が上がっているときは、
	bsf rv3,7	;1にする。
	;タイミング情報をバックアップ側に回す
	movf rit,W
	movwf ritb
	;ビット数を進める
	decfsz rileft,F
	goto mainloopr5

;最後のビットを読んだ後
	;タイマ繰り上がチェック
	btfsc INTCON,T0IF
	call inctimer
	;1ms以内に消えるか
	movlw D'210'
	movwf rix
mainloopr9
	btfsc PORTA,5	;消灯した？
	goto mainloopr10	;はい。
					;いいえ。
	decfsz rix,F
	goto mainloopr9
	goto mainloop	;1msたっても消えないので戻る。

mainloopr10
	;前回の点灯から3ms以内に再び光らないか
	;タイマ繰り上がチェック
	btfsc INTCON,T0IF
	call inctimer
	;光っていたらだめです
	btfss PORTA,5
	goto mainloop
	;14回ぶん以上たっていたら抜ける
	movf ritb,W
	subwf TMR0,W	;W = 経過時間(TMR0 - ritb) 
	sublw D'13'	; W = 13 - 経過時間
	btfsc STATUS,C	;経過時間 > 13 ?
	goto mainloopr10	;いいえ。
					;はい。

	;値の検査
mainloopr11
	;ベンダコードが0x0033であるかチェック
	movf rv0,W
	xorlw H'00'
	btfss STATUS,Z
	goto mainloop

	movf rv1,W
	xorlw H'33'
	btfss STATUS,Z
	goto mainloop
	;最後のバイトがデータの反転になっているかチェック
	movf rv2,W
	xorwf rv3,W
	xorlw H'ff'
	btfss STATUS,Z
	goto mainloop
	;おめでとう！リモコン受信に成功。
	;値そのものはrv2に入っている
	;タイマ繰り上がチェック
	btfsc INTCON,T0IF
	call inctimer

	;状態に応じて動作。
	;赤ボタンだったら使える場合に動作
checkbtn3
	movlw H'03'
	xorwf rv2,W
	btfss STATUS,Z	;ボタン3(赤)が押された？
	goto checkbtn2	;いいえ。
					;はい。

	btfss tenmetu,7	;その状態は赤ボタンを許可？
	goto mainloop	;いいえ。戻る。
	btfsc runstatus,0	;モード設定で赤ボタンを許可？
	goto setsec3		;はい。
					;いいえ。
	movf secleft,W
	btfss STATUS,Z	;secleftは0?
	goto mainloop	;いいえ。戻る。
					;はい。赤ボタンを機能させます。
setsec3
	;残り秒数を更新して変化を早める
	movlw D'1'		;残り秒数を1にすると
	movwf secleft	;0から1秒で変わる
	;長音を鳴らす
	movlw D'1'
	movwf isbeep
	movwf beepw
	clrf beepa
	clrf beepb
	movlw D'7'
	movwf beepc
	;鳴り終わるまで操作させない
setsec3p2
	btfsc INTCON,T0IF		;タイマあふれの
	call inctimer		;検出	
	btfsc isbeep,0		;鳴り終わった？
	goto setsec3p2		;いいえ。ループを続ける
						;はい。
	goto mainloop	;もとに戻る

checkbtn2
	movlw H'02'
	xorwf rv2,W
	btfss STATUS,Z	;黄ボタンが押された？
	goto checkbtn1	;いいえ。
					;はい。
	;項目番号を進める
	incf evsel,F
	;終端(0a)になったらセーブかロードに移る
	movlw H'0a'
	xorwf evsel,W
	btfsc STATUS,Z	;0aになった？
	goto savestatus	;はい。
					;いいえ。
	call ringsetup	;鳴らして
	goto mainloop	;戻る。

	;状態をセーブするかロードするかする
savestatus
	;鳴らす回数を決める
	movlw D'1'	;bit0が0なら1回鳴らす
	btfsc ev09,0	;bit0が1のときは
	movlw D'2'	;2回鳴らす
	movwf beepa
	;セーブかロード
	btfss ev09,0	;bit0が0の場合は
	call saveev	;セーブ
	btfsc ev09,0	;bit0が1の場合は
	call loadev	;ロード。
	call setfromev	;evの値から各種秒数などをセット
	clrf evsel	;選択を0番に戻す
	clrf ev09	;「セーブ」をデフォルトとする
	;鳴らす
	clrf beepb
	movlw D'7'
	movwf beepc	;長音
	movlw D'1'
	movwf beepw
	movwf isbeep	
	;鳴り終わるまで操作を禁止する
savestatusp2
	btfsc INTCON,T0IF		;タイマあふれの
	call inctimer		;検出
	btfsc isbeep,0		;鳴り終わった？
	goto savestatusp2		;いいえ。ループを続ける。
						;はい。
	;先頭の項目を鳴らして、戻る。
	call ringsetup
	goto mainloop

checkbtn1
	movlw H'01'
	xorwf rv2,W
	btfss STATUS,Z	;青ボタンが押された？
	goto mainloop	;いいえ。戻る。
					;はい。
	;設定値を進める
	movf evsel,W
	addlw ev00	;メモリ上のアドレスに変換
	movwf FSR	;アドレスをセット
	incf INDF,W	;値を進める
	andlw H'07'	;7の次は0に戻る
	movwf INDF
	call ringsetup	;設定の状態を鳴らす
	goto mainloop

;;
;ここからサブルーチン
;;
;evselとevXXの値から鳴らす
ringsetup
	incf evsel,W
	movwf beepa	;evsel+1回鳴らす
	movf evsel,W
	addlw ev00	;メモリ上のアドレスに変換
	movwf FSR	;ポインタにセット
	incf INDF,W
	movwf beepb	;値+1回鳴らす
	clrf beepc
	movlw D'1'
	movwf beepw
	movwf isbeep
	return

	;evXXの情報から待ち時間や設定情報を各変数に入れる
setfromev
	clrf tm0a	;0aは無条件で0(無期限)

	;ev00について
	;ev00に変更があったか、または起動時にだけ動作モードを更新する
	movf ev00bak,W
	xorwf ev00,W
	btfsc STATUS,Z	;変化ありor起動直後？
	goto setfromevp2	;いいえ。次の項目に移る。
					;はい。モード変更をする。
	movf ev00,W
	movwf ev00bak	;バックアップ値を更新
	call loadmval
	movwf runpos		;次の更新で1足されるので、	
	decf runpos,F	;1つ手前のアドレスにする。
	movlw D'1'		;残り秒数を「１」にして
	movwf secleft	;すぐに次の状態に移らせる。

setfromevp2
	;ev01からのセット
	movf ev01,W
	call loadbval
	movwf tm00	;A道青
	;ev02からのセット
	movf ev02,W
	call loadbval
	movwf tm05	;B道青
	;ev03について
	movf ev03,W
	call loadbval
	movwf tm0b	;スクランブル歩青
	;ev04について
	movf ev04,W
	call loadtval
	movwf tm01	;青点滅
	movwf tm06
	;ev05について
	movf ev05,W
	call loadrval
	movwf tm02	;歩赤, 車青
	movwf tm07
	;ev07について
	movf ev07,W
	call loadrval
	movwf tm04
	movwf tm09
	movwf tm0c
	;ev08について
	; bit0は 赤ボタン　0:許可 1:禁止
	bcf runstatus,0
	btfss ev08,0		;bit0が0であれば、
	bsf runstatus,0	;赤ボタン許可bitを上げる
	; bit1は 全手動モード 0:しない 1:する
	btfss ev08,1		;全手動モードにする？
	goto setfromevp6	;いいえ。
					;はい。
	;tm00からtm0cまでをいったん全部0にする。
	movlw tm00
	movwf FSR	;tm00から始める
	decf FSR,F	;すぐ増やすのでまず減らす。
setfromevp81
	incf FSR,F
	clrf INDF
	movf FSR,W
	xorlw tm0c		;tm0cを
	btfss STATUS,Z	;終わった？
	goto setfromevp81;いいえ。続ける。
					;はい。
setfromevp6
	;ev06について
	movf ev06,W
	call loadtval
	movwf tm03	;黄の長さ。0にはできない。
	movwf tm08
	;ev09について。
	;変数への操作が必要ない。
	return


	;EEPROMからevXXの値を読み込む
	;値は0..7の範囲に固定される。
	;戻るときevselは0になる。
loadev
	movlw D'10'	;10回
	movwf evsel
	movlw ev00	;evの先頭のアドレスを
	movwf FSR	;ポインタにセット
	bsf STATUS,RP0	;Select bank 1
	clrf EEADR		;EEPROMのアドレスは0から
loadevp2
	bsf STATUS,RP0	;Select bank 1
	bsf EECON1, RD	;読み込み指令
	movf EEDATA,W	;Wレジスタに読み込む
	incf EEADR,F		;EEPROMアドレスを進める
	bcf STATUS,RP0	;Select bank 0
	andlw H'07'		;上5bitsを切り捨てる。
	movwf INDF		;メモリに書き込む
	incf FSR,F		;RAMアドレスを進める	
	decfsz evsel,F	;10回終わった？
	goto loadevp2	;いいえ。続ける。
					;はい。
	return
	
	;evXXの値をEEPROMにセーブする
	;戻るときevselは0になる。
saveev
	movlw D'10'
	movwf evsel	;10回
	movlw ev00	;evの先頭のアドレスを
	movwf FSR	;ポインタにセット
	bsf STATUS,RP0	;Select bank 1
	clrf EEADR		;EEPROMのアドレスは0から
	bcf STATUS,RP0	;Select bank 0
saveevp2
	movf INDF,W		;値をロード
	incf FSR,F		;値のアドレスを進める
	call writeEE		;自動でバンク1に切り替わる。
	incf EEADR,F		;EEPROMのアドレスを進める
	bcf STATUS,RP0	;Select bank 0
	decfsz evsel,F	;10回終わった？
	goto saveevp2	;いいえ。
					;はい。
	return

	;Wレジスタの値をすでにセットされたEEADRに書き込みベリファイする。
	;かけない場合はずっと回り続ける
	;呼ぶとバンク1に切り替わる。
	;帰るときはバンク1のまま。
writeEEretry
	movf eebuf,W	;再び値をWレジスタに入れる
writeEE
	bsf STATUS,RP0	;Select bank 1
	movwf eebuf
	movwf EEDATA
	bsf EECON1,WREN	;書き込み許可
	movlw H'55'
	movwf EECON2
	movlw H'aa'
	movwf EECON2
	bsf EECON1,WR		
writeEEp2
	btfsc EECON1,WR	;書き込み終了？
	goto writeEEp2	;いいえ。まだ。
					;はい。
	bcf EECON1,WREN	;書き込み禁止にする
	;ベリファイのため読む
	bsf 	EECON1,RD	;読み込み指示
	movf EEDATA,W	;読んだ値をWに入れる
	xorwf eebuf,W	;書いた値と読んだ値を比べる
	btfss STATUS,Z	;値は一致した？
	goto writeEEretry	;いいえ。書き直し。
					;はい。
	return

	;タイマあふれがきたらここを呼ぶ
inctimer
	bcf INTCON,T0IF	;フラグを下げる
	incf tcountl,F
	btfsc tcountl,0	;奇数になった場合は
	return			;すぐ戻る

	;1/8秒単位で来る
	;ブザーの管理
	btfss isbeep,0	;音声動作中でなければ	
	goto inctimerp1	;ルーチンの大部分を抜かす

	movf beepw,W
	btfss STATUS,Z
	goto beepwait

	movf beepa,W
	btfss STATUS,Z
	goto beepach

	movf beepb,W
	btfss STATUS,Z
	goto beepbch

	movf beepc,W
	btfss STATUS,Z
	goto beepcch

	;どれにも当てはまらない
	clrf isbeep		;フラグを下げる
	;ブザーフラグが降りているときはここに来る
inctimerp1
	clrf alarm		;ブザーを止める
	;ブザー稼働ルーチンからはここに戻る
inctimerp2
	; 1/8秒単位での経過では、必ずここまでは来る。
	btfss tcountl,2	;1/4秒以上たった？
	goto chview3		;いいえ。ブザーと表示の物理更新へ進む。
					;はい。
	clrf tcountl
	incf tcountq,F
	btfss tcountq,2	;1秒以上たった？
	goto changeview	;いいえ。
					;はい。

	clrf tcountq
	incf tcounts,F	;秒の更新

	;秒ごとに行うべきこと
	;残り秒数の更新
	movf secleft,W
	btfsc STATUS,Z	;すでに0秒の場合は
	goto changeview	;何もせずに表示更新へ進む
	decfsz secleft,F	;残り秒数を1秒減らす。そして、
	goto changeview	;まだ0にならない場合は表示更新へ進む
	;残り0秒に到達。状態の更新をする。
changepos
	;状態の番号を進める
	incf runpos,F
changepos2
	;新しい状態を読み込む
	call loadnewbufa
	movwf bufa
	call loadnewbufb
	movwf bufb
	call loadnewtenmetu
	movwf tenmetu
	call loadnewtadr
	movwf tadr
	;tadrの値によっては位置を変えて読み直し
	movf tadr,W
	btfss STATUS,Z	;tadrが0だった？
	goto changepos3	;いいえ。次はsecleftの設定
					;はい。読み直しが必要。
	;新しい位置にbufaをセットして再び読み取る
	movf bufa,W
	movwf runpos
	goto changepos2

changepos3
	;secleft(この状態の残り秒数)の設定
	bcf STATUS,IRP	;バンク0,1にインダイレクトアクセス
	movf tadr,W
	movwf FSR		;ポインタにアドレスを置く
	movf INDF,W
	movwf secleft

changeview
	;点滅の更新
	;tcountqは0,1,2,3
	btfss tcountq,0
	goto chview2
	;tcountqは奇数(歩道青はつく側）
	btfsc tenmetu,4	;B歩道青(B7)
	bsf bufb,7
	btfsc tenmetu,0	;A歩道青(B1)
	bsf bufb,1
	goto chview3
chview2
	;tcountqは偶数(歩道青は消える側)
	btfsc tenmetu,4	;B歩道青(B7)
	bcf bufb,7
	btfsc tenmetu,0	;A歩道青(B1)
	bcf bufb,1
	;車道側について
	btfss tcountq,1
	goto chview4
	;tcountq==2のとき(秒後半)
	btfsc tenmetu,6	;B赤(B2)
	bsf bufb,2
	btfsc tenmetu,5	;B黄(B4)
	bcf bufb,4
	btfsc tenmetu,2	;A赤(A1)
	bsf bufa,1
	btfsc tenmetu,1	;A黄(A2)
	bcf bufa,2
	goto chview3
chview4
	;tcountq==0のとき(秒開始時)
	btfsc tenmetu,6	;B赤(B2)
	bcf bufb,2
	btfsc tenmetu,5	;B黄(B4)
	bsf bufb,4
	btfsc tenmetu,2	;A赤(A1)
	bcf bufa,1
	btfsc tenmetu,1	;A黄(A2)
	bsf bufa,2

chview3
	;表示の更新。1/8秒端数の場合はここに飛んでくる。
	;ブザーの設定をバッファに転送
	bsf bufa,4
	btfsc alarm,0
	bcf bufa,4
	;バッファの内容をI/Oピンに転送
	movf bufa,W
	movwf PORTA
	movf bufb,W
	movwf PORTB
	return

beepwait
	bcf alarm,0		;音を止める
	decf beepw,F
	goto inctimerp2

beepach
	movlw D'0'		;待ち変数の初期設定値
	;alarmの反転
	btfsc alarm,0
	goto beepach2
	;現在は鳴ってない場合
	bsf alarm,0
	goto beepach3
beepach2
	;現在は鳴っている場合
	bcf alarm,0
	decfsz beepa,F
	goto beepach3
	movlw D'2'		; 終わりになったら待ち=2にする
beepach3
	movwf beepw
	goto inctimerp2

beepbch
	movlw D'0'
	;alarmの反転
	btfsc alarm,0
	goto beepbch2
	;alarmがoffのとき
	bsf alarm,0
	goto beepbch3
beepbch2
	;alarmがonのとき
	bcf alarm,0
	decfsz beepb,F
	goto beepbch3
	movlw D'2'
beepbch3
	movwf beepw
	goto inctimerp2
	
beepcch
	bsf alarm,0
	decfsz beepc,F
	goto inctimerp2
	;beepcが0になった場合
	bcf alarm,0
	movlw D'1'
	movwf beepw
	goto inctimerp2

; 新しいbufa,bufb,tenmetu,tadrを読み取る
; runposの位置にあるデータを読む
cendpos	equ	H'43'	;最終となるシーケンス位置
	org H'400'	;1024番地から始める	
loadnewbufa
	movlw H'04'
	movwf PCLATH
	;値の制限。逸脱したら0を返す。
	movf runpos,W	;runpos は
	sublw cendpos	;0 から cendpos までが正当な範囲
	btfss STATUS,C	;runpos <= cendpos?
	retlw H'00'		;いいえ。異常値なので0を返す
					;はい。
	movf runpos,W
	addwf PCL,F

	; 通常動作(00 - 0a)
	dt H'02',H'08',H'08',H'08',H'04',H'02',H'02',H'02',H'02',H'02',H'00'
	;点滅信号(0b - 0d)
	dt H'04',H'02',H'0b'
	;押しボタン式信号(0e - 15)
	dt H'08',H'08',H'04',H'02',H'02',H'02',H'02',H'0e'
	; 関西タイプ押しボタン式信号(16 - 1d)
	dt H'04',H'08',H'04',H'02',H'02',H'02',H'02',H'16'
	; スクランブル交差点(1e - 27)
	dt H'02',H'08',H'04',H'02',H'02',H'02',H'02',H'02',H'02',H'1e'
	; 点灯テスト(28 - 2b)
	dt H'0f',H'0f',H'00',H'28'
	;通常動作で黄のとき歩行者側青点滅(2c - 34)
	dt H'02',H'08',H'08',H'04',H'02',H'02',H'02',H'02',H'2c'
	;右矢印ありの十字路(35 - 43)
	dt H'02',H'08',H'08',H'08',H'04',H'03',H'04',H'02'
	dt H'02',H'02',H'02',H'02',H'02',H'02',H'35'

loadnewbufb
	movlw H'04'
	movwf PCLATH
	;値の範囲を限定
	movf runpos,W
	sublw cendpos
	btfss STATUS,C	; runpos <= cendpos
	retlw H'00'		; いいえ。異常時は0を返す。
					; はい。
	movf runpos,W
	addwf PCL,F
	;通常動作(00 - 0a)
	dt H'45',H'46',H'46',H'45',H'45',H'45',H'a1',H'a1',H'61',H'51',H'00'
	;点滅動作(0b - 0d)
	dt H'04',H'10',H'00'
	;押しボタン式信号(0e - 15)
	dt H'40',H'40',H'40',H'40',H'80',H'80',H'40',H'00'
	;関西タイプ押しボタン式信号(16 - 1d)
	dt H'40',H'40',H'40',H'40',H'80',H'80',H'40',H'00'
	;スクランブル交差点(1e - 27)
	dt H'45',H'45',H'45',H'45',H'61',H'51',H'45',H'86',H'86',H'00'
	;点灯テスト(28 - 2b)
	dt H'ff',H'ff',H'00',H'00'
	;通常動作で黄のときに歩行者側が青点滅(2c - 34)
	dt H'45',H'46',H'46',H'46',H'45',H'a1',H'a1',H'91',H'00'
	;右矢印ありの十字路(35 - 43)
	dt H'45',H'46',H'46',H'45',H'45',H'45',H'45',H'45'
	dt H'a1',H'a1',H'61',H'51',H'4d',H'51',H'00'

	org H'500'
	;1280番地から始める
loadnewtenmetu
	movlw H'05'
	movwf PCLATH
	;値の範囲を限定する
	movf runpos,W
	sublw cendpos
	btfss STATUS,C	;runpos <= cendpos ?
	retlw H'00'		;いいえ。異常時は0を返す。
					;はい。
	movf runpos,W
	addwf PCL,F
	;通常動作(00 - 0a)
	dt H'80',H'80',H'81',H'80',H'00',H'80',H'80',H'90',H'80',H'00',H'00'
	;点滅信号(0b - 0d)
	dt H'c2',H'a4',H'00'	
	;押しボタン式信号(0e - 15)
	dt H'80',H'80',H'00',H'80',H'80',H'90',H'80',H'00'
	;関西タイプ押しボタン式信号(16 - 1d)
	dt H'82',H'80',H'00',H'80',H'80',H'90',H'80',H'00'
	;スクランブル交差点(1e - 27)
	dt H'80',H'80',H'00',H'80',H'80',H'00',H'80',H'80',H'91',H'00'
	;点灯テスト(28 - 2b)
	dt H'80',H'f7',H'80',H'00'
	;通常動作で黄のときに歩行者側が青点滅(2c - 34)
	dt H'80',H'80',H'81',H'01',H'80',H'80',H'90',H'10',H'00'
	;右矢印ありの十字路(35 - 43)
	dt H'80',H'80',H'81',H'80',H'00',H'80',H'00',H'80'
	dt H'80',H'90',H'80',H'00',H'80',H'00',H'00'

loadnewtadr
	movlw H'05'
	movwf PCLATH
	;値の範囲を限定する
	movf runpos,W
	sublw cendpos
	btfss STATUS,C	;runpos <= cendpos ?
	retlw H'00'		;いいえ。異常値は0を返す。
					;はい。
	movf runpos,W
	addwf PCL,F
	;通常動作 (00 - 0a)
	dt H'59', H'50', H'51', H'52', H'53', H'54', H'55', H'56', H'57', H'58', H'00'
	;点滅信号 (0b - 0d)
	dt H'5a', H'5a', H'00'
	;押しボタン式信号 (0e - 15)
	dt H'5a', H'50', H'53', H'54', H'55', H'56', H'57', H'00'
	;関西タイプ押しボタン式信号 (16 - 1d)
	dt H'5a', H'50', H'53', H'54', H'55', H'56', H'57', H'00'
	;スクランブル交差点 (1e - 27)
	dt H'5c',H'50',H'53',H'54',H'55',H'58',H'59',H'5b',H'51',H'00'
	;点灯テスト (28 - 2b)
	dt H'5a', H'5a', H'5a', H'00'
	;通常動作で黄のときに歩行者側が青点滅(2c - 34)
	dt H'59',H'50',H'51',H'53',H'54',H'55',H'56',H'58',H'00'
	;右矢印ありの十字路(35 - 43)
	dt H'59',H'50',H'51',H'52',H'53',H'5b',H'53',H'54'
	dt H'55',H'56',H'57',H'58',H'5b',H'58',H'00'


;Wレジスタに0から7の範囲の値を入れて呼ぶと、
;対応する値をWレジスタに入れて返す。
;1536番地から始まる。
	org H'600'
;動作モードの値
loadmval
	movwf tmp1
	movlw H'06'
	movwf PCLATH
	movf tmp1,W
	andlw H'07'		;8個までに限る
	addwf PCL,F
	;1:十字路 2:十字路黄時歩行青点滅 3:スクランブル 4:右矢印あり 
	dt H'00',H'2c',H'1e',H'35'
	;5:押しボタン 6:関西押しボタン 7:点滅信号 8:点灯テスト
	dt H'0e',H'16',H'0b',H'28'

;青信号の長さの値
loadbval
	movwf tmp1
	movlw H'06'
	movwf PCLATH
	movf tmp1,W
	andlw H'07'		;8個までに限る
	addwf PCL,F
	dt	D'5', D'10', D'20', D'30', D'45', D'60', D'90', D'120'

; 青点滅の長さなどとして
loadtval
	movwf tmp1
	movlw H'06'
	movwf PCLATH
	movf tmp1,W
	andlw H'07'		;8個までに限る
	addwf PCL,F
	dt D'3', D'4', D'5', D'7', D'10', D'14', D'19', D'25'

;全赤の長さなどとして
loadrval
	movwf tmp1
	movlw H'06'
	movwf PCLATH
	movf tmp1,W
	andlw H'07'		;8個までに限る
	addwf PCL,F
	dt D'1', D'2', D'3', D'4', D'6', D'9', D'12', D'15'

;;
; EEPROMの値の初期値を入れておく
;;
	org H'2100'
	;とりあえず、全部最小値(1回鼓動)とする。
	de H'00',H'00',H'00',H'00'	;ev00-ev03
	de H'00',H'00',H'00',H'00'	;ev04-ev07
	de H'00',H'00'			;ev08-ev09
	end
